Coverage Report

Created: 2026-02-14 09:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/netcdf-c-4.7.4/libsrc/ncx.c
Line
Count
Source
1
/* Do not edit this file. It is produced from the corresponding .m4 source */
2
/*
3
 *  Copyright (C) 2014, Northwestern University and Argonne National Laboratory
4
 *  See COPYRIGHT notice in top-level directory.
5
 */
6
/* $Id: ncx.m4 2601 2016-11-07 04:54:42Z wkliao $ */
7
8
#ifdef __GNUC__
9
#pragma GCC diagnostic ignored "-Wunused-parameter"
10
#endif
11
12
13
14
15
16
17
#if HAVE_CONFIG_H
18
#include <config.h>
19
#endif
20
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <limits.h>
25
26
27
#pragma GCC diagnostic ignored "-Wdeprecated"
28
#include "ncx.h"
29
#include "nc3dispatch.h"
30
31
32
33
34
35
#ifdef HAVE_INTTYPES_H
36
#include <inttypes.h> /* uint16_t, uint32_t, uint64_t */
37
#elif defined(HAVE_STDINT_H)
38
#include <stdint.h>   /* uint16_t, uint32_t, uint64_t */
39
#endif
40
41
42
43
/*
44
 * The only error code returned from subroutines in this file is NC_ERANGE,
45
 * if errors are detected.
46
 */
47
48
/*
49
 * An external data representation interface.
50
 */
51
52
/* alias poorly named limits.h macros */
53
0
#define  SHORT_MAX  SHRT_MAX
54
0
#define  SHORT_MIN  SHRT_MIN
55
0
#define USHORT_MAX USHRT_MAX
56
#ifndef LLONG_MAX
57
#   define LLONG_MAX  9223372036854775807LL
58
#   define LLONG_MIN  (-LLONG_MAX - 1LL)
59
#   define ULLONG_MAX 18446744073709551615ULL
60
#endif
61
#ifndef LONG_LONG_MAX
62
0
#define LONG_LONG_MAX LLONG_MAX
63
#endif
64
#ifndef LONGLONG_MAX
65
0
#define LONGLONG_MAX LONG_LONG_MAX
66
#endif
67
#ifndef LONG_LONG_MIN
68
0
#define LONG_LONG_MIN LLONG_MIN
69
#endif
70
#ifndef LONGLONG_MIN
71
0
#define LONGLONG_MIN LONG_LONG_MIN
72
#endif
73
#ifndef ULONG_LONG_MAX
74
0
#define ULONG_LONG_MAX ULLONG_MAX
75
#endif
76
#ifndef ULONGLONG_MAX
77
0
#define ULONGLONG_MAX ULONG_LONG_MAX
78
#endif
79
#include <float.h>
80
#ifndef FLT_MAX /* This POSIX macro missing on some systems */
81
# ifndef NO_IEEE_FLOAT
82
# define FLT_MAX 3.40282347e+38f
83
# else
84
# error "You will need to define FLT_MAX"
85
# endif
86
#endif
87
/* alias poorly named float.h macros */
88
#define FLOAT_MAX FLT_MAX
89
#define FLOAT_MIN (-FLT_MAX)
90
#define DOUBLE_MAX DBL_MAX
91
#define DOUBLE_MIN (-DBL_MAX)
92
#define FLOAT_MAX_EXP FLT_MAX_EXP
93
#define DOUBLE_MAX_EXP DBL_MAX_EXP
94
#include <assert.h>
95
#define UCHAR_MIN 0
96
#define Min(a,b) ((a) < (b) ? (a) : (b))
97
#define Max(a,b) ((a) > (b) ? (a) : (b))
98
99
#ifndef SIZEOF_UCHAR
100
#ifdef  SIZEOF_UNSIGNED_CHAR
101
#define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR
102
#else
103
#error "unknown SIZEOF_UCHAR"
104
#endif
105
#endif
106
107
#ifndef SIZEOF_USHORT
108
#ifdef  SIZEOF_UNSIGNED_SHORT_INT
109
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
110
#elif defined(SIZEOF_UNSIGNED_SHORT)
111
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT
112
#else
113
#error "unknown SIZEOF_USHORT"
114
#endif
115
#endif
116
117
#ifndef SIZEOF_UINT
118
#ifdef  SIZEOF_UNSIGNED_INT
119
#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
120
#else
121
#error "unknown SIZEOF_UINT"
122
#endif
123
#endif
124
125
#ifndef SIZEOF_LONGLONG
126
#ifdef  SIZEOF_LONG_LONG
127
#define SIZEOF_LONGLONG SIZEOF_LONG_LONG
128
#else
129
#error "unknown SIZEOF_LONGLONG"
130
#endif
131
#endif
132
133
#ifndef SIZEOF_INT64
134
#ifdef  SIZEOF_LONG_LONG
135
#define SIZEOF_INT64 SIZEOF_LONG_LONG
136
#elif defined(SIZEOF_LONGLONG)
137
#define SIZEOF_INT64 SIZEOF_LONGLONG
138
#else
139
#error "unknown SIZEOF_INT64"
140
#endif
141
#endif
142
143
#ifndef SIZEOF_ULONGLONG
144
#ifdef  SIZEOF_UNSIGNED_LONG_LONG
145
#define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG
146
#else
147
#error "unknown SIZEOF_ULONGLONG"
148
#endif
149
#endif
150
151
#ifndef SIZEOF_UINT64
152
#ifdef  SIZEOF_UNSIGNED_LONG_LONG
153
#define SIZEOF_UINT64 SIZEOF_UNSIGNED_LONG_LONG
154
#elif defined(SIZEOF_ULONGLONG)
155
#define SIZEOF_UINT64 SIZEOF_ULONGLONG
156
#else
157
#error "unknown SIZEOF_UINT64"
158
#endif
159
#endif
160
161
/*
162
 * If the machine's float domain is "smaller" than the external one
163
 * use the machine domain
164
 */
165
#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */
166
#undef X_FLOAT_MAX
167
# define X_FLOAT_MAX FLT_MAX
168
#undef X_FLOAT_MIN
169
# define X_FLOAT_MIN (-X_FLOAT_MAX)
170
#endif
171
172
#if defined(_SX) && _SX != 0 /* NEC SUPER UX */
173
#define LOOPCNT 256    /* must be no longer than hardware vector length */
174
#if _INT64
175
#undef  INT_MAX /* workaround cpp bug */
176
#define INT_MAX  X_INT_MAX
177
#undef  INT_MIN /* workaround cpp bug */
178
#define INT_MIN  X_INT_MIN
179
#undef  LONG_MAX /* workaround cpp bug */
180
#define LONG_MAX  X_INT_MAX
181
#undef  LONG_MIN /* workaround cpp bug */
182
#define LONG_MIN  X_INT_MIN
183
#elif _LONG64
184
#undef  LONG_MAX /* workaround cpp bug */
185
#define LONG_MAX  4294967295L
186
#undef  LONG_MIN /* workaround cpp bug */
187
#define LONG_MIN -4294967295L
188
#endif
189
#if !_FLOAT0
190
#error "FLOAT1 and FLOAT2 not supported"
191
#endif
192
#endif /* _SX */
193
194
static const char nada[X_ALIGN] = {0, 0, 0, 0};
195
196
#ifndef WORDS_BIGENDIAN
197
/* LITTLE_ENDIAN: DEC and intel */
198
/*
199
 * Routines to convert to BIG ENDIAN.
200
 * Optimize the swapn?b() and swap?b() routines aggressively.
201
 */
202
203
256
#define SWAP2(a) ( (((a) & 0xff) << 8) | \
204
256
                   (((a) >> 8) & 0xff) )
205
206
224k
#define SWAP4(a) ( ((a) << 24) | \
207
224k
                  (((a) <<  8) & 0x00ff0000) | \
208
224k
                  (((a) >>  8) & 0x0000ff00) | \
209
224k
                  (((a) >> 24) & 0x000000ff) )
210
211
55.6k
#define SWAP8(a) ( (((a) & 0x00000000000000FFULL) << 56) | \
212
55.6k
                   (((a) & 0x000000000000FF00ULL) << 40) | \
213
55.6k
                   (((a) & 0x0000000000FF0000ULL) << 24) | \
214
55.6k
                   (((a) & 0x00000000FF000000ULL) <<  8) | \
215
55.6k
                   (((a) & 0x000000FF00000000ULL) >>  8) | \
216
55.6k
                   (((a) & 0x0000FF0000000000ULL) >> 24) | \
217
55.6k
                   (((a) & 0x00FF000000000000ULL) >> 40) | \
218
55.6k
                   (((a) & 0xFF00000000000000ULL) >> 56) )
219
220
#if defined(_MSC_VER) && _MSC_VER < 1900
221
#define inline __inline
222
#endif
223
224
inline static void
225
swapn2b(void *dst, const void *src, size_t nn)
226
4
{
227
    /* it is OK if dst == src */
228
4
    int i;
229
4
    uint16_t *op = (uint16_t*) dst;
230
4
    uint16_t *ip = (uint16_t*) src;
231
260
    for (i=0; i<nn; i++) {
232
256
        op[i] = ip[i];
233
256
        op[i] = (uint16_t)SWAP2(op[i]);
234
256
    }
235
#if 0
236
  char *op = dst;
237
  const char *ip = src;
238
239
/* unroll the following to reduce loop overhead
240
 *
241
 *  while (nn-- > 0)
242
 *  {
243
 *    *op++ = *(++ip);
244
 *    *op++ = *(ip++ -1);
245
 *  }
246
 */
247
  while (nn > 3)
248
  {
249
    *op++ = *(++ip);
250
    *op++ = *(ip++ -1);
251
    *op++ = *(++ip);
252
    *op++ = *(ip++ -1);
253
    *op++ = *(++ip);
254
    *op++ = *(ip++ -1);
255
    *op++ = *(++ip);
256
    *op++ = *(ip++ -1);
257
    nn -= 4;
258
  }
259
  while (nn-- > 0)
260
  {
261
    *op++ = *(++ip);
262
    *op++ = *(ip++ -1);
263
  }
264
#endif
265
4
}
266
267
# ifndef vax
268
inline static void
269
swap4b(void *dst, const void *src)
270
0
{
271
    /* copy over, make the below swap in-place */
272
0
    uint32_t tmp = *(uint32_t*)src;
273
0
    tmp = SWAP4(tmp);
274
0
    memcpy(dst, &tmp, 4);
275
276
    /* Codes below will cause "break strict-aliasing rules" in gcc
277
    uint32_t *op = (uint32_t*)dst;
278
    *op = *(uint32_t*)src;
279
    *op = SWAP4(*op);
280
    */
281
282
    /* Below are copied from netCDF-4.
283
     * See https://bugtracking.unidata.ucar.edu/browse/NCF-338
284
     * Quote "One issue we are wrestling with is how compilers optimize this
285
     * code.  For some reason, we are actually needing to add an artificial
286
     * move to a 4 byte space to get it to work.  I think what is happening is
287
     * that the optimizer is bit shifting within a double, which is incorrect.
288
     * The following code actually does work correctly.
289
     *  This is in Linux land, gcc.
290
     *
291
     * However, the above in-place byte-swap does not appear affected by this.
292
     */
293
#if 0
294
    uint32_t *ip = (uint32_t*)src;
295
    uint32_t tempOut;  /* cannot use pointer when gcc O2 optimizer is used */
296
    tempOut = SWAP4(*ip);
297
298
    *(float *)dst = *(float *)(&tempOut);
299
#endif
300
301
    /* OLD implementation that results in four load and four store CPU
302
       instructions
303
    char *op = dst;
304
    const char *ip = src;
305
    op[0] = ip[3];
306
    op[1] = ip[2];
307
    op[2] = ip[1];
308
    op[3] = ip[0];
309
    */
310
311
0
}
312
# endif /* !vax */
313
314
inline static void
315
swapn4b(void *dst, const void *src, size_t nn)
316
255k
{
317
255k
    int i;
318
255k
    uint32_t *op = (uint32_t*) dst;
319
255k
    uint32_t *ip = (uint32_t*) src;
320
479k
    for (i=0; i<nn; i++) {
321
        /* copy over, make the below swap in-place */
322
224k
        op[i] = ip[i];
323
224k
        op[i] = SWAP4(op[i]);
324
224k
    }
325
326
#if 0
327
  char *op = dst;
328
  const char *ip = src;
329
330
/* unroll the following to reduce loop overhead
331
 *  while (nn-- > 0)
332
 *  {
333
 *    op[0] = ip[3];
334
 *    op[1] = ip[2];
335
 *    op[2] = ip[1];
336
 *    op[3] = ip[0];
337
 *    op += 4;
338
 *    ip += 4;
339
 *  }
340
 */
341
  while (nn > 3)
342
  {
343
    op[0] = ip[3];
344
    op[1] = ip[2];
345
    op[2] = ip[1];
346
    op[3] = ip[0];
347
    op[4] = ip[7];
348
    op[5] = ip[6];
349
    op[6] = ip[5];
350
    op[7] = ip[4];
351
    op[8] = ip[11];
352
    op[9] = ip[10];
353
    op[10] = ip[9];
354
    op[11] = ip[8];
355
    op[12] = ip[15];
356
    op[13] = ip[14];
357
    op[14] = ip[13];
358
    op[15] = ip[12];
359
    op += 16;
360
    ip += 16;
361
    nn -= 4;
362
  }
363
  while (nn-- > 0)
364
  {
365
    op[0] = ip[3];
366
    op[1] = ip[2];
367
    op[2] = ip[1];
368
    op[3] = ip[0];
369
    op += 4;
370
    ip += 4;
371
  }
372
#endif
373
255k
}
374
375
# ifndef vax
376
inline static void
377
swap8b(void *dst, const void *src)
378
0
{
379
#ifdef FLOAT_WORDS_BIGENDIAN
380
    /* copy over, make the below swap in-place */
381
    *(uint64_t*)dst = *(uint64_t*)src;
382
383
    uint32_t *op = (uint32_t*)dst;
384
    *op = SWAP4(*op);
385
    op = (uint32_t*)((char*)dst+4);
386
    *op = SWAP4(*op);
387
#else
388
0
    uint64_t tmp = *(uint64_t*)src;
389
0
    tmp = SWAP8(tmp);
390
0
    memcpy(dst, &tmp, 8);
391
392
    /* Codes below will cause "break strict-aliasing rules" in gcc
393
    uint64_t *op = (uint64_t*)dst;
394
    *op = *(uint64_t*)src;
395
    *op = SWAP8(*op);
396
    */
397
0
#endif
398
399
#if 0
400
  char *op = dst;
401
  const char *ip = src;
402
#  ifndef FLOAT_WORDS_BIGENDIAN
403
  op[0] = ip[7];
404
  op[1] = ip[6];
405
  op[2] = ip[5];
406
  op[3] = ip[4];
407
  op[4] = ip[3];
408
  op[5] = ip[2];
409
  op[6] = ip[1];
410
  op[7] = ip[0];
411
#  else
412
  op[0] = ip[3];
413
  op[1] = ip[2];
414
  op[2] = ip[1];
415
  op[3] = ip[0];
416
  op[4] = ip[7];
417
  op[5] = ip[6];
418
  op[6] = ip[5];
419
  op[7] = ip[4];
420
#endif
421
#endif
422
0
}
423
# endif /* !vax */
424
425
# ifndef vax
426
inline static void
427
swapn8b(void *dst, const void *src, size_t nn)
428
22.6k
{
429
#ifdef FLOAT_WORDS_BIGENDIAN
430
    int i;
431
    uint64_t *dst_p = (uint64_t*) dst;
432
    uint64_t *src_p = (uint64_t*) src;
433
    for (i=0; i<nn; i++) {
434
        /* copy over, make the below swap in-place */
435
        dst_p[i] = src_p[i];
436
        uint32_t *op = (uint32_t*)(&dst_p[i]);
437
        *op = SWAP4(*op);
438
        op = (uint32_t*)((char*)op+4);
439
        *op = SWAP4(*op);
440
    }
441
#else
442
22.6k
    int i;
443
22.6k
    uint64_t *op = (uint64_t*) dst;
444
22.6k
    uint64_t *ip = (uint64_t*) src;
445
78.3k
    for (i=0; i<nn; i++) {
446
        /* copy over, make the below swap in-place */
447
55.6k
        op[i] = ip[i];
448
55.6k
        op[i] = SWAP8(op[i]);
449
55.6k
    }
450
22.6k
#endif
451
452
#if 0
453
  char *op = dst;
454
  const char *ip = src;
455
456
/* unroll the following to reduce loop overhead
457
 *  while (nn-- > 0)
458
 *  {
459
 *    op[0] = ip[7];
460
 *    op[1] = ip[6];
461
 *    op[2] = ip[5];
462
 *    op[3] = ip[4];
463
 *    op[4] = ip[3];
464
 *    op[5] = ip[2];
465
 *    op[6] = ip[1];
466
 *    op[7] = ip[0];
467
 *    op += 8;
468
 *    ip += 8;
469
 *  }
470
 */
471
#  ifndef FLOAT_WORDS_BIGENDIAN
472
  while (nn > 1)
473
  {
474
    op[0] = ip[7];
475
    op[1] = ip[6];
476
    op[2] = ip[5];
477
    op[3] = ip[4];
478
    op[4] = ip[3];
479
    op[5] = ip[2];
480
    op[6] = ip[1];
481
    op[7] = ip[0];
482
    op[8] = ip[15];
483
    op[9] = ip[14];
484
    op[10] = ip[13];
485
    op[11] = ip[12];
486
    op[12] = ip[11];
487
    op[13] = ip[10];
488
    op[14] = ip[9];
489
    op[15] = ip[8];
490
    op += 16;
491
    ip += 16;
492
    nn -= 2;
493
  }
494
  while (nn-- > 0)
495
  {
496
    op[0] = ip[7];
497
    op[1] = ip[6];
498
    op[2] = ip[5];
499
    op[3] = ip[4];
500
    op[4] = ip[3];
501
    op[5] = ip[2];
502
    op[6] = ip[1];
503
    op[7] = ip[0];
504
    op += 8;
505
    ip += 8;
506
  }
507
#  else
508
  while (nn-- > 0)
509
  {
510
    op[0] = ip[3];
511
    op[1] = ip[2];
512
    op[2] = ip[1];
513
    op[3] = ip[0];
514
    op[4] = ip[7];
515
    op[5] = ip[6];
516
    op[6] = ip[5];
517
    op[7] = ip[4];
518
    op += 8;
519
    ip += 8;
520
  }
521
#endif
522
#endif
523
22.6k
}
524
# endif /* !vax */
525
526
#endif /* LITTLE_ENDIAN */
527
528
529
530
531
532
533
/*
534
 * Primitive numeric conversion functions.
535
 */
536
537
538
539
540
541
/* x_schar */
542
/* x_uchar */
543
544
/* We don't implement any x_schar and x_uchar primitives. */
545
546
547
/* external NC_SHORT --------------------------------------------------------*/
548
549
#if SHORT_MAX == X_SHORT_MAX
550
typedef short ix_short;
551
#define SIZEOF_IX_SHORT SIZEOF_SHORT
552
0
#define IX_SHORT_MAX SHORT_MAX
553
#elif INT_MAX >= X_SHORT_MAX
554
typedef int ix_short;
555
#define SIZEOF_IX_SHORT SIZEOF_INT
556
#define IX_SHORT_MAX INT_MAX
557
#elif LONG_MAX >= X_SHORT_MAX
558
typedef long ix_short;
559
#define SIZEOF_IX_SHORT SIZEOF_LONG
560
#define IX_SHORT_MAX LONG_MAX
561
#elif LLONG_MAX >= X_SHORT_MAX
562
typedef long long ix_short;
563
#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
564
#define IX_SHORT_MAX LLONG_MAX
565
#else
566
#error "ix_short implementation"
567
#endif
568
569
static void
570
get_ix_short(const void *xp, ix_short *ip)
571
10.5k
{
572
10.5k
  const uchar *cp = (const uchar *) xp;
573
10.5k
  *ip = (ix_short)(*cp++ << 8);
574
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
575
  if (*ip & 0x8000)
576
  {
577
    /* extern is negative */
578
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
579
  }
580
#endif
581
10.5k
  *ip = (ix_short)(*ip | *cp);
582
10.5k
}
583
584
static void
585
put_ix_short(void *xp, const ix_short *ip)
586
10.5k
{
587
10.5k
  uchar *cp = (uchar *) xp;
588
10.5k
  *cp++ = (uchar)((*ip) >> 8);
589
10.5k
  *cp   = (uchar)((*ip) & 0xff);
590
10.5k
}
591
592
static int
593
ncx_get_short_schar(const void *xp, schar *ip)
594
0
{
595
0
    int err=NC_NOERR;
596
0
    ix_short xx = 0;
597
0
    get_ix_short(xp, &xx);
598
599
0
#if IX_SHORT_MAX > SCHAR_MAX
600
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
601
#ifdef ERANGE_FILL
602
        *ip = NC_FILL_BYTE;
603
        return NC_ERANGE;
604
#else
605
0
        err = NC_ERANGE;
606
0
#endif
607
0
    }
608
0
#endif
609
610
611
0
    *ip = (schar) xx;
612
0
    return err;
613
0
}
614
615
static int
616
ncx_get_short_short(const void *xp, short *ip)
617
10.5k
{
618
10.5k
    int err=NC_NOERR;
619
10.5k
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
620
10.5k
    get_ix_short(xp, (ix_short *)ip);
621
#else
622
    ix_short xx = 0;
623
    get_ix_short(xp, &xx);
624
625
#if IX_SHORT_MAX > SHORT_MAX
626
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
627
#ifdef ERANGE_FILL
628
        *ip = NC_FILL_SHORT;
629
        return NC_ERANGE;
630
#else
631
        err = NC_ERANGE;
632
#endif
633
    }
634
#endif
635
636
637
    *ip = (short) xx;
638
#endif
639
10.5k
    return err;
640
10.5k
}
641
642
static int
643
ncx_get_short_int(const void *xp, int *ip)
644
0
{
645
0
    int err=NC_NOERR;
646
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
647
    get_ix_short(xp, (ix_short *)ip);
648
#else
649
0
    ix_short xx = 0;
650
0
    get_ix_short(xp, &xx);
651
652
#if IX_SHORT_MAX > INT_MAX
653
    if (xx > INT_MAX || xx < INT_MIN) {
654
#ifdef ERANGE_FILL
655
        *ip = NC_FILL_INT;
656
        return NC_ERANGE;
657
#else
658
        err = NC_ERANGE;
659
#endif
660
    }
661
#endif
662
663
664
0
    *ip = (int) xx;
665
0
#endif
666
0
    return err;
667
0
}
668
669
static int
670
ncx_get_short_long(const void *xp, long *ip)
671
0
{
672
0
    int err=NC_NOERR;
673
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
674
    get_ix_short(xp, (ix_short *)ip);
675
#else
676
0
    ix_short xx = 0;
677
0
    get_ix_short(xp, &xx);
678
679
#if IX_SHORT_MAX > LONG_MAX
680
    if (xx > LONG_MAX || xx < LONG_MIN) {
681
#ifdef ERANGE_FILL
682
        *ip = NC_FILL_INT;
683
        return NC_ERANGE;
684
#else
685
        err = NC_ERANGE;
686
#endif
687
    }
688
#endif
689
690
691
0
    *ip = (long) xx;
692
0
#endif
693
0
    return err;
694
0
}
695
696
static int
697
ncx_get_short_longlong(const void *xp, longlong *ip)
698
0
{
699
0
    int err=NC_NOERR;
700
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
701
    get_ix_short(xp, (ix_short *)ip);
702
#else
703
0
    ix_short xx = 0;
704
0
    get_ix_short(xp, &xx);
705
706
#if IX_SHORT_MAX > LONGLONG_MAX
707
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
708
#ifdef ERANGE_FILL
709
        *ip = NC_FILL_INT64;
710
        return NC_ERANGE;
711
#else
712
        err = NC_ERANGE;
713
#endif
714
    }
715
#endif
716
717
718
0
    *ip = (longlong) xx;
719
0
#endif
720
0
    return err;
721
0
}
722
723
static int
724
ncx_get_short_ushort(const void *xp, ushort *ip)
725
0
{
726
0
    int err=NC_NOERR;
727
0
    ix_short xx = 0;
728
0
    get_ix_short(xp, &xx);
729
730
#if IX_SHORT_MAX > USHORT_MAX
731
    if (xx > USHORT_MAX) {
732
#ifdef ERANGE_FILL
733
        *ip = NC_FILL_USHORT;
734
        return NC_ERANGE;
735
#else
736
        err = NC_ERANGE;
737
#endif
738
    }
739
#endif
740
741
0
    if (xx < 0) {
742
#ifdef ERANGE_FILL
743
        *ip = NC_FILL_USHORT;
744
        return NC_ERANGE;
745
#else
746
0
        err = NC_ERANGE; /* because ip is unsigned */
747
0
#endif
748
0
    }
749
0
    *ip = (ushort) xx;
750
0
    return err;
751
0
}
752
753
static int
754
ncx_get_short_uchar(const void *xp, uchar *ip)
755
0
{
756
0
    int err=NC_NOERR;
757
0
    ix_short xx = 0;
758
0
    get_ix_short(xp, &xx);
759
760
0
#if IX_SHORT_MAX > UCHAR_MAX
761
0
    if (xx > UCHAR_MAX) {
762
#ifdef ERANGE_FILL
763
        *ip = NC_FILL_UBYTE;
764
        return NC_ERANGE;
765
#else
766
0
        err = NC_ERANGE;
767
0
#endif
768
0
    }
769
0
#endif
770
771
0
    if (xx < 0) {
772
#ifdef ERANGE_FILL
773
        *ip = NC_FILL_UBYTE;
774
        return NC_ERANGE;
775
#else
776
0
        err = NC_ERANGE; /* because ip is unsigned */
777
0
#endif
778
0
    }
779
0
    *ip = (uchar) xx;
780
0
    return err;
781
0
}
782
783
static int
784
ncx_get_short_uint(const void *xp, uint *ip)
785
0
{
786
0
    int err=NC_NOERR;
787
0
    ix_short xx = 0;
788
0
    get_ix_short(xp, &xx);
789
790
#if IX_SHORT_MAX > UINT_MAX
791
    if (xx > UINT_MAX) {
792
#ifdef ERANGE_FILL
793
        *ip = NC_FILL_UINT;
794
        return NC_ERANGE;
795
#else
796
        err = NC_ERANGE;
797
#endif
798
    }
799
#endif
800
801
0
    if (xx < 0) {
802
#ifdef ERANGE_FILL
803
        *ip = NC_FILL_UINT;
804
        return NC_ERANGE;
805
#else
806
0
        err = NC_ERANGE; /* because ip is unsigned */
807
0
#endif
808
0
    }
809
0
    *ip = (uint) xx;
810
0
    return err;
811
0
}
812
813
static int
814
ncx_get_short_ulonglong(const void *xp, ulonglong *ip)
815
0
{
816
0
    int err=NC_NOERR;
817
0
    ix_short xx = 0;
818
0
    get_ix_short(xp, &xx);
819
820
#if IX_SHORT_MAX > ULONGLONG_MAX
821
    if (xx > ULONGLONG_MAX) {
822
#ifdef ERANGE_FILL
823
        *ip = NC_FILL_UINT64;
824
        return NC_ERANGE;
825
#else
826
        err = NC_ERANGE;
827
#endif
828
    }
829
#endif
830
831
0
    if (xx < 0) {
832
#ifdef ERANGE_FILL
833
        *ip = NC_FILL_UINT64;
834
        return NC_ERANGE;
835
#else
836
0
        err = NC_ERANGE; /* because ip is unsigned */
837
0
#endif
838
0
    }
839
0
    *ip = (ulonglong) xx;
840
0
    return err;
841
0
}
842
843
static int
844
ncx_get_short_float(const void *xp, float *ip)
845
0
{
846
0
  ix_short xx = 0;
847
0
  get_ix_short(xp, &xx);
848
0
  *ip = (float)xx;
849
0
  return NC_NOERR;
850
0
}
851
852
static int
853
ncx_get_short_double(const void *xp, double *ip)
854
0
{
855
0
  ix_short xx = 0;
856
0
  get_ix_short(xp, &xx);
857
0
  *ip = (double)xx;
858
0
  return NC_NOERR;
859
0
}
860
861
862
static int
863
ncx_put_short_schar(void *xp, const schar *ip, void *fillp)
864
0
{
865
0
  uchar *cp = (uchar *) xp;
866
0
  if (*ip & 0x80)
867
0
    *cp++ = 0xff;
868
0
  else
869
0
    *cp++ = 0;
870
0
  *cp = (uchar)*ip;
871
0
  return NC_NOERR;
872
0
}
873
874
static int
875
ncx_put_short_uchar(void *xp, const uchar *ip, void *fillp)
876
0
{
877
0
  uchar *cp = (uchar *) xp;
878
0
  *cp++ = 0;
879
0
  *cp = *ip;
880
0
  return NC_NOERR;
881
0
}
882
883
static int
884
ncx_put_short_short(void *xp, const short *ip, void *fillp)
885
10.5k
{
886
10.5k
    int err=NC_NOERR;
887
10.5k
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
888
10.5k
    put_ix_short(xp, (const ix_short *)ip);
889
#else
890
    ix_short xx = NC_FILL_SHORT;
891
892
#if IX_SHORT_MAX < SHORT_MAX
893
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
894
        
895
#ifdef ERANGE_FILL
896
            if (fillp != NULL) memcpy(&xx, fillp, 2);
897
#endif
898
        err = NC_ERANGE;
899
    }
900
#ifdef ERANGE_FILL
901
    else
902
#endif
903
#endif
904
        xx = (ix_short)*ip;
905
906
    put_ix_short(xp, &xx);
907
#endif
908
10.5k
    return err;
909
10.5k
}
910
911
static int
912
ncx_put_short_int(void *xp, const int *ip, void *fillp)
913
0
{
914
0
    int err=NC_NOERR;
915
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
916
    put_ix_short(xp, (const ix_short *)ip);
917
#else
918
0
    ix_short xx = NC_FILL_SHORT;
919
920
0
#if IX_SHORT_MAX < INT_MAX
921
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
922
        
923
#ifdef ERANGE_FILL
924
            if (fillp != NULL) memcpy(&xx, fillp, 2);
925
#endif
926
0
        err = NC_ERANGE;
927
0
    }
928
#ifdef ERANGE_FILL
929
    else
930
#endif
931
0
#endif
932
0
        xx = (ix_short)*ip;
933
934
0
    put_ix_short(xp, &xx);
935
0
#endif
936
0
    return err;
937
0
}
938
939
static int
940
ncx_put_short_long(void *xp, const long *ip, void *fillp)
941
0
{
942
0
    int err=NC_NOERR;
943
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
944
    put_ix_short(xp, (const ix_short *)ip);
945
#else
946
0
    ix_short xx = NC_FILL_SHORT;
947
948
0
#if IX_SHORT_MAX < LONG_MAX
949
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
950
        
951
#ifdef ERANGE_FILL
952
            if (fillp != NULL) memcpy(&xx, fillp, 2);
953
#endif
954
0
        err = NC_ERANGE;
955
0
    }
956
#ifdef ERANGE_FILL
957
    else
958
#endif
959
0
#endif
960
0
        xx = (ix_short)*ip;
961
962
0
    put_ix_short(xp, &xx);
963
0
#endif
964
0
    return err;
965
0
}
966
967
static int
968
ncx_put_short_longlong(void *xp, const longlong *ip, void *fillp)
969
0
{
970
0
    int err=NC_NOERR;
971
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
972
    put_ix_short(xp, (const ix_short *)ip);
973
#else
974
0
    ix_short xx = NC_FILL_SHORT;
975
976
0
#if IX_SHORT_MAX < LONGLONG_MAX
977
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
978
        
979
#ifdef ERANGE_FILL
980
            if (fillp != NULL) memcpy(&xx, fillp, 2);
981
#endif
982
0
        err = NC_ERANGE;
983
0
    }
984
#ifdef ERANGE_FILL
985
    else
986
#endif
987
0
#endif
988
0
        xx = (ix_short)*ip;
989
990
0
    put_ix_short(xp, &xx);
991
0
#endif
992
0
    return err;
993
0
}
994
995
static int
996
ncx_put_short_ushort(void *xp, const ushort *ip, void *fillp)
997
0
{
998
0
    int err=NC_NOERR;
999
0
    ix_short xx = NC_FILL_SHORT;
1000
1001
0
#if IX_SHORT_MAX < USHORT_MAX
1002
0
    if (*ip > IX_SHORT_MAX) {
1003
        
1004
#ifdef ERANGE_FILL
1005
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1006
#endif
1007
0
        err = NC_ERANGE;
1008
0
    }
1009
#ifdef ERANGE_FILL
1010
    else
1011
#endif
1012
0
#endif
1013
0
        xx = (ix_short)*ip;
1014
1015
0
    put_ix_short(xp, &xx);
1016
0
    return err;
1017
0
}
1018
1019
static int
1020
ncx_put_short_uint(void *xp, const uint *ip, void *fillp)
1021
0
{
1022
0
    int err=NC_NOERR;
1023
0
    ix_short xx = NC_FILL_SHORT;
1024
1025
0
#if IX_SHORT_MAX < UINT_MAX
1026
0
    if (*ip > IX_SHORT_MAX) {
1027
        
1028
#ifdef ERANGE_FILL
1029
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1030
#endif
1031
0
        err = NC_ERANGE;
1032
0
    }
1033
#ifdef ERANGE_FILL
1034
    else
1035
#endif
1036
0
#endif
1037
0
        xx = (ix_short)*ip;
1038
1039
0
    put_ix_short(xp, &xx);
1040
0
    return err;
1041
0
}
1042
1043
static int
1044
ncx_put_short_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1045
0
{
1046
0
    int err=NC_NOERR;
1047
0
    ix_short xx = NC_FILL_SHORT;
1048
1049
0
#if IX_SHORT_MAX < ULONGLONG_MAX
1050
0
    if (*ip > IX_SHORT_MAX) {
1051
        
1052
#ifdef ERANGE_FILL
1053
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1054
#endif
1055
0
        err = NC_ERANGE;
1056
0
    }
1057
#ifdef ERANGE_FILL
1058
    else
1059
#endif
1060
0
#endif
1061
0
        xx = (ix_short)*ip;
1062
1063
0
    put_ix_short(xp, &xx);
1064
0
    return err;
1065
0
}
1066
1067
static int
1068
ncx_put_short_float(void *xp, const float *ip, void *fillp)
1069
0
{
1070
0
    int err=NC_NOERR;
1071
0
    ix_short xx = NC_FILL_SHORT;
1072
1073
0
    if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
1074
        
1075
#ifdef ERANGE_FILL
1076
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1077
#endif
1078
0
        err = NC_ERANGE;
1079
0
    }
1080
#ifdef ERANGE_FILL
1081
    else
1082
#endif
1083
0
        xx = (ix_short)*ip;
1084
1085
0
    put_ix_short(xp, &xx);
1086
0
    return err;
1087
0
}
1088
1089
static int
1090
ncx_put_short_double(void *xp, const double *ip, void *fillp)
1091
0
{
1092
0
    int err=NC_NOERR;
1093
0
    ix_short xx = NC_FILL_SHORT;
1094
1095
0
    if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) {
1096
        
1097
#ifdef ERANGE_FILL
1098
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1099
#endif
1100
0
        err = NC_ERANGE;
1101
0
    }
1102
#ifdef ERANGE_FILL
1103
    else
1104
#endif
1105
0
        xx = (ix_short)*ip;
1106
1107
0
    put_ix_short(xp, &xx);
1108
0
    return err;
1109
0
}
1110
1111
1112
/* external NC_USHORT -------------------------------------------------------*/
1113
1114
#if USHORT_MAX == X_USHORT_MAX
1115
typedef unsigned short ix_ushort;
1116
#define SIZEOF_IX_USHORT SIZEOF_USHORT
1117
0
#define IX_USHORT_MAX USHORT_MAX
1118
#elif UINT_MAX >= X_USHORT_MAX
1119
typedef unsigned int ix_ushort;
1120
#define SIZEOF_IX_USHORT SIZEOF_UINT
1121
#define IX_USHORT_MAX UINT_MAX
1122
#elif ULONG_MAX >= X_USHORT_MAX
1123
typedef unsigned long ix_ushort;
1124
#define SIZEOF_IX_USHORT SIZEOF_ULONG
1125
#define IX_USHORT_MAX ULONG_MAX
1126
#elif ULLONG_MAX >= X_USHORT_MAX
1127
typedef unsigned long long ix_ushort;
1128
#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
1129
#define IX_USHORT_MAX ULLONG_MAX
1130
#else
1131
#error "ix_ushort implementation"
1132
#endif
1133
1134
static void
1135
get_ix_ushort(const void *xp, ix_ushort *ip)
1136
0
{
1137
0
  const uchar *cp = (const uchar *) xp;
1138
0
  *ip = (ix_ushort)(*cp++ << 8);
1139
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
1140
  if (*ip & 0x8000)
1141
  {
1142
    /* extern is negative */
1143
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
1144
  }
1145
#endif
1146
0
  *ip = (ix_ushort)(*ip | *cp);
1147
0
}
1148
1149
static void
1150
put_ix_ushort(void *xp, const ix_ushort *ip)
1151
0
{
1152
0
  uchar *cp = (uchar *) xp;
1153
0
  *cp++ = (uchar)((*ip) >> 8);
1154
0
  *cp   = (uchar)((*ip) & 0xff);
1155
0
}
1156
1157
static int
1158
ncx_get_ushort_schar(const void *xp, schar *ip)
1159
0
{
1160
0
    int err=NC_NOERR;
1161
0
    ix_ushort xx = 0;
1162
0
    get_ix_ushort(xp, &xx);
1163
1164
0
#if IX_USHORT_MAX > SCHAR_MAX
1165
0
    if (xx > SCHAR_MAX) {
1166
#ifdef ERANGE_FILL
1167
        *ip = NC_FILL_BYTE;
1168
        return NC_ERANGE;
1169
#else
1170
0
        err = NC_ERANGE;
1171
0
#endif
1172
0
    }
1173
0
#endif
1174
1175
1176
0
    *ip = (schar) xx;
1177
0
    return err;
1178
0
}
1179
1180
static int
1181
ncx_get_ushort_short(const void *xp, short *ip)
1182
0
{
1183
0
    int err=NC_NOERR;
1184
0
    ix_ushort xx = 0;
1185
0
    get_ix_ushort(xp, &xx);
1186
1187
0
#if IX_USHORT_MAX > SHORT_MAX
1188
0
    if (xx > SHORT_MAX) {
1189
#ifdef ERANGE_FILL
1190
        *ip = NC_FILL_SHORT;
1191
        return NC_ERANGE;
1192
#else
1193
0
        err = NC_ERANGE;
1194
0
#endif
1195
0
    }
1196
0
#endif
1197
1198
1199
0
    *ip = (short) xx;
1200
0
    return err;
1201
0
}
1202
1203
static int
1204
ncx_get_ushort_int(const void *xp, int *ip)
1205
0
{
1206
0
    int err=NC_NOERR;
1207
0
    ix_ushort xx = 0;
1208
0
    get_ix_ushort(xp, &xx);
1209
1210
#if IX_USHORT_MAX > INT_MAX
1211
    if (xx > INT_MAX) {
1212
#ifdef ERANGE_FILL
1213
        *ip = NC_FILL_INT;
1214
        return NC_ERANGE;
1215
#else
1216
        err = NC_ERANGE;
1217
#endif
1218
    }
1219
#endif
1220
1221
1222
0
    *ip = (int) xx;
1223
0
    return err;
1224
0
}
1225
1226
static int
1227
ncx_get_ushort_long(const void *xp, long *ip)
1228
0
{
1229
0
    int err=NC_NOERR;
1230
0
    ix_ushort xx = 0;
1231
0
    get_ix_ushort(xp, &xx);
1232
1233
#if IX_USHORT_MAX > LONG_MAX
1234
    if (xx > LONG_MAX) {
1235
#ifdef ERANGE_FILL
1236
        *ip = NC_FILL_INT;
1237
        return NC_ERANGE;
1238
#else
1239
        err = NC_ERANGE;
1240
#endif
1241
    }
1242
#endif
1243
1244
1245
0
    *ip = (long) xx;
1246
0
    return err;
1247
0
}
1248
1249
static int
1250
ncx_get_ushort_longlong(const void *xp, longlong *ip)
1251
0
{
1252
0
    int err=NC_NOERR;
1253
0
    ix_ushort xx = 0;
1254
0
    get_ix_ushort(xp, &xx);
1255
1256
#if IX_USHORT_MAX > LONGLONG_MAX
1257
    if (xx > LONGLONG_MAX) {
1258
#ifdef ERANGE_FILL
1259
        *ip = NC_FILL_INT64;
1260
        return NC_ERANGE;
1261
#else
1262
        err = NC_ERANGE;
1263
#endif
1264
    }
1265
#endif
1266
1267
1268
0
    *ip = (longlong) xx;
1269
0
    return err;
1270
0
}
1271
1272
static int
1273
ncx_get_ushort_ushort(const void *xp, ushort *ip)
1274
0
{
1275
0
    int err=NC_NOERR;
1276
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1277
0
    get_ix_ushort(xp, (ix_ushort *)ip);
1278
#else
1279
    ix_ushort xx = 0;
1280
    get_ix_ushort(xp, &xx);
1281
1282
#if IX_USHORT_MAX > USHORT_MAX
1283
    if (xx > USHORT_MAX) {
1284
#ifdef ERANGE_FILL
1285
        *ip = NC_FILL_USHORT;
1286
        return NC_ERANGE;
1287
#else
1288
        err = NC_ERANGE;
1289
#endif
1290
    }
1291
#endif
1292
1293
1294
    *ip = (ushort) xx;
1295
#endif
1296
0
    return err;
1297
0
}
1298
1299
static int
1300
ncx_get_ushort_uchar(const void *xp, uchar *ip)
1301
0
{
1302
0
    int err=NC_NOERR;
1303
#if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
1304
    get_ix_ushort(xp, (ix_ushort *)ip);
1305
#else
1306
0
    ix_ushort xx = 0;
1307
0
    get_ix_ushort(xp, &xx);
1308
1309
0
#if IX_USHORT_MAX > UCHAR_MAX
1310
0
    if (xx > UCHAR_MAX) {
1311
#ifdef ERANGE_FILL
1312
        *ip = NC_FILL_UBYTE;
1313
        return NC_ERANGE;
1314
#else
1315
0
        err = NC_ERANGE;
1316
0
#endif
1317
0
    }
1318
0
#endif
1319
1320
1321
0
    *ip = (uchar) xx;
1322
0
#endif
1323
0
    return err;
1324
0
}
1325
1326
static int
1327
ncx_get_ushort_uint(const void *xp, uint *ip)
1328
0
{
1329
0
    int err=NC_NOERR;
1330
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1331
    get_ix_ushort(xp, (ix_ushort *)ip);
1332
#else
1333
0
    ix_ushort xx = 0;
1334
0
    get_ix_ushort(xp, &xx);
1335
1336
#if IX_USHORT_MAX > UINT_MAX
1337
    if (xx > UINT_MAX) {
1338
#ifdef ERANGE_FILL
1339
        *ip = NC_FILL_UINT;
1340
        return NC_ERANGE;
1341
#else
1342
        err = NC_ERANGE;
1343
#endif
1344
    }
1345
#endif
1346
1347
1348
0
    *ip = (uint) xx;
1349
0
#endif
1350
0
    return err;
1351
0
}
1352
1353
static int
1354
ncx_get_ushort_ulonglong(const void *xp, ulonglong *ip)
1355
0
{
1356
0
    int err=NC_NOERR;
1357
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1358
    get_ix_ushort(xp, (ix_ushort *)ip);
1359
#else
1360
0
    ix_ushort xx = 0;
1361
0
    get_ix_ushort(xp, &xx);
1362
1363
#if IX_USHORT_MAX > ULONGLONG_MAX
1364
    if (xx > ULONGLONG_MAX) {
1365
#ifdef ERANGE_FILL
1366
        *ip = NC_FILL_UINT64;
1367
        return NC_ERANGE;
1368
#else
1369
        err = NC_ERANGE;
1370
#endif
1371
    }
1372
#endif
1373
1374
1375
0
    *ip = (ulonglong) xx;
1376
0
#endif
1377
0
    return err;
1378
0
}
1379
1380
static int
1381
ncx_get_ushort_float(const void *xp, float *ip)
1382
0
{
1383
0
  ix_ushort xx = 0;
1384
0
  get_ix_ushort(xp, &xx);
1385
0
  *ip = (float)xx;
1386
0
  return NC_NOERR;
1387
0
}
1388
1389
static int
1390
ncx_get_ushort_double(const void *xp, double *ip)
1391
0
{
1392
0
  ix_ushort xx = 0;
1393
0
  get_ix_ushort(xp, &xx);
1394
0
  *ip = (double)xx;
1395
0
  return NC_NOERR;
1396
0
}
1397
1398
1399
static int
1400
ncx_put_ushort_schar(void *xp, const schar *ip, void *fillp)
1401
0
{
1402
0
    int err=NC_NOERR;
1403
0
    uchar *cp;
1404
0
    if (*ip < 0) {
1405
#ifdef ERANGE_FILL
1406
        if (fillp != NULL) memcpy(xp, fillp, 2);
1407
#ifndef WORDS_BIGENDIAN
1408
        swapn2b(xp, xp, 1);
1409
#endif
1410
        return NC_ERANGE;
1411
#else
1412
0
        err = NC_ERANGE;
1413
0
#endif
1414
0
    }
1415
1416
0
    cp = (uchar *) xp;
1417
0
    if (*ip & 0x80)
1418
0
        *cp++ = 0xff;
1419
0
    else
1420
0
        *cp++ = 0;
1421
0
    *cp = (uchar)*ip;
1422
1423
0
    return err;
1424
0
}
1425
1426
static int
1427
ncx_put_ushort_uchar(void *xp, const uchar *ip, void *fillp)
1428
0
{
1429
0
  uchar *cp = (uchar *) xp;
1430
0
  *cp++ = 0;
1431
0
  *cp = *ip;
1432
0
  return NC_NOERR;
1433
0
}
1434
1435
static int
1436
ncx_put_ushort_short(void *xp, const short *ip, void *fillp)
1437
0
{
1438
0
    int err=NC_NOERR;
1439
0
    ix_ushort xx = NC_FILL_USHORT;
1440
1441
#if IX_USHORT_MAX < SHORT_MAX
1442
    if (*ip > IX_USHORT_MAX) {
1443
        
1444
#ifdef ERANGE_FILL
1445
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1446
#endif
1447
        err = NC_ERANGE;
1448
    }
1449
#ifdef ERANGE_FILL
1450
    else
1451
#endif
1452
#endif
1453
0
    if (*ip < 0) {
1454
        
1455
#ifdef ERANGE_FILL
1456
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1457
#endif
1458
0
        err = NC_ERANGE; /* because xp is unsigned */
1459
0
    }
1460
#ifdef ERANGE_FILL
1461
    else
1462
#endif
1463
0
        xx = (ix_ushort)*ip;
1464
1465
0
    put_ix_ushort(xp, &xx);
1466
0
    return err;
1467
0
}
1468
1469
static int
1470
ncx_put_ushort_int(void *xp, const int *ip, void *fillp)
1471
0
{
1472
0
    int err=NC_NOERR;
1473
0
    ix_ushort xx = NC_FILL_USHORT;
1474
1475
0
#if IX_USHORT_MAX < INT_MAX
1476
0
    if (*ip > IX_USHORT_MAX) {
1477
        
1478
#ifdef ERANGE_FILL
1479
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1480
#endif
1481
0
        err = NC_ERANGE;
1482
0
    }
1483
#ifdef ERANGE_FILL
1484
    else
1485
#endif
1486
0
#endif
1487
0
    if (*ip < 0) {
1488
        
1489
#ifdef ERANGE_FILL
1490
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1491
#endif
1492
0
        err = NC_ERANGE; /* because xp is unsigned */
1493
0
    }
1494
#ifdef ERANGE_FILL
1495
    else
1496
#endif
1497
0
        xx = (ix_ushort)*ip;
1498
1499
0
    put_ix_ushort(xp, &xx);
1500
0
    return err;
1501
0
}
1502
1503
static int
1504
ncx_put_ushort_long(void *xp, const long *ip, void *fillp)
1505
0
{
1506
0
    int err=NC_NOERR;
1507
0
    ix_ushort xx = NC_FILL_USHORT;
1508
1509
0
#if IX_USHORT_MAX < LONG_MAX
1510
0
    if (*ip > IX_USHORT_MAX) {
1511
        
1512
#ifdef ERANGE_FILL
1513
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1514
#endif
1515
0
        err = NC_ERANGE;
1516
0
    }
1517
#ifdef ERANGE_FILL
1518
    else
1519
#endif
1520
0
#endif
1521
0
    if (*ip < 0) {
1522
        
1523
#ifdef ERANGE_FILL
1524
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1525
#endif
1526
0
        err = NC_ERANGE; /* because xp is unsigned */
1527
0
    }
1528
#ifdef ERANGE_FILL
1529
    else
1530
#endif
1531
0
        xx = (ix_ushort)*ip;
1532
1533
0
    put_ix_ushort(xp, &xx);
1534
0
    return err;
1535
0
}
1536
1537
static int
1538
ncx_put_ushort_longlong(void *xp, const longlong *ip, void *fillp)
1539
0
{
1540
0
    int err=NC_NOERR;
1541
0
    ix_ushort xx = NC_FILL_USHORT;
1542
1543
0
#if IX_USHORT_MAX < LONGLONG_MAX
1544
0
    if (*ip > IX_USHORT_MAX) {
1545
        
1546
#ifdef ERANGE_FILL
1547
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1548
#endif
1549
0
        err = NC_ERANGE;
1550
0
    }
1551
#ifdef ERANGE_FILL
1552
    else
1553
#endif
1554
0
#endif
1555
0
    if (*ip < 0) {
1556
        
1557
#ifdef ERANGE_FILL
1558
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1559
#endif
1560
0
        err = NC_ERANGE; /* because xp is unsigned */
1561
0
    }
1562
#ifdef ERANGE_FILL
1563
    else
1564
#endif
1565
0
        xx = (ix_ushort)*ip;
1566
1567
0
    put_ix_ushort(xp, &xx);
1568
0
    return err;
1569
0
}
1570
1571
static int
1572
ncx_put_ushort_ushort(void *xp, const ushort *ip, void *fillp)
1573
0
{
1574
0
    int err=NC_NOERR;
1575
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1576
0
    put_ix_ushort(xp, (const ix_ushort *)ip);
1577
#else
1578
    ix_ushort xx = NC_FILL_USHORT;
1579
1580
#if IX_USHORT_MAX < USHORT_MAX
1581
    if (*ip > IX_USHORT_MAX) {
1582
        
1583
#ifdef ERANGE_FILL
1584
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1585
#endif
1586
        err = NC_ERANGE;
1587
    }
1588
#ifdef ERANGE_FILL
1589
    else
1590
#endif
1591
#endif
1592
        xx = (ix_ushort)*ip;
1593
1594
    put_ix_ushort(xp, &xx);
1595
#endif
1596
0
    return err;
1597
0
}
1598
1599
static int
1600
ncx_put_ushort_uint(void *xp, const uint *ip, void *fillp)
1601
0
{
1602
0
    int err=NC_NOERR;
1603
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1604
    put_ix_ushort(xp, (const ix_ushort *)ip);
1605
#else
1606
0
    ix_ushort xx = NC_FILL_USHORT;
1607
1608
0
#if IX_USHORT_MAX < UINT_MAX
1609
0
    if (*ip > IX_USHORT_MAX) {
1610
        
1611
#ifdef ERANGE_FILL
1612
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1613
#endif
1614
0
        err = NC_ERANGE;
1615
0
    }
1616
#ifdef ERANGE_FILL
1617
    else
1618
#endif
1619
0
#endif
1620
0
        xx = (ix_ushort)*ip;
1621
1622
0
    put_ix_ushort(xp, &xx);
1623
0
#endif
1624
0
    return err;
1625
0
}
1626
1627
static int
1628
ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1629
0
{
1630
0
    int err=NC_NOERR;
1631
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1632
    put_ix_ushort(xp, (const ix_ushort *)ip);
1633
#else
1634
0
    ix_ushort xx = NC_FILL_USHORT;
1635
1636
0
#if IX_USHORT_MAX < ULONGLONG_MAX
1637
0
    if (*ip > IX_USHORT_MAX) {
1638
        
1639
#ifdef ERANGE_FILL
1640
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1641
#endif
1642
0
        err = NC_ERANGE;
1643
0
    }
1644
#ifdef ERANGE_FILL
1645
    else
1646
#endif
1647
0
#endif
1648
0
        xx = (ix_ushort)*ip;
1649
1650
0
    put_ix_ushort(xp, &xx);
1651
0
#endif
1652
0
    return err;
1653
0
}
1654
1655
static int
1656
ncx_put_ushort_float(void *xp, const float *ip, void *fillp)
1657
0
{
1658
0
    int err=NC_NOERR;
1659
0
    ix_ushort xx = NC_FILL_USHORT;
1660
1661
0
    if (*ip > (double)X_USHORT_MAX || *ip < 0) {
1662
        
1663
#ifdef ERANGE_FILL
1664
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1665
#endif
1666
0
        err = NC_ERANGE;
1667
0
    }
1668
#ifdef ERANGE_FILL
1669
    else
1670
#endif
1671
0
        xx = (ix_ushort)*ip;
1672
1673
0
    put_ix_ushort(xp, &xx);
1674
0
    return err;
1675
0
}
1676
1677
static int
1678
ncx_put_ushort_double(void *xp, const double *ip, void *fillp)
1679
0
{
1680
0
    int err=NC_NOERR;
1681
0
    ix_ushort xx = NC_FILL_USHORT;
1682
1683
0
    if (*ip > X_USHORT_MAX || *ip < 0) {
1684
        
1685
#ifdef ERANGE_FILL
1686
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1687
#endif
1688
0
        err = NC_ERANGE;
1689
0
    }
1690
#ifdef ERANGE_FILL
1691
    else
1692
#endif
1693
0
        xx = (ix_ushort)*ip;
1694
1695
0
    put_ix_ushort(xp, &xx);
1696
0
    return err;
1697
0
}
1698
1699
1700
/* external NC_INT ----------------------------------------------------------*/
1701
1702
#if SHORT_MAX == X_INT_MAX
1703
typedef short ix_int;
1704
#define SIZEOF_IX_INT SIZEOF_SHORT
1705
#define IX_INT_MAX SHORT_MAX
1706
#elif INT_MAX  >= X_INT_MAX
1707
typedef int ix_int;
1708
#define SIZEOF_IX_INT SIZEOF_INT
1709
0
#define IX_INT_MAX INT_MAX
1710
#elif LONG_MAX  >= X_INT_MAX
1711
typedef long ix_int;
1712
#define SIZEOF_IX_INT SIZEOF_LONG
1713
#define IX_INT_MAX LONG_MAX
1714
#else
1715
#error "ix_int implementation"
1716
#endif
1717
1718
1719
static void
1720
get_ix_int(const void *xp, ix_int *ip)
1721
0
{
1722
0
  const uchar *cp = (const uchar *) xp;
1723
1724
0
#if INT_MAX  >= X_INT_MAX
1725
0
  *ip = (ix_int)((unsigned)(*cp++) << 24);
1726
#else
1727
  *ip = *cp++ << 24;
1728
#endif
1729
#if SIZEOF_IX_INT > X_SIZEOF_INT
1730
  if (*ip & 0x80000000)
1731
  {
1732
    /* extern is negative */
1733
    *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
1734
  }
1735
#endif
1736
0
  *ip |= (*cp++ << 16);
1737
0
  *ip |= (*cp++ << 8);
1738
0
  *ip |= *cp;
1739
0
}
1740
1741
static void
1742
put_ix_int(void *xp, const ix_int *ip)
1743
0
{
1744
0
  uchar *cp = (uchar *) xp;
1745
1746
0
  *cp++ = (uchar)( (*ip) >> 24);
1747
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
1748
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
1749
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
1750
0
}
1751
1752
#if X_SIZEOF_INT != SIZEOF_INT
1753
static int
1754
ncx_get_int_int(const void *xp, int *ip)
1755
{
1756
    int err=NC_NOERR;
1757
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1758
    get_ix_int(xp, (ix_int *)ip);
1759
#else
1760
    ix_int xx = 0;
1761
    get_ix_int(xp, &xx);
1762
1763
#if IX_INT_MAX > INT_MAX
1764
    if (xx > INT_MAX || xx < INT_MIN) {
1765
#ifdef ERANGE_FILL
1766
        *ip = NC_FILL_INT;
1767
        return NC_ERANGE;
1768
#else
1769
        err = NC_ERANGE;
1770
#endif
1771
    }
1772
#endif
1773
1774
1775
    *ip = (int) xx;
1776
#endif
1777
    return err;
1778
}
1779
1780
#endif
1781
static int
1782
ncx_get_int_schar(const void *xp, schar *ip)
1783
0
{
1784
0
    int err=NC_NOERR;
1785
0
    ix_int xx = 0;
1786
0
    get_ix_int(xp, &xx);
1787
1788
0
#if IX_INT_MAX > SCHAR_MAX
1789
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
1790
#ifdef ERANGE_FILL
1791
        *ip = NC_FILL_BYTE;
1792
        return NC_ERANGE;
1793
#else
1794
0
        err = NC_ERANGE;
1795
0
#endif
1796
0
    }
1797
0
#endif
1798
1799
1800
0
    *ip = (schar) xx;
1801
0
    return err;
1802
0
}
1803
1804
static int
1805
ncx_get_int_short(const void *xp, short *ip)
1806
0
{
1807
0
    int err=NC_NOERR;
1808
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1809
    get_ix_int(xp, (ix_int *)ip);
1810
#else
1811
0
    ix_int xx = 0;
1812
0
    get_ix_int(xp, &xx);
1813
1814
0
#if IX_INT_MAX > SHORT_MAX
1815
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
1816
#ifdef ERANGE_FILL
1817
        *ip = NC_FILL_SHORT;
1818
        return NC_ERANGE;
1819
#else
1820
0
        err = NC_ERANGE;
1821
0
#endif
1822
0
    }
1823
0
#endif
1824
1825
1826
0
    *ip = (short) xx;
1827
0
#endif
1828
0
    return err;
1829
0
}
1830
1831
static int
1832
ncx_get_int_long(const void *xp, long *ip)
1833
0
{
1834
0
    int err=NC_NOERR;
1835
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1836
    get_ix_int(xp, (ix_int *)ip);
1837
#else
1838
0
    ix_int xx = 0;
1839
0
    get_ix_int(xp, &xx);
1840
1841
#if IX_INT_MAX > LONG_MAX
1842
    if (xx > LONG_MAX || xx < LONG_MIN) {
1843
#ifdef ERANGE_FILL
1844
        *ip = NC_FILL_INT;
1845
        return NC_ERANGE;
1846
#else
1847
        err = NC_ERANGE;
1848
#endif
1849
    }
1850
#endif
1851
1852
1853
0
    *ip = (long) xx;
1854
0
#endif
1855
0
    return err;
1856
0
}
1857
1858
static int
1859
ncx_get_int_longlong(const void *xp, longlong *ip)
1860
0
{
1861
0
    int err=NC_NOERR;
1862
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1863
    get_ix_int(xp, (ix_int *)ip);
1864
#else
1865
0
    ix_int xx = 0;
1866
0
    get_ix_int(xp, &xx);
1867
1868
#if IX_INT_MAX > LONGLONG_MAX
1869
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
1870
#ifdef ERANGE_FILL
1871
        *ip = NC_FILL_INT64;
1872
        return NC_ERANGE;
1873
#else
1874
        err = NC_ERANGE;
1875
#endif
1876
    }
1877
#endif
1878
1879
1880
0
    *ip = (longlong) xx;
1881
0
#endif
1882
0
    return err;
1883
0
}
1884
1885
static int
1886
ncx_get_int_ushort(const void *xp, ushort *ip)
1887
0
{
1888
0
    int err=NC_NOERR;
1889
0
    ix_int xx = 0;
1890
0
    get_ix_int(xp, &xx);
1891
1892
0
#if IX_INT_MAX > USHORT_MAX
1893
0
    if (xx > USHORT_MAX) {
1894
#ifdef ERANGE_FILL
1895
        *ip = NC_FILL_USHORT;
1896
        return NC_ERANGE;
1897
#else
1898
0
        err = NC_ERANGE;
1899
0
#endif
1900
0
    }
1901
0
#endif
1902
1903
0
    if (xx < 0) {
1904
#ifdef ERANGE_FILL
1905
        *ip = NC_FILL_USHORT;
1906
        return NC_ERANGE;
1907
#else
1908
0
        err = NC_ERANGE; /* because ip is unsigned */
1909
0
#endif
1910
0
    }
1911
0
    *ip = (ushort) xx;
1912
0
    return err;
1913
0
}
1914
1915
static int
1916
ncx_get_int_uchar(const void *xp, uchar *ip)
1917
0
{
1918
0
    int err=NC_NOERR;
1919
0
    ix_int xx = 0;
1920
0
    get_ix_int(xp, &xx);
1921
1922
0
#if IX_INT_MAX > UCHAR_MAX
1923
0
    if (xx > UCHAR_MAX) {
1924
#ifdef ERANGE_FILL
1925
        *ip = NC_FILL_UBYTE;
1926
        return NC_ERANGE;
1927
#else
1928
0
        err = NC_ERANGE;
1929
0
#endif
1930
0
    }
1931
0
#endif
1932
1933
0
    if (xx < 0) {
1934
#ifdef ERANGE_FILL
1935
        *ip = NC_FILL_UBYTE;
1936
        return NC_ERANGE;
1937
#else
1938
0
        err = NC_ERANGE; /* because ip is unsigned */
1939
0
#endif
1940
0
    }
1941
0
    *ip = (uchar) xx;
1942
0
    return err;
1943
0
}
1944
1945
static int
1946
ncx_get_int_uint(const void *xp, uint *ip)
1947
0
{
1948
0
    int err=NC_NOERR;
1949
0
    ix_int xx = 0;
1950
0
    get_ix_int(xp, &xx);
1951
1952
#if IX_INT_MAX > UINT_MAX
1953
    if (xx > UINT_MAX) {
1954
#ifdef ERANGE_FILL
1955
        *ip = NC_FILL_UINT;
1956
        return NC_ERANGE;
1957
#else
1958
        err = NC_ERANGE;
1959
#endif
1960
    }
1961
#endif
1962
1963
0
    if (xx < 0) {
1964
#ifdef ERANGE_FILL
1965
        *ip = NC_FILL_UINT;
1966
        return NC_ERANGE;
1967
#else
1968
0
        err = NC_ERANGE; /* because ip is unsigned */
1969
0
#endif
1970
0
    }
1971
0
    *ip = (uint) xx;
1972
0
    return err;
1973
0
}
1974
1975
static int
1976
ncx_get_int_ulonglong(const void *xp, ulonglong *ip)
1977
0
{
1978
0
    int err=NC_NOERR;
1979
0
    ix_int xx = 0;
1980
0
    get_ix_int(xp, &xx);
1981
1982
#if IX_INT_MAX > ULONGLONG_MAX
1983
    if (xx > ULONGLONG_MAX) {
1984
#ifdef ERANGE_FILL
1985
        *ip = NC_FILL_UINT64;
1986
        return NC_ERANGE;
1987
#else
1988
        err = NC_ERANGE;
1989
#endif
1990
    }
1991
#endif
1992
1993
0
    if (xx < 0) {
1994
#ifdef ERANGE_FILL
1995
        *ip = NC_FILL_UINT64;
1996
        return NC_ERANGE;
1997
#else
1998
0
        err = NC_ERANGE; /* because ip is unsigned */
1999
0
#endif
2000
0
    }
2001
0
    *ip = (ulonglong) xx;
2002
0
    return err;
2003
0
}
2004
2005
static int
2006
ncx_get_int_float(const void *xp, float *ip)
2007
0
{
2008
0
  ix_int xx = 0;
2009
0
  get_ix_int(xp, &xx);
2010
0
  *ip = (float)xx;
2011
0
  return NC_NOERR;
2012
0
}
2013
2014
static int
2015
ncx_get_int_double(const void *xp, double *ip)
2016
0
{
2017
0
  ix_int xx = 0;
2018
0
  get_ix_int(xp, &xx);
2019
0
  *ip = (double)xx;
2020
0
  return NC_NOERR;
2021
0
}
2022
2023
2024
static int
2025
ncx_put_int_schar(void *xp, const schar *ip, void *fillp)
2026
0
{
2027
0
  uchar *cp = (uchar *) xp;
2028
0
  if (*ip & 0x80)
2029
0
  {
2030
0
    *cp++ = 0xff;
2031
0
    *cp++ = 0xff;
2032
0
    *cp++ = 0xff;
2033
0
  }
2034
0
  else
2035
0
  {
2036
0
    *cp++ = 0x00;
2037
0
    *cp++ = 0x00;
2038
0
    *cp++ = 0x00;
2039
0
  }
2040
0
  *cp = (uchar)*ip;
2041
0
  return NC_NOERR;
2042
0
}
2043
2044
static int
2045
ncx_put_int_uchar(void *xp, const uchar *ip, void *fillp)
2046
0
{
2047
0
  uchar *cp = (uchar *) xp;
2048
0
  *cp++ = 0x00;
2049
0
  *cp++ = 0x00;
2050
0
  *cp++ = 0x00;
2051
0
  *cp   = *ip;
2052
0
  return NC_NOERR;
2053
0
}
2054
2055
#if X_SIZEOF_INT != SIZEOF_INT
2056
static int
2057
ncx_put_int_int(void *xp, const int *ip, void *fillp)
2058
{
2059
    int err=NC_NOERR;
2060
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
2061
    put_ix_int(xp, (const ix_int *)ip);
2062
#else
2063
    ix_int xx = NC_FILL_INT;
2064
2065
#if IX_INT_MAX < INT_MAX
2066
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2067
        
2068
#ifdef ERANGE_FILL
2069
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2070
#endif
2071
        err = NC_ERANGE;
2072
    }
2073
#ifdef ERANGE_FILL
2074
    else
2075
#endif
2076
#endif
2077
        xx = (ix_int)*ip;
2078
2079
    put_ix_int(xp, &xx);
2080
#endif
2081
    return err;
2082
}
2083
2084
#endif
2085
static int
2086
ncx_put_int_short(void *xp, const short *ip, void *fillp)
2087
0
{
2088
0
    int err=NC_NOERR;
2089
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
2090
    put_ix_int(xp, (const ix_int *)ip);
2091
#else
2092
0
    ix_int xx = NC_FILL_INT;
2093
2094
#if IX_INT_MAX < SHORT_MAX
2095
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2096
        
2097
#ifdef ERANGE_FILL
2098
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2099
#endif
2100
        err = NC_ERANGE;
2101
    }
2102
#ifdef ERANGE_FILL
2103
    else
2104
#endif
2105
#endif
2106
0
        xx = (ix_int)*ip;
2107
2108
0
    put_ix_int(xp, &xx);
2109
0
#endif
2110
0
    return err;
2111
0
}
2112
2113
static int
2114
ncx_put_int_long(void *xp, const long *ip, void *fillp)
2115
0
{
2116
0
    int err=NC_NOERR;
2117
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
2118
    put_ix_int(xp, (const ix_int *)ip);
2119
#else
2120
0
    ix_int xx = NC_FILL_INT;
2121
2122
0
#if IX_INT_MAX < LONG_MAX
2123
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2124
        
2125
#ifdef ERANGE_FILL
2126
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2127
#endif
2128
0
        err = NC_ERANGE;
2129
0
    }
2130
#ifdef ERANGE_FILL
2131
    else
2132
#endif
2133
0
#endif
2134
0
        xx = (ix_int)*ip;
2135
2136
0
    put_ix_int(xp, &xx);
2137
0
#endif
2138
0
    return err;
2139
0
}
2140
2141
static int
2142
ncx_put_int_longlong(void *xp, const longlong *ip, void *fillp)
2143
0
{
2144
0
    int err=NC_NOERR;
2145
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
2146
    put_ix_int(xp, (const ix_int *)ip);
2147
#else
2148
0
    ix_int xx = NC_FILL_INT;
2149
2150
0
#if IX_INT_MAX < LONGLONG_MAX
2151
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2152
        
2153
#ifdef ERANGE_FILL
2154
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2155
#endif
2156
0
        err = NC_ERANGE;
2157
0
    }
2158
#ifdef ERANGE_FILL
2159
    else
2160
#endif
2161
0
#endif
2162
0
        xx = (ix_int)*ip;
2163
2164
0
    put_ix_int(xp, &xx);
2165
0
#endif
2166
0
    return err;
2167
0
}
2168
2169
static int
2170
ncx_put_int_ushort(void *xp, const ushort *ip, void *fillp)
2171
0
{
2172
0
    int err=NC_NOERR;
2173
0
    ix_int xx = NC_FILL_INT;
2174
2175
#if IX_INT_MAX < USHORT_MAX
2176
    if (*ip > IX_INT_MAX) {
2177
        
2178
#ifdef ERANGE_FILL
2179
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2180
#endif
2181
        err = NC_ERANGE;
2182
    }
2183
#ifdef ERANGE_FILL
2184
    else
2185
#endif
2186
#endif
2187
0
        xx = (ix_int)*ip;
2188
2189
0
    put_ix_int(xp, &xx);
2190
0
    return err;
2191
0
}
2192
2193
static int
2194
ncx_put_int_uint(void *xp, const uint *ip, void *fillp)
2195
0
{
2196
0
    int err=NC_NOERR;
2197
0
    ix_int xx = NC_FILL_INT;
2198
2199
0
#if IX_INT_MAX < UINT_MAX
2200
0
    if (*ip > IX_INT_MAX) {
2201
        
2202
#ifdef ERANGE_FILL
2203
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2204
#endif
2205
0
        err = NC_ERANGE;
2206
0
    }
2207
#ifdef ERANGE_FILL
2208
    else
2209
#endif
2210
0
#endif
2211
0
        xx = (ix_int)*ip;
2212
2213
0
    put_ix_int(xp, &xx);
2214
0
    return err;
2215
0
}
2216
2217
static int
2218
ncx_put_int_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2219
0
{
2220
0
    int err=NC_NOERR;
2221
0
    ix_int xx = NC_FILL_INT;
2222
2223
0
#if IX_INT_MAX < ULONGLONG_MAX
2224
0
    if (*ip > IX_INT_MAX) {
2225
        
2226
#ifdef ERANGE_FILL
2227
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2228
#endif
2229
0
        err = NC_ERANGE;
2230
0
    }
2231
#ifdef ERANGE_FILL
2232
    else
2233
#endif
2234
0
#endif
2235
0
        xx = (ix_int)*ip;
2236
2237
0
    put_ix_int(xp, &xx);
2238
0
    return err;
2239
0
}
2240
2241
static int
2242
ncx_put_int_float(void *xp, const float *ip, void *fillp)
2243
0
{
2244
0
    int err=NC_NOERR;
2245
0
    ix_int xx = NC_FILL_INT;
2246
2247
0
    if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
2248
        
2249
#ifdef ERANGE_FILL
2250
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2251
#endif
2252
0
        err = NC_ERANGE;
2253
0
    }
2254
#ifdef ERANGE_FILL
2255
    else
2256
#endif
2257
0
        xx = (ix_int)*ip;
2258
2259
0
    put_ix_int(xp, &xx);
2260
0
    return err;
2261
0
}
2262
2263
static int
2264
ncx_put_int_double(void *xp, const double *ip, void *fillp)
2265
0
{
2266
0
    int err=NC_NOERR;
2267
0
    ix_int xx = NC_FILL_INT;
2268
2269
0
    if (*ip > X_INT_MAX || *ip < X_INT_MIN) {
2270
        
2271
#ifdef ERANGE_FILL
2272
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2273
#endif
2274
0
        err = NC_ERANGE;
2275
0
    }
2276
#ifdef ERANGE_FILL
2277
    else
2278
#endif
2279
0
        xx = (ix_int)*ip;
2280
2281
0
    put_ix_int(xp, &xx);
2282
0
    return err;
2283
0
}
2284
2285
2286
2287
/* external NC_UINT ---------------------------------------------------------*/
2288
2289
#if USHORT_MAX == X_UINT_MAX
2290
typedef ushort ix_uint;
2291
#define SIZEOF_IX_UINT SIZEOF_USHORT
2292
#define IX_UINT_MAX USHORT_MAX
2293
#elif UINT_MAX  >= X_UINT_MAX
2294
typedef uint ix_uint;
2295
#define SIZEOF_IX_UINT SIZEOF_UINT
2296
0
#define IX_UINT_MAX UINT_MAX
2297
#elif ULONG_MAX  >= X_UINT_MAX
2298
typedef ulong ix_uint;
2299
#define SIZEOF_IX_UINT SIZEOF_ULONG
2300
#define IX_UINT_MAX ULONG_MAX
2301
#else
2302
#error "ix_uint implementation"
2303
#endif
2304
2305
2306
static void
2307
get_ix_uint(const void *xp, ix_uint *ip)
2308
0
{
2309
0
  const uchar *cp = (const uchar *) xp;
2310
2311
0
  *ip = (ix_uint)(*cp++ << 24);
2312
0
  *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 16));
2313
0
  *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 8));
2314
0
  *ip = (ix_uint)(*ip | *cp);
2315
0
}
2316
2317
static void
2318
put_ix_uint(void *xp, const ix_uint *ip)
2319
0
{
2320
0
  uchar *cp = (uchar *) xp;
2321
2322
0
  *cp++ = (uchar)((*ip) >> 24);
2323
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
2324
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
2325
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
2326
0
}
2327
2328
#if X_SIZEOF_UINT != SIZEOF_UINT
2329
static int
2330
ncx_get_uint_uint(const void *xp, uint *ip)
2331
{
2332
    int err=NC_NOERR;
2333
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2334
    get_ix_uint(xp, (ix_uint *)ip);
2335
#else
2336
    ix_uint xx = 0;
2337
    get_ix_uint(xp, &xx);
2338
2339
#if IX_UINT_MAX > UINT_MAX
2340
    if (xx > UINT_MAX) {
2341
#ifdef ERANGE_FILL
2342
        *ip = NC_FILL_UINT;
2343
        return NC_ERANGE;
2344
#else
2345
        err = NC_ERANGE;
2346
#endif
2347
    }
2348
#endif
2349
2350
2351
    *ip = (uint) xx;
2352
#endif
2353
    return err;
2354
}
2355
2356
#endif
2357
2358
static int
2359
ncx_get_uint_schar(const void *xp, schar *ip)
2360
0
{
2361
0
    int err=NC_NOERR;
2362
0
    ix_uint xx = 0;
2363
0
    get_ix_uint(xp, &xx);
2364
2365
0
#if IX_UINT_MAX > SCHAR_MAX
2366
0
    if (xx > SCHAR_MAX) {
2367
#ifdef ERANGE_FILL
2368
        *ip = NC_FILL_BYTE;
2369
        return NC_ERANGE;
2370
#else
2371
0
        err = NC_ERANGE;
2372
0
#endif
2373
0
    }
2374
0
#endif
2375
2376
2377
0
    *ip = (schar) xx;
2378
0
    return err;
2379
0
}
2380
2381
static int
2382
ncx_get_uint_short(const void *xp, short *ip)
2383
0
{
2384
0
    int err=NC_NOERR;
2385
0
    ix_uint xx = 0;
2386
0
    get_ix_uint(xp, &xx);
2387
2388
0
#if IX_UINT_MAX > SHORT_MAX
2389
0
    if (xx > SHORT_MAX) {
2390
#ifdef ERANGE_FILL
2391
        *ip = NC_FILL_SHORT;
2392
        return NC_ERANGE;
2393
#else
2394
0
        err = NC_ERANGE;
2395
0
#endif
2396
0
    }
2397
0
#endif
2398
2399
2400
0
    *ip = (short) xx;
2401
0
    return err;
2402
0
}
2403
2404
static int
2405
ncx_get_uint_int(const void *xp, int *ip)
2406
0
{
2407
0
    int err=NC_NOERR;
2408
0
    ix_uint xx = 0;
2409
0
    get_ix_uint(xp, &xx);
2410
2411
0
#if IX_UINT_MAX > INT_MAX
2412
0
    if (xx > INT_MAX) {
2413
#ifdef ERANGE_FILL
2414
        *ip = NC_FILL_INT;
2415
        return NC_ERANGE;
2416
#else
2417
0
        err = NC_ERANGE;
2418
0
#endif
2419
0
    }
2420
0
#endif
2421
2422
2423
0
    *ip = (int) xx;
2424
0
    return err;
2425
0
}
2426
2427
static int
2428
ncx_get_uint_long(const void *xp, long *ip)
2429
0
{
2430
0
    int err=NC_NOERR;
2431
0
    ix_uint xx = 0;
2432
0
    get_ix_uint(xp, &xx);
2433
2434
#if IX_UINT_MAX > LONG_MAX
2435
    if (xx > LONG_MAX) {
2436
#ifdef ERANGE_FILL
2437
        *ip = NC_FILL_INT;
2438
        return NC_ERANGE;
2439
#else
2440
        err = NC_ERANGE;
2441
#endif
2442
    }
2443
#endif
2444
2445
2446
0
    *ip = (long) xx;
2447
0
    return err;
2448
0
}
2449
2450
static int
2451
ncx_get_uint_longlong(const void *xp, longlong *ip)
2452
0
{
2453
0
    int err=NC_NOERR;
2454
0
    ix_uint xx = 0;
2455
0
    get_ix_uint(xp, &xx);
2456
2457
#if IX_UINT_MAX > LONGLONG_MAX
2458
    if (xx > LONGLONG_MAX) {
2459
#ifdef ERANGE_FILL
2460
        *ip = NC_FILL_INT64;
2461
        return NC_ERANGE;
2462
#else
2463
        err = NC_ERANGE;
2464
#endif
2465
    }
2466
#endif
2467
2468
2469
0
    *ip = (longlong) xx;
2470
0
    return err;
2471
0
}
2472
2473
static int
2474
ncx_get_uint_ushort(const void *xp, ushort *ip)
2475
0
{
2476
0
    int err=NC_NOERR;
2477
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2478
    get_ix_uint(xp, (ix_uint *)ip);
2479
#else
2480
0
    ix_uint xx = 0;
2481
0
    get_ix_uint(xp, &xx);
2482
2483
0
#if IX_UINT_MAX > USHORT_MAX
2484
0
    if (xx > USHORT_MAX) {
2485
#ifdef ERANGE_FILL
2486
        *ip = NC_FILL_USHORT;
2487
        return NC_ERANGE;
2488
#else
2489
0
        err = NC_ERANGE;
2490
0
#endif
2491
0
    }
2492
0
#endif
2493
2494
2495
0
    *ip = (ushort) xx;
2496
0
#endif
2497
0
    return err;
2498
0
}
2499
2500
static int
2501
ncx_get_uint_uchar(const void *xp, uchar *ip)
2502
0
{
2503
0
    int err=NC_NOERR;
2504
#if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
2505
    get_ix_uint(xp, (ix_uint *)ip);
2506
#else
2507
0
    ix_uint xx = 0;
2508
0
    get_ix_uint(xp, &xx);
2509
2510
0
#if IX_UINT_MAX > UCHAR_MAX
2511
0
    if (xx > UCHAR_MAX) {
2512
#ifdef ERANGE_FILL
2513
        *ip = NC_FILL_UBYTE;
2514
        return NC_ERANGE;
2515
#else
2516
0
        err = NC_ERANGE;
2517
0
#endif
2518
0
    }
2519
0
#endif
2520
2521
2522
0
    *ip = (uchar) xx;
2523
0
#endif
2524
0
    return err;
2525
0
}
2526
2527
static int
2528
ncx_get_uint_ulonglong(const void *xp, ulonglong *ip)
2529
0
{
2530
0
    int err=NC_NOERR;
2531
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2532
    get_ix_uint(xp, (ix_uint *)ip);
2533
#else
2534
0
    ix_uint xx = 0;
2535
0
    get_ix_uint(xp, &xx);
2536
2537
#if IX_UINT_MAX > ULONGLONG_MAX
2538
    if (xx > ULONGLONG_MAX) {
2539
#ifdef ERANGE_FILL
2540
        *ip = NC_FILL_UINT64;
2541
        return NC_ERANGE;
2542
#else
2543
        err = NC_ERANGE;
2544
#endif
2545
    }
2546
#endif
2547
2548
2549
0
    *ip = (ulonglong) xx;
2550
0
#endif
2551
0
    return err;
2552
0
}
2553
2554
static int
2555
ncx_get_uint_float(const void *xp, float *ip)
2556
0
{
2557
0
  ix_uint xx = 0;
2558
0
  get_ix_uint(xp, &xx);
2559
0
  *ip = (float)xx;
2560
0
  return NC_NOERR;
2561
0
}
2562
2563
static int
2564
ncx_get_uint_double(const void *xp, double *ip)
2565
0
{
2566
0
  ix_uint xx = 0;
2567
0
  get_ix_uint(xp, &xx);
2568
0
  *ip = (double)xx;
2569
0
  return NC_NOERR;
2570
0
}
2571
2572
2573
static int
2574
ncx_put_uint_schar(void *xp, const schar *ip, void *fillp)
2575
0
{
2576
0
    uchar *cp;
2577
0
    if (*ip < 0) {
2578
#ifdef ERANGE_FILL
2579
        if (fillp != NULL) memcpy(xp, fillp, 4);
2580
#ifndef WORDS_BIGENDIAN
2581
        swapn4b(xp, xp, 1);
2582
#endif
2583
#endif
2584
0
        return NC_ERANGE;
2585
0
    }
2586
2587
0
    cp = (uchar *) xp;
2588
0
    *cp++ = 0x00;
2589
0
    *cp++ = 0x00;
2590
0
    *cp++ = 0x00;
2591
0
    *cp = (uchar)*ip;
2592
2593
0
    return NC_NOERR;
2594
0
}
2595
2596
static int
2597
ncx_put_uint_uchar(void *xp, const uchar *ip, void *fillp)
2598
0
{
2599
0
  uchar *cp = (uchar *) xp;
2600
0
  *cp++ = 0x00;
2601
0
  *cp++ = 0x00;
2602
0
  *cp++ = 0x00;
2603
0
  *cp   = *ip;
2604
0
  return NC_NOERR;
2605
0
}
2606
2607
#if X_SIZEOF_UINT != SIZEOF_UINT
2608
static int
2609
ncx_put_uint_uint(void *xp, const uint *ip, void *fillp)
2610
{
2611
    int err=NC_NOERR;
2612
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2613
    put_ix_uint(xp, (const ix_uint *)ip);
2614
#else
2615
    ix_uint xx = NC_FILL_UINT;
2616
2617
#if IX_UINT_MAX < UINT_MAX
2618
    if (*ip > IX_UINT_MAX) {
2619
        
2620
#ifdef ERANGE_FILL
2621
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2622
#endif
2623
        err = NC_ERANGE;
2624
    }
2625
#ifdef ERANGE_FILL
2626
    else
2627
#endif
2628
#endif
2629
        xx = (ix_uint)*ip;
2630
2631
    put_ix_uint(xp, &xx);
2632
#endif
2633
    return err;
2634
}
2635
2636
#endif
2637
2638
static int
2639
ncx_put_uint_short(void *xp, const short *ip, void *fillp)
2640
0
{
2641
0
    int err=NC_NOERR;
2642
0
    ix_uint xx = NC_FILL_UINT;
2643
2644
#if IX_UINT_MAX < SHORT_MAX
2645
    if (*ip > IX_UINT_MAX) {
2646
        
2647
#ifdef ERANGE_FILL
2648
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2649
#endif
2650
        err = NC_ERANGE;
2651
    }
2652
#ifdef ERANGE_FILL
2653
    else
2654
#endif
2655
#endif
2656
0
    if (*ip < 0) {
2657
        
2658
#ifdef ERANGE_FILL
2659
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2660
#endif
2661
0
        err = NC_ERANGE; /* because xp is unsigned */
2662
0
    }
2663
#ifdef ERANGE_FILL
2664
    else
2665
#endif
2666
0
        xx = (ix_uint)*ip;
2667
2668
0
    put_ix_uint(xp, &xx);
2669
0
    return err;
2670
0
}
2671
2672
static int
2673
ncx_put_uint_int(void *xp, const int *ip, void *fillp)
2674
0
{
2675
0
    int err=NC_NOERR;
2676
0
    ix_uint xx = NC_FILL_UINT;
2677
2678
#if IX_UINT_MAX < INT_MAX
2679
    if (*ip > IX_UINT_MAX) {
2680
        
2681
#ifdef ERANGE_FILL
2682
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2683
#endif
2684
        err = NC_ERANGE;
2685
    }
2686
#ifdef ERANGE_FILL
2687
    else
2688
#endif
2689
#endif
2690
0
    if (*ip < 0) {
2691
        
2692
#ifdef ERANGE_FILL
2693
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2694
#endif
2695
0
        err = NC_ERANGE; /* because xp is unsigned */
2696
0
    }
2697
#ifdef ERANGE_FILL
2698
    else
2699
#endif
2700
0
        xx = (ix_uint)*ip;
2701
2702
0
    put_ix_uint(xp, &xx);
2703
0
    return err;
2704
0
}
2705
2706
static int
2707
ncx_put_uint_long(void *xp, const long *ip, void *fillp)
2708
0
{
2709
0
    int err=NC_NOERR;
2710
0
    ix_uint xx = NC_FILL_UINT;
2711
2712
0
#if IX_UINT_MAX < LONG_MAX
2713
0
    if (*ip > IX_UINT_MAX) {
2714
        
2715
#ifdef ERANGE_FILL
2716
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2717
#endif
2718
0
        err = NC_ERANGE;
2719
0
    }
2720
#ifdef ERANGE_FILL
2721
    else
2722
#endif
2723
0
#endif
2724
0
    if (*ip < 0) {
2725
        
2726
#ifdef ERANGE_FILL
2727
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2728
#endif
2729
0
        err = NC_ERANGE; /* because xp is unsigned */
2730
0
    }
2731
#ifdef ERANGE_FILL
2732
    else
2733
#endif
2734
0
        xx = (ix_uint)*ip;
2735
2736
0
    put_ix_uint(xp, &xx);
2737
0
    return err;
2738
0
}
2739
2740
static int
2741
ncx_put_uint_longlong(void *xp, const longlong *ip, void *fillp)
2742
0
{
2743
0
    int err=NC_NOERR;
2744
0
    ix_uint xx = NC_FILL_UINT;
2745
2746
0
#if IX_UINT_MAX < LONGLONG_MAX
2747
0
    if (*ip > IX_UINT_MAX) {
2748
        
2749
#ifdef ERANGE_FILL
2750
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2751
#endif
2752
0
        err = NC_ERANGE;
2753
0
    }
2754
#ifdef ERANGE_FILL
2755
    else
2756
#endif
2757
0
#endif
2758
0
    if (*ip < 0) {
2759
        
2760
#ifdef ERANGE_FILL
2761
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2762
#endif
2763
0
        err = NC_ERANGE; /* because xp is unsigned */
2764
0
    }
2765
#ifdef ERANGE_FILL
2766
    else
2767
#endif
2768
0
        xx = (ix_uint)*ip;
2769
2770
0
    put_ix_uint(xp, &xx);
2771
0
    return err;
2772
0
}
2773
2774
static int
2775
ncx_put_uint_ushort(void *xp, const ushort *ip, void *fillp)
2776
0
{
2777
0
    int err=NC_NOERR;
2778
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2779
    put_ix_uint(xp, (const ix_uint *)ip);
2780
#else
2781
0
    ix_uint xx = NC_FILL_UINT;
2782
2783
#if IX_UINT_MAX < USHORT_MAX
2784
    if (*ip > IX_UINT_MAX) {
2785
        
2786
#ifdef ERANGE_FILL
2787
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2788
#endif
2789
        err = NC_ERANGE;
2790
    }
2791
#ifdef ERANGE_FILL
2792
    else
2793
#endif
2794
#endif
2795
0
        xx = (ix_uint)*ip;
2796
2797
0
    put_ix_uint(xp, &xx);
2798
0
#endif
2799
0
    return err;
2800
0
}
2801
2802
static int
2803
ncx_put_uint_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2804
0
{
2805
0
    int err=NC_NOERR;
2806
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2807
    put_ix_uint(xp, (const ix_uint *)ip);
2808
#else
2809
0
    ix_uint xx = NC_FILL_UINT;
2810
2811
0
#if IX_UINT_MAX < ULONGLONG_MAX
2812
0
    if (*ip > IX_UINT_MAX) {
2813
        
2814
#ifdef ERANGE_FILL
2815
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2816
#endif
2817
0
        err = NC_ERANGE;
2818
0
    }
2819
#ifdef ERANGE_FILL
2820
    else
2821
#endif
2822
0
#endif
2823
0
        xx = (ix_uint)*ip;
2824
2825
0
    put_ix_uint(xp, &xx);
2826
0
#endif
2827
0
    return err;
2828
0
}
2829
2830
static int
2831
ncx_put_uint_float(void *xp, const float *ip, void *fillp)
2832
0
{
2833
0
    int err=NC_NOERR;
2834
0
    ix_uint xx = NC_FILL_UINT;
2835
2836
0
    if (*ip > (double)X_UINT_MAX || *ip < 0) {
2837
        
2838
#ifdef ERANGE_FILL
2839
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2840
#endif
2841
0
        err = NC_ERANGE;
2842
0
    }
2843
#ifdef ERANGE_FILL
2844
    else
2845
#endif
2846
0
        xx = (ix_uint)*ip;
2847
2848
0
    put_ix_uint(xp, &xx);
2849
0
    return err;
2850
0
}
2851
2852
static int
2853
ncx_put_uint_double(void *xp, const double *ip, void *fillp)
2854
0
{
2855
0
    int err=NC_NOERR;
2856
0
    ix_uint xx = NC_FILL_UINT;
2857
2858
0
    if (*ip > X_UINT_MAX || *ip < 0) {
2859
        
2860
#ifdef ERANGE_FILL
2861
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2862
#endif
2863
0
        err = NC_ERANGE;
2864
0
    }
2865
#ifdef ERANGE_FILL
2866
    else
2867
#endif
2868
0
        xx = (ix_uint)*ip;
2869
2870
0
    put_ix_uint(xp, &xx);
2871
0
    return err;
2872
0
}
2873
2874
2875
2876
/* external NC_FLOAT --------------------------------------------------------*/
2877
2878
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
2879
2880
inline static void
2881
get_ix_float(const void *xp, float *ip)
2882
0
{
2883
#ifdef WORDS_BIGENDIAN
2884
  (void) memcpy(ip, xp, SIZEOF_FLOAT);
2885
#else
2886
0
  swap4b(ip, xp);
2887
0
#endif
2888
0
}
2889
2890
inline static void
2891
put_ix_float(void *xp, const float *ip)
2892
0
{
2893
#ifdef WORDS_BIGENDIAN
2894
  (void) memcpy(xp, ip, X_SIZEOF_FLOAT);
2895
#else
2896
0
  swap4b(xp, ip);
2897
0
#endif
2898
0
}
2899
2900
#elif defined(vax) && vax != 0
2901
2902
/* What IEEE single precision floating point looks like on a Vax */
2903
struct  ieee_single {
2904
  unsigned int  exp_hi       : 7;
2905
  unsigned int  sign         : 1;
2906
  unsigned int  mant_hi      : 7;
2907
  unsigned int  exp_lo       : 1;
2908
  unsigned int  mant_lo_hi   : 8;
2909
  unsigned int  mant_lo_lo   : 8;
2910
};
2911
2912
/* Vax single precision floating point */
2913
struct  vax_single {
2914
  unsigned int  mantissa1 : 7;
2915
  unsigned int  exp       : 8;
2916
  unsigned int  sign      : 1;
2917
  unsigned int  mantissa2 : 16;
2918
};
2919
2920
#define VAX_SNG_BIAS  0x81
2921
#define IEEE_SNG_BIAS 0x7f
2922
2923
static struct sgl_limits {
2924
  struct vax_single s;
2925
  struct ieee_single ieee;
2926
} max = {
2927
  { 0x7f, 0xff, 0x0, 0xffff },  /* Max Vax */
2928
  { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }   /* Max IEEE */
2929
};
2930
static struct sgl_limits min = {
2931
  { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
2932
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }    /* Min IEEE */
2933
};
2934
2935
static void
2936
get_ix_float(const void *xp, float *ip)
2937
{
2938
    struct vax_single *const vsp = (struct vax_single *) ip;
2939
    const struct ieee_single *const isp =
2940
       (const struct ieee_single *) xp;
2941
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
2942
2943
    switch(exp) {
2944
    case 0 :
2945
      /* ieee subnormal */
2946
      if (isp->mant_hi == min.ieee.mant_hi
2947
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
2948
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
2949
      {
2950
        *vsp = min.s;
2951
      }
2952
      else
2953
      {
2954
        unsigned mantissa = (isp->mant_hi << 16)
2955
           | isp->mant_lo_hi << 8
2956
           | isp->mant_lo_lo;
2957
        unsigned tmp = mantissa >> 20;
2958
        if (tmp >= 4) {
2959
          vsp->exp = 2;
2960
        } else if (tmp >= 2) {
2961
          vsp->exp = 1;
2962
        } else {
2963
          *vsp = min.s;
2964
          break;
2965
        } /* else */
2966
        tmp = mantissa - (1 << (20 + vsp->exp ));
2967
        tmp <<= 3 - vsp->exp;
2968
        vsp->mantissa2 = tmp;
2969
        vsp->mantissa1 = (tmp >> 16);
2970
      }
2971
      break;
2972
    case 0xfe :
2973
    case 0xff :
2974
      *vsp = max.s;
2975
      break;
2976
    default :
2977
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
2978
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
2979
      vsp->mantissa1 = isp->mant_hi;
2980
    }
2981
2982
    vsp->sign = isp->sign;
2983
2984
}
2985
2986
2987
static void
2988
put_ix_float(void *xp, const float *ip)
2989
{
2990
    const struct vax_single *const vsp =
2991
       (const struct vax_single *)ip;
2992
    struct ieee_single *const isp = (struct ieee_single *) xp;
2993
2994
    switch(vsp->exp){
2995
    case 0 :
2996
      /* all vax float with zero exponent map to zero */
2997
      *isp = min.ieee;
2998
      break;
2999
    case 2 :
3000
    case 1 :
3001
    {
3002
      /* These will map to subnormals */
3003
      unsigned mantissa = (vsp->mantissa1 << 16)
3004
           | vsp->mantissa2;
3005
      mantissa >>= 3 - vsp->exp;
3006
      mantissa += (1 << (20 + vsp->exp));
3007
      isp->mant_lo_lo = mantissa;
3008
      isp->mant_lo_hi = mantissa >> 8;
3009
      isp->mant_hi = mantissa >> 16;
3010
      isp->exp_lo = 0;
3011
      isp->exp_hi = 0;
3012
    }
3013
      break;
3014
    case 0xff : /* max.s.exp */
3015
      if (vsp->mantissa2 == max.s.mantissa2 &&
3016
          vsp->mantissa1 == max.s.mantissa1)
3017
      {
3018
        /* map largest vax float to ieee infinity */
3019
        *isp = max.ieee;
3020
        break;
3021
      } /* else, fall thru */
3022
    default :
3023
    {
3024
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
3025
      isp->exp_hi = exp >> 1;
3026
      isp->exp_lo = exp;
3027
      isp->mant_lo_lo = vsp->mantissa2;
3028
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
3029
      isp->mant_hi = vsp->mantissa1;
3030
    }
3031
    }
3032
3033
    isp->sign = vsp->sign;
3034
3035
}
3036
3037
  /* vax */
3038
#elif defined(_CRAY) && !defined(__crayx1)
3039
3040
/*
3041
 * Return the number of bytes until the next "word" boundary
3042
 * N.B. This is based on the very weird YMP address structure,
3043
 * which puts the address within a word in the leftmost 3 bits
3044
 * of the address.
3045
 */
3046
static size_t
3047
word_align(const void *vp)
3048
{
3049
  const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
3050
  return (rem != 0);
3051
}
3052
3053
struct ieee_single_hi {
3054
  unsigned int  sign  : 1;
3055
  unsigned int   exp  : 8;
3056
  unsigned int  mant  :23;
3057
  unsigned int  pad :32;
3058
};
3059
typedef struct ieee_single_hi ieee_single_hi;
3060
3061
struct ieee_single_lo {
3062
  unsigned int  pad :32;
3063
  unsigned int  sign  : 1;
3064
  unsigned int   exp  : 8;
3065
  unsigned int  mant  :23;
3066
};
3067
typedef struct ieee_single_lo ieee_single_lo;
3068
3069
static const int ieee_single_bias = 0x7f;
3070
3071
struct ieee_double {
3072
  unsigned int  sign  : 1;
3073
  unsigned int   exp  :11;
3074
  unsigned int  mant  :52;
3075
};
3076
typedef struct ieee_double ieee_double;
3077
3078
static const int ieee_double_bias = 0x3ff;
3079
3080
#if defined(NO_IEEE_FLOAT)
3081
3082
struct cray_single {
3083
  unsigned int  sign  : 1;
3084
  unsigned int   exp  :15;
3085
  unsigned int  mant  :48;
3086
};
3087
typedef struct cray_single cray_single;
3088
3089
static const int cs_ieis_bias = 0x4000 - 0x7f;
3090
3091
static const int cs_id_bias = 0x4000 - 0x3ff;
3092
3093
3094
static void
3095
get_ix_float(const void *xp, float *ip)
3096
{
3097
3098
  if (word_align(xp) == 0)
3099
  {
3100
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3101
    cray_single *csp = (cray_single *) ip;
3102
3103
    if (isp->exp == 0)
3104
    {
3105
      /* ieee subnormal */
3106
      *ip = (double)isp->mant;
3107
      if (isp->mant != 0)
3108
      {
3109
        csp->exp -= (ieee_single_bias + 22);
3110
      }
3111
    }
3112
    else
3113
    {
3114
      csp->exp  = isp->exp + cs_ieis_bias + 1;
3115
      csp->mant = isp->mant << (48 - 1 - 23);
3116
      csp->mant |= (1 << (48 - 1));
3117
    }
3118
    csp->sign = isp->sign;
3119
3120
3121
  }
3122
  else
3123
  {
3124
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3125
    cray_single *csp = (cray_single *) ip;
3126
3127
    if (isp->exp == 0)
3128
    {
3129
      /* ieee subnormal */
3130
      *ip = (double)isp->mant;
3131
      if (isp->mant != 0)
3132
      {
3133
        csp->exp -= (ieee_single_bias + 22);
3134
      }
3135
    }
3136
    else
3137
    {
3138
      csp->exp  = isp->exp + cs_ieis_bias + 1;
3139
      csp->mant = isp->mant << (48 - 1 - 23);
3140
      csp->mant |= (1 << (48 - 1));
3141
    }
3142
    csp->sign = isp->sign;
3143
3144
3145
  }
3146
}
3147
3148
static void
3149
put_ix_float(void *xp, const float *ip)
3150
{
3151
  if (word_align(xp) == 0)
3152
  {
3153
    ieee_single_hi *isp = (ieee_single_hi*)xp;
3154
  const cray_single *csp = (const cray_single *) ip;
3155
  int ieee_exp = csp->exp - cs_ieis_bias -1;
3156
3157
  isp->sign = csp->sign;
3158
3159
  if (ieee_exp >= 0xff)
3160
  {
3161
    /* NC_ERANGE => ieee Inf */
3162
    isp->exp = 0xff;
3163
    isp->mant = 0x0;
3164
  }
3165
  else if (ieee_exp > 0)
3166
  {
3167
    /* normal ieee representation */
3168
    isp->exp  = ieee_exp;
3169
    /* assumes cray rep is in normal form */
3170
    assert(csp->mant & 0x800000000000);
3171
    isp->mant = (((csp->mant << 1) &
3172
        0xffffffffffff) >> (48 - 23));
3173
  }
3174
  else if (ieee_exp > -23)
3175
  {
3176
    /* ieee subnormal, right shift */
3177
    const int rshift = (48 - 23 - ieee_exp);
3178
3179
    isp->mant = csp->mant >> rshift;
3180
3181
#if 0
3182
    if (csp->mant & (1 << (rshift -1)))
3183
    {
3184
      /* round up */
3185
      isp->mant++;
3186
    }
3187
#endif
3188
3189
    isp->exp  = 0;
3190
  }
3191
  else
3192
  {
3193
    /* smaller than ieee can represent */
3194
    isp->exp = 0;
3195
    isp->mant = 0;
3196
  }
3197
3198
  }
3199
  else
3200
  {
3201
    ieee_single_lo *isp = (ieee_single_lo*)xp;
3202
  const cray_single *csp = (const cray_single *) ip;
3203
  int ieee_exp = csp->exp - cs_ieis_bias -1;
3204
3205
  isp->sign = csp->sign;
3206
3207
  if (ieee_exp >= 0xff)
3208
  {
3209
    /* NC_ERANGE => ieee Inf */
3210
    isp->exp = 0xff;
3211
    isp->mant = 0x0;
3212
  }
3213
  else if (ieee_exp > 0)
3214
  {
3215
    /* normal ieee representation */
3216
    isp->exp  = ieee_exp;
3217
    /* assumes cray rep is in normal form */
3218
    assert(csp->mant & 0x800000000000);
3219
    isp->mant = (((csp->mant << 1) &
3220
        0xffffffffffff) >> (48 - 23));
3221
  }
3222
  else if (ieee_exp > -23)
3223
  {
3224
    /* ieee subnormal, right shift */
3225
    const int rshift = (48 - 23 - ieee_exp);
3226
3227
    isp->mant = csp->mant >> rshift;
3228
3229
#if 0
3230
    if (csp->mant & (1 << (rshift -1)))
3231
    {
3232
      /* round up */
3233
      isp->mant++;
3234
    }
3235
#endif
3236
3237
    isp->exp  = 0;
3238
  }
3239
  else
3240
  {
3241
    /* smaller than ieee can represent */
3242
    isp->exp = 0;
3243
    isp->mant = 0;
3244
  }
3245
3246
  }
3247
}
3248
3249
#else
3250
  /* IEEE Cray with only doubles */
3251
static void
3252
get_ix_float(const void *xp, float *ip)
3253
{
3254
3255
  ieee_double *idp = (ieee_double *) ip;
3256
3257
  if (word_align(xp) == 0)
3258
  {
3259
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3260
    if (isp->exp == 0 && isp->mant == 0)
3261
    {
3262
      idp->exp = 0;
3263
      idp->mant = 0;
3264
    }
3265
    else
3266
    {
3267
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3268
      idp->mant = isp->mant << (52 - 23);
3269
    }
3270
    idp->sign = isp->sign;
3271
  }
3272
  else
3273
  {
3274
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3275
    if (isp->exp == 0 && isp->mant == 0)
3276
    {
3277
      idp->exp = 0;
3278
      idp->mant = 0;
3279
    }
3280
    else
3281
    {
3282
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3283
      idp->mant = isp->mant << (52 - 23);
3284
    }
3285
    idp->sign = isp->sign;
3286
  }
3287
}
3288
3289
static void
3290
put_ix_float(void *xp, const float *ip)
3291
{
3292
  const ieee_double *idp = (const ieee_double *) ip;
3293
  if (word_align(xp) == 0)
3294
  {
3295
    ieee_single_hi *isp = (ieee_single_hi*)xp;
3296
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3297
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3298
    else
3299
      isp->exp = 0;
3300
    isp->mant = idp->mant >> (52 - 23);
3301
    isp->sign = idp->sign;
3302
  }
3303
  else
3304
  {
3305
    ieee_single_lo *isp = (ieee_single_lo*)xp;
3306
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3307
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3308
    else
3309
      isp->exp = 0;
3310
    isp->mant = idp->mant >> (52 - 23);
3311
    isp->sign = idp->sign;
3312
  }
3313
}
3314
#endif
3315
3316
#else
3317
#error "ix_float implementation"
3318
#endif
3319
3320
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3321
static int
3322
ncx_get_float_float(const void *xp, float *ip, void *fillp)
3323
{
3324
  /* TODO */
3325
  get_ix_float(xp, ip);
3326
  return NC_NOERR;
3327
}
3328
#endif
3329
3330
0
#define ix_float float
3331
3332
static int
3333
ncx_get_float_schar(const void *xp, schar *ip)
3334
0
{
3335
0
  ix_float xx = 0;
3336
0
  get_ix_float(xp, &xx);
3337
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3338
#ifdef ERANGE_FILL
3339
            *ip = NC_FILL_BYTE;
3340
#endif
3341
0
            return NC_ERANGE;
3342
0
        }
3343
0
  *ip = (schar)xx;
3344
0
  return NC_NOERR;
3345
0
}
3346
3347
static int
3348
ncx_get_float_short(const void *xp, short *ip)
3349
0
{
3350
0
  ix_float xx = 0;
3351
0
  get_ix_float(xp, &xx);
3352
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3353
#ifdef ERANGE_FILL
3354
            *ip = NC_FILL_SHORT;
3355
#endif
3356
0
            return NC_ERANGE;
3357
0
        }
3358
0
  *ip = (short)xx;
3359
0
  return NC_NOERR;
3360
0
}
3361
3362
static int
3363
ncx_get_float_int(const void *xp, int *ip)
3364
0
{
3365
0
  ix_float xx = 0;
3366
0
  get_ix_float(xp, &xx);
3367
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3368
#ifdef ERANGE_FILL
3369
            *ip = NC_FILL_INT;
3370
#endif
3371
0
            return NC_ERANGE;
3372
0
        }
3373
0
  *ip = (int)xx;
3374
0
  return NC_NOERR;
3375
0
}
3376
3377
static int
3378
ncx_get_float_long(const void *xp, long *ip)
3379
0
{
3380
0
  ix_float xx = 0;
3381
0
  get_ix_float(xp, &xx);
3382
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3383
#ifdef ERANGE_FILL
3384
            *ip = NC_FILL_INT;
3385
#endif
3386
0
            return NC_ERANGE;
3387
0
        }
3388
0
  *ip = (long)xx;
3389
0
  return NC_NOERR;
3390
0
}
3391
3392
static int
3393
ncx_get_float_double(const void *xp, double *ip)
3394
0
{
3395
0
  ix_float xx = 0;
3396
0
  get_ix_float(xp, &xx);
3397
0
  *ip = (double)xx;
3398
0
  return NC_NOERR;
3399
0
}
3400
3401
static int
3402
ncx_get_float_longlong(const void *xp, longlong *ip)
3403
0
{
3404
0
  ix_float xx = 0;
3405
0
  get_ix_float(xp, &xx);
3406
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3407
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3408
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3409
#ifdef ERANGE_FILL
3410
            *ip = NC_FILL_INT64;
3411
#endif
3412
0
            return NC_ERANGE;
3413
0
        }
3414
0
  else *ip = (longlong)xx;
3415
0
  return NC_NOERR;
3416
0
}
3417
3418
static int
3419
ncx_get_float_uchar(const void *xp, uchar *ip)
3420
0
{
3421
0
  ix_float xx = 0;
3422
0
  get_ix_float(xp, &xx);
3423
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3424
#ifdef ERANGE_FILL
3425
            *ip = NC_FILL_UBYTE;
3426
#endif
3427
0
            return NC_ERANGE;
3428
0
        }
3429
0
  *ip = (uchar)xx;
3430
0
  return NC_NOERR;
3431
0
}
3432
3433
static int
3434
ncx_get_float_ushort(const void *xp, ushort *ip)
3435
0
{
3436
0
  ix_float xx = 0;
3437
0
  get_ix_float(xp, &xx);
3438
0
  if (xx > (double)USHORT_MAX || xx < 0) {
3439
#ifdef ERANGE_FILL
3440
            *ip = NC_FILL_USHORT;
3441
#endif
3442
0
            return NC_ERANGE;
3443
0
        }
3444
0
  *ip = (ushort)xx;
3445
0
  return NC_NOERR;
3446
0
}
3447
3448
static int
3449
ncx_get_float_uint(const void *xp, uint *ip)
3450
0
{
3451
0
  ix_float xx = 0;
3452
0
  get_ix_float(xp, &xx);
3453
0
  if (xx > (double)UINT_MAX || xx < 0) {
3454
#ifdef ERANGE_FILL
3455
            *ip = NC_FILL_UINT;
3456
#endif
3457
0
            return NC_ERANGE;
3458
0
        }
3459
0
  *ip = (uint)xx;
3460
0
  return NC_NOERR;
3461
0
}
3462
3463
static int
3464
ncx_get_float_ulonglong(const void *xp, ulonglong *ip)
3465
0
{
3466
0
  ix_float xx = 0;
3467
0
  get_ix_float(xp, &xx);
3468
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3469
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3470
#ifdef ERANGE_FILL
3471
            *ip = NC_FILL_UINT64;
3472
#endif
3473
0
            return NC_ERANGE;
3474
0
        }
3475
0
  else *ip = (ulonglong)xx;
3476
0
  return NC_NOERR;
3477
0
}
3478
3479
3480
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3481
static int
3482
ncx_put_float_float(void *xp, const float *ip, void *fillp)
3483
{
3484
    int err=NC_NOERR;
3485
    float *_ip=ip;
3486
#ifdef NO_IEEE_FLOAT
3487
#ifdef ERANGE_FILL
3488
    float tmp;
3489
#endif
3490
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3491
        
3492
#ifdef ERANGE_FILL
3493
            if (fillp != NULL) memcpy(&tmp, fillp, 4);
3494
#endif
3495
#ifdef ERANGE_FILL
3496
        _ip = &tmp;
3497
#endif
3498
        err = NC_ERANGE;
3499
    }
3500
#endif
3501
    put_ix_float(xp, _ip);
3502
    return err;
3503
}
3504
#endif
3505
3506
static int
3507
ncx_put_float_schar(void *xp, const schar *ip, void *fillp)
3508
0
{
3509
0
    int err=NC_NOERR;
3510
0
    ix_float xx = NC_FILL_FLOAT;
3511
3512
    
3513
0
        xx = (ix_float)*ip;
3514
3515
0
    put_ix_float(xp, &xx);
3516
0
    return err;
3517
0
}
3518
3519
static int
3520
ncx_put_float_short(void *xp, const short *ip, void *fillp)
3521
0
{
3522
0
    int err=NC_NOERR;
3523
0
    ix_float xx = NC_FILL_FLOAT;
3524
3525
    
3526
0
        xx = (ix_float)*ip;
3527
3528
0
    put_ix_float(xp, &xx);
3529
0
    return err;
3530
0
}
3531
3532
static int
3533
ncx_put_float_int(void *xp, const int *ip, void *fillp)
3534
0
{
3535
0
    int err=NC_NOERR;
3536
0
    ix_float xx = NC_FILL_FLOAT;
3537
3538
    
3539
0
        xx = (ix_float)*ip;
3540
3541
0
    put_ix_float(xp, &xx);
3542
0
    return err;
3543
0
}
3544
3545
static int
3546
ncx_put_float_long(void *xp, const long *ip, void *fillp)
3547
0
{
3548
0
    int err=NC_NOERR;
3549
0
    ix_float xx = NC_FILL_FLOAT;
3550
3551
    
3552
0
        xx = (ix_float)*ip;
3553
3554
0
    put_ix_float(xp, &xx);
3555
0
    return err;
3556
0
}
3557
3558
static int
3559
ncx_put_float_double(void *xp, const double *ip, void *fillp)
3560
0
{
3561
0
    int err=NC_NOERR;
3562
0
    ix_float xx = NC_FILL_FLOAT;
3563
3564
0
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3565
        
3566
#ifdef ERANGE_FILL
3567
            if (fillp != NULL) memcpy(&xx, fillp, 4);
3568
#endif
3569
0
        err = NC_ERANGE;
3570
0
    }
3571
#ifdef ERANGE_FILL
3572
    else
3573
#endif
3574
0
        xx = (ix_float)*ip;
3575
3576
0
    put_ix_float(xp, &xx);
3577
0
    return err;
3578
0
}
3579
3580
static int
3581
ncx_put_float_longlong(void *xp, const longlong *ip, void *fillp)
3582
0
{
3583
0
    int err=NC_NOERR;
3584
0
    ix_float xx = NC_FILL_FLOAT;
3585
3586
    
3587
0
        xx = (ix_float)*ip;
3588
3589
0
    put_ix_float(xp, &xx);
3590
0
    return err;
3591
0
}
3592
3593
static int
3594
ncx_put_float_uchar(void *xp, const uchar *ip, void *fillp)
3595
0
{
3596
0
    int err=NC_NOERR;
3597
0
    ix_float xx = NC_FILL_FLOAT;
3598
3599
    
3600
0
        xx = (ix_float)*ip;
3601
3602
0
    put_ix_float(xp, &xx);
3603
0
    return err;
3604
0
}
3605
3606
static int
3607
ncx_put_float_ushort(void *xp, const ushort *ip, void *fillp)
3608
0
{
3609
0
    int err=NC_NOERR;
3610
0
    ix_float xx = NC_FILL_FLOAT;
3611
3612
    
3613
0
        xx = (ix_float)*ip;
3614
3615
0
    put_ix_float(xp, &xx);
3616
0
    return err;
3617
0
}
3618
3619
static int
3620
ncx_put_float_uint(void *xp, const uint *ip, void *fillp)
3621
0
{
3622
0
    int err=NC_NOERR;
3623
0
    ix_float xx = NC_FILL_FLOAT;
3624
3625
    
3626
0
        xx = (ix_float)*ip;
3627
3628
0
    put_ix_float(xp, &xx);
3629
0
    return err;
3630
0
}
3631
3632
static int
3633
ncx_put_float_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3634
0
{
3635
0
    int err=NC_NOERR;
3636
0
    ix_float xx = NC_FILL_FLOAT;
3637
3638
    
3639
0
        xx = (ix_float)*ip;
3640
3641
0
    put_ix_float(xp, &xx);
3642
0
    return err;
3643
0
}
3644
3645
3646
3647
/* external NC_DOUBLE -------------------------------------------------------*/
3648
3649
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
3650
3651
static void
3652
get_ix_double(const void *xp, double *ip)
3653
0
{
3654
#ifdef WORDS_BIGENDIAN
3655
  (void) memcpy(ip, xp, SIZEOF_DOUBLE);
3656
#else
3657
0
  swap8b(ip, xp);
3658
0
#endif
3659
0
}
3660
3661
static void
3662
put_ix_double(void *xp, const double *ip)
3663
0
{
3664
#ifdef WORDS_BIGENDIAN
3665
  (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
3666
#else
3667
0
  swap8b(xp, ip);
3668
0
#endif
3669
0
}
3670
3671
#elif defined(vax) && vax != 0
3672
3673
/* What IEEE double precision floating point looks like on a Vax */
3674
struct  ieee_double {
3675
  unsigned int  exp_hi   : 7;
3676
  unsigned int  sign     : 1;
3677
  unsigned int  mant_6   : 4;
3678
  unsigned int  exp_lo   : 4;
3679
  unsigned int  mant_5   : 8;
3680
  unsigned int  mant_4   : 8;
3681
3682
  unsigned int  mant_lo  : 32;
3683
};
3684
3685
/* Vax double precision floating point */
3686
struct  vax_double {
3687
  unsigned int  mantissa1 : 7;
3688
  unsigned int  exp       : 8;
3689
  unsigned int  sign      : 1;
3690
  unsigned int  mantissa2 : 16;
3691
  unsigned int  mantissa3 : 16;
3692
  unsigned int  mantissa4 : 16;
3693
};
3694
3695
#define VAX_DBL_BIAS  0x81
3696
#define IEEE_DBL_BIAS 0x3ff
3697
#define MASK(nbits) ((1 << nbits) - 1)
3698
3699
static const struct dbl_limits {
3700
  struct  vax_double d;
3701
  struct  ieee_double ieee;
3702
} dbl_limits[2] = {
3703
  {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
3704
  { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
3705
  {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},   /* Min Vax */
3706
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
3707
};
3708
3709
3710
static void
3711
get_ix_double(const void *xp, double *ip)
3712
{
3713
  struct vax_double *const vdp =
3714
       (struct vax_double *)ip;
3715
  const struct ieee_double *const idp =
3716
       (const struct ieee_double *) xp;
3717
  {
3718
    const struct dbl_limits *lim;
3719
    int ii;
3720
    for (ii = 0, lim = dbl_limits;
3721
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
3722
      ii++, lim++)
3723
    {
3724
      if ((idp->mant_lo == lim->ieee.mant_lo)
3725
        && (idp->mant_4 == lim->ieee.mant_4)
3726
        && (idp->mant_5 == lim->ieee.mant_5)
3727
        && (idp->mant_6 == lim->ieee.mant_6)
3728
        && (idp->exp_lo == lim->ieee.exp_lo)
3729
        && (idp->exp_hi == lim->ieee.exp_hi)
3730
        )
3731
      {
3732
        *vdp = lim->d;
3733
        goto doneit;
3734
      }
3735
    }
3736
  }
3737
  {
3738
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
3739
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
3740
  }
3741
  {
3742
    unsigned mant_hi = ((idp->mant_6 << 16)
3743
         | (idp->mant_5 << 8)
3744
         | idp->mant_4);
3745
    unsigned mant_lo = SWAP4(idp->mant_lo);
3746
    vdp->mantissa1 = (mant_hi >> 13);
3747
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
3748
        | (mant_lo >> 29);
3749
    vdp->mantissa3 = (mant_lo >> 13);
3750
    vdp->mantissa4 = (mant_lo << 3);
3751
  }
3752
  doneit:
3753
    vdp->sign = idp->sign;
3754
3755
}
3756
3757
3758
static void
3759
put_ix_double(void *xp, const double *ip)
3760
{
3761
  const struct vax_double *const vdp =
3762
      (const struct vax_double *)ip;
3763
  struct ieee_double *const idp =
3764
       (struct ieee_double *) xp;
3765
3766
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
3767
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
3768
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
3769
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
3770
    (vdp->exp == dbl_limits[0].d.exp))
3771
  {
3772
    *idp = dbl_limits[0].ieee;
3773
    goto shipit;
3774
  }
3775
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
3776
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
3777
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
3778
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
3779
    (vdp->exp == dbl_limits[1].d.exp))
3780
  {
3781
    *idp = dbl_limits[1].ieee;
3782
    goto shipit;
3783
  }
3784
3785
  {
3786
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
3787
3788
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
3789
      (vdp->mantissa3 << 13) |
3790
      ((vdp->mantissa4 >> 3) & MASK(13));
3791
3792
    unsigned mant_hi = (vdp->mantissa1 << 13)
3793
         | (vdp->mantissa2 >> 3);
3794
3795
    if ((vdp->mantissa4 & 7) > 4)
3796
    {
3797
      /* round up */
3798
      mant_lo++;
3799
      if (mant_lo == 0)
3800
      {
3801
        mant_hi++;
3802
        if (mant_hi > 0xffffff)
3803
        {
3804
          mant_hi = 0;
3805
          exp++;
3806
        }
3807
      }
3808
    }
3809
3810
    idp->mant_lo = SWAP4(mant_lo);
3811
    idp->mant_6 = mant_hi >> 16;
3812
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
3813
    idp->mant_4 = mant_hi;
3814
    idp->exp_hi = exp >> 4;
3815
    idp->exp_lo = exp;
3816
  }
3817
3818
  shipit:
3819
    idp->sign = vdp->sign;
3820
3821
}
3822
3823
  /* vax */
3824
#elif defined(_CRAY) && !defined(__crayx1)
3825
3826
static void
3827
get_ix_double(const void *xp, double *ip)
3828
{
3829
  const ieee_double *idp = (const ieee_double *) xp;
3830
  cray_single *csp = (cray_single *) ip;
3831
3832
  if (idp->exp == 0)
3833
  {
3834
    /* ieee subnormal */
3835
    *ip = (double)idp->mant;
3836
    if (idp->mant != 0)
3837
    {
3838
      csp->exp -= (ieee_double_bias + 51);
3839
    }
3840
  }
3841
  else
3842
  {
3843
    csp->exp  = idp->exp + cs_id_bias + 1;
3844
    csp->mant = idp->mant >> (52 - 48 + 1);
3845
    csp->mant |= (1 << (48 - 1));
3846
  }
3847
  csp->sign = idp->sign;
3848
}
3849
3850
static void
3851
put_ix_double(void *xp, const double *ip)
3852
{
3853
  ieee_double *idp = (ieee_double *) xp;
3854
  const cray_single *csp = (const cray_single *) ip;
3855
3856
  int ieee_exp = csp->exp - cs_id_bias -1;
3857
3858
  idp->sign = csp->sign;
3859
3860
  if (ieee_exp >= 0x7ff)
3861
  {
3862
    /* NC_ERANGE => ieee Inf */
3863
    idp->exp = 0x7ff;
3864
    idp->mant = 0x0;
3865
  }
3866
  else if (ieee_exp > 0)
3867
  {
3868
    /* normal ieee representation */
3869
    idp->exp  = ieee_exp;
3870
    /* assumes cray rep is in normal form */
3871
    assert(csp->mant & 0x800000000000);
3872
    idp->mant = (((csp->mant << 1) &
3873
        0xffffffffffff) << (52 - 48));
3874
  }
3875
  else if (ieee_exp >= (-(52 -48)))
3876
  {
3877
    /* ieee subnormal, left shift */
3878
    const int lshift = (52 - 48) + ieee_exp;
3879
    idp->mant = csp->mant << lshift;
3880
    idp->exp  = 0;
3881
  }
3882
  else if (ieee_exp >= -52)
3883
  {
3884
    /* ieee subnormal, right shift */
3885
    const int rshift = (- (52 - 48) - ieee_exp);
3886
3887
    idp->mant = csp->mant >> rshift;
3888
3889
#if 0
3890
    if (csp->mant & (1 << (rshift -1)))
3891
    {
3892
      /* round up */
3893
      idp->mant++;
3894
    }
3895
#endif
3896
3897
    idp->exp  = 0;
3898
  }
3899
  else
3900
  {
3901
    /* smaller than ieee can represent */
3902
    idp->exp = 0;
3903
    idp->mant = 0;
3904
  }
3905
}
3906
#else
3907
#error "ix_double implementation"
3908
#endif
3909
3910
0
#define ix_double double
3911
3912
static int
3913
ncx_get_double_schar(const void *xp, schar *ip)
3914
0
{
3915
0
  ix_double xx = 0;
3916
0
  get_ix_double(xp, &xx);
3917
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3918
#ifdef ERANGE_FILL
3919
            *ip = NC_FILL_BYTE;
3920
#endif
3921
0
            return NC_ERANGE;
3922
0
        }
3923
0
  *ip = (schar)xx;
3924
0
  return NC_NOERR;
3925
0
}
3926
3927
static int
3928
ncx_get_double_short(const void *xp, short *ip)
3929
0
{
3930
0
  ix_double xx = 0;
3931
0
  get_ix_double(xp, &xx);
3932
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3933
#ifdef ERANGE_FILL
3934
            *ip = NC_FILL_SHORT;
3935
#endif
3936
0
            return NC_ERANGE;
3937
0
        }
3938
0
  *ip = (short)xx;
3939
0
  return NC_NOERR;
3940
0
}
3941
3942
static int
3943
ncx_get_double_int(const void *xp, int *ip)
3944
0
{
3945
0
  ix_double xx = 0;
3946
0
  get_ix_double(xp, &xx);
3947
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3948
#ifdef ERANGE_FILL
3949
            *ip = NC_FILL_INT;
3950
#endif
3951
0
            return NC_ERANGE;
3952
0
        }
3953
0
  *ip = (int)xx;
3954
0
  return NC_NOERR;
3955
0
}
3956
3957
static int
3958
ncx_get_double_long(const void *xp, long *ip)
3959
0
{
3960
0
  ix_double xx = 0;
3961
0
  get_ix_double(xp, &xx);
3962
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3963
#ifdef ERANGE_FILL
3964
            *ip = NC_FILL_INT;
3965
#endif
3966
0
            return NC_ERANGE;
3967
0
        }
3968
0
  *ip = (long)xx;
3969
0
  return NC_NOERR;
3970
0
}
3971
3972
static int
3973
ncx_get_double_longlong(const void *xp, longlong *ip)
3974
0
{
3975
0
  ix_double xx = 0;
3976
0
  get_ix_double(xp, &xx);
3977
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3978
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3979
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3980
#ifdef ERANGE_FILL
3981
            *ip = NC_FILL_INT64;
3982
#endif
3983
0
            return NC_ERANGE;
3984
0
        }
3985
0
  else *ip = (longlong)xx;
3986
0
  return NC_NOERR;
3987
0
}
3988
3989
static int
3990
ncx_get_double_uchar(const void *xp, uchar *ip)
3991
0
{
3992
0
  ix_double xx = 0;
3993
0
  get_ix_double(xp, &xx);
3994
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3995
#ifdef ERANGE_FILL
3996
            *ip = NC_FILL_UBYTE;
3997
#endif
3998
0
            return NC_ERANGE;
3999
0
        }
4000
0
  *ip = (uchar)xx;
4001
0
  return NC_NOERR;
4002
0
}
4003
4004
static int
4005
ncx_get_double_ushort(const void *xp, ushort *ip)
4006
0
{
4007
0
  ix_double xx = 0;
4008
0
  get_ix_double(xp, &xx);
4009
0
  if (xx > (double)USHORT_MAX || xx < 0) {
4010
#ifdef ERANGE_FILL
4011
            *ip = NC_FILL_USHORT;
4012
#endif
4013
0
            return NC_ERANGE;
4014
0
        }
4015
0
  *ip = (ushort)xx;
4016
0
  return NC_NOERR;
4017
0
}
4018
4019
static int
4020
ncx_get_double_uint(const void *xp, uint *ip)
4021
0
{
4022
0
  ix_double xx = 0;
4023
0
  get_ix_double(xp, &xx);
4024
0
  if (xx > (double)UINT_MAX || xx < 0) {
4025
#ifdef ERANGE_FILL
4026
            *ip = NC_FILL_UINT;
4027
#endif
4028
0
            return NC_ERANGE;
4029
0
        }
4030
0
  *ip = (uint)xx;
4031
0
  return NC_NOERR;
4032
0
}
4033
4034
static int
4035
ncx_get_double_ulonglong(const void *xp, ulonglong *ip)
4036
0
{
4037
0
  ix_double xx = 0;
4038
0
  get_ix_double(xp, &xx);
4039
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
4040
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
4041
#ifdef ERANGE_FILL
4042
            *ip = NC_FILL_UINT64;
4043
#endif
4044
0
            return NC_ERANGE;
4045
0
        }
4046
0
  else *ip = (ulonglong)xx;
4047
0
  return NC_NOERR;
4048
0
}
4049
4050
4051
static int
4052
ncx_get_double_float(const void *xp, float *ip)
4053
0
{
4054
0
    double xx = 0.0;
4055
0
    get_ix_double(xp, &xx);
4056
0
    if (xx > FLT_MAX) {
4057
#ifdef ERANGE_FILL
4058
        *ip = NC_FILL_FLOAT;
4059
#else
4060
0
        *ip = FLT_MAX;
4061
0
#endif
4062
0
        return NC_ERANGE;
4063
0
    }
4064
0
    if (xx < (-FLT_MAX)) {
4065
#ifdef ERANGE_FILL
4066
        *ip = NC_FILL_FLOAT;
4067
#else
4068
0
        *ip = (-FLT_MAX);
4069
0
#endif
4070
0
        return NC_ERANGE;
4071
0
    }
4072
0
    *ip = (float) xx;
4073
0
    return NC_NOERR;
4074
0
}
4075
4076
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4077
static int
4078
ncx_get_double_double(const void *xp, double *ip, void *fillp)
4079
{
4080
  /* TODO */
4081
  get_ix_double(xp, ip);
4082
  return NC_NOERR;
4083
}
4084
#endif
4085
4086
static int
4087
ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
4088
0
{
4089
0
    int err=NC_NOERR;
4090
0
    ix_double xx = NC_FILL_DOUBLE;
4091
4092
    
4093
0
        xx = (ix_double)*ip;
4094
4095
0
    put_ix_double(xp, &xx);
4096
0
    return err;
4097
0
}
4098
4099
static int
4100
ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
4101
0
{
4102
0
    int err=NC_NOERR;
4103
0
    ix_double xx = NC_FILL_DOUBLE;
4104
4105
    
4106
0
        xx = (ix_double)*ip;
4107
4108
0
    put_ix_double(xp, &xx);
4109
0
    return err;
4110
0
}
4111
4112
static int
4113
ncx_put_double_short(void *xp, const short *ip, void *fillp)
4114
0
{
4115
0
    int err=NC_NOERR;
4116
0
    ix_double xx = NC_FILL_DOUBLE;
4117
4118
    
4119
0
        xx = (ix_double)*ip;
4120
4121
0
    put_ix_double(xp, &xx);
4122
0
    return err;
4123
0
}
4124
4125
static int
4126
ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
4127
0
{
4128
0
    int err=NC_NOERR;
4129
0
    ix_double xx = NC_FILL_DOUBLE;
4130
4131
    
4132
0
        xx = (ix_double)*ip;
4133
4134
0
    put_ix_double(xp, &xx);
4135
0
    return err;
4136
0
}
4137
4138
static int
4139
ncx_put_double_int(void *xp, const int *ip, void *fillp)
4140
0
{
4141
0
    int err=NC_NOERR;
4142
0
    ix_double xx = NC_FILL_DOUBLE;
4143
4144
    
4145
0
        xx = (ix_double)*ip;
4146
4147
0
    put_ix_double(xp, &xx);
4148
0
    return err;
4149
0
}
4150
4151
static int
4152
ncx_put_double_long(void *xp, const long *ip, void *fillp)
4153
0
{
4154
0
    int err=NC_NOERR;
4155
0
    ix_double xx = NC_FILL_DOUBLE;
4156
4157
    
4158
0
        xx = (ix_double)*ip;
4159
4160
0
    put_ix_double(xp, &xx);
4161
0
    return err;
4162
0
}
4163
4164
static int
4165
ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
4166
0
{
4167
0
    int err=NC_NOERR;
4168
0
    ix_double xx = NC_FILL_DOUBLE;
4169
4170
    
4171
0
        xx = (ix_double)*ip;
4172
4173
0
    put_ix_double(xp, &xx);
4174
0
    return err;
4175
0
}
4176
4177
static int
4178
ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
4179
0
{
4180
0
    int err=NC_NOERR;
4181
0
    ix_double xx = NC_FILL_DOUBLE;
4182
4183
    
4184
0
        xx = (ix_double)*ip;
4185
4186
0
    put_ix_double(xp, &xx);
4187
0
    return err;
4188
0
}
4189
4190
static int
4191
ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4192
0
{
4193
0
    int err=NC_NOERR;
4194
0
    ix_double xx = NC_FILL_DOUBLE;
4195
4196
    
4197
0
        xx = (ix_double)*ip;
4198
4199
0
    put_ix_double(xp, &xx);
4200
0
    return err;
4201
0
}
4202
4203
4204
static int
4205
ncx_put_double_float(void *xp, const float *ip, void *fillp)
4206
0
{
4207
0
    int err=NC_NOERR;
4208
0
    double xx = NC_FILL_DOUBLE;
4209
0
#if 1 /* TODO: figure this out (if condition below will never be true)*/
4210
0
    if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
4211
        
4212
#ifdef ERANGE_FILL
4213
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4214
#endif
4215
0
        err = NC_ERANGE;
4216
0
    }
4217
#ifdef ERANGE_FILL
4218
    else
4219
#endif
4220
0
#endif
4221
0
        xx = (double) *ip;
4222
4223
0
    put_ix_double(xp, &xx);
4224
0
    return err;
4225
0
}
4226
4227
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4228
static int
4229
ncx_put_double_double(void *xp, const double *ip, void *fillp)
4230
{
4231
    int err=NC_NOERR;
4232
    double *_ip = ip;
4233
#ifdef NO_IEEE_FLOAT
4234
#ifdef ERANGE_FILL
4235
    double tmp=NC_FILL_DOUBLE;
4236
#endif
4237
    if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
4238
        
4239
#ifdef ERANGE_FILL
4240
            if (fillp != NULL) memcpy(&tmp, fillp, 8);
4241
#endif
4242
#ifdef ERANGE_FILL
4243
        _ip = &tmp;
4244
#endif
4245
        err = NC_ERANGE;
4246
    }
4247
#endif
4248
    put_ix_double(xp, _ip);
4249
    return err;
4250
}
4251
#endif
4252
4253
4254
/* external NC_INT64 --------------------------------------------------------*/
4255
4256
#if SHORT_MAX == X_INT64_MAX
4257
typedef short ix_int64;
4258
#define SIZEOF_IX_INT64 SIZEOF_SHORT
4259
#define IX_INT64_MAX SHORT_MAX
4260
#elif LONG_LONG_MAX  >= X_INT64_MAX
4261
typedef longlong ix_int64;
4262
#define SIZEOF_IX_INT64 SIZEOF_LONGLONG
4263
0
#define IX_INT64_MAX LONG_LONG_MAX
4264
#elif LONG_MAX  >= X_INT64_MAX
4265
typedef long ix_int64;
4266
#define SIZEOF_IX_INT64 SIZEOF_LONG
4267
#define IX_INT64_MAX LONG_MAX
4268
#else
4269
#error "ix_int64 implementation"
4270
#endif
4271
4272
4273
static void
4274
get_ix_int64(const void *xp, ix_int64 *ip)
4275
0
{
4276
0
    const uchar *cp = (const uchar *) xp;
4277
4278
0
    *ip  = ((ix_int64)(*cp++) << 56);
4279
0
    *ip |= ((ix_int64)(*cp++) << 48);
4280
0
    *ip |= ((ix_int64)(*cp++) << 40);
4281
0
    *ip |= ((ix_int64)(*cp++) << 32);
4282
0
    *ip |= ((ix_int64)(*cp++) << 24);
4283
0
    *ip |= ((ix_int64)(*cp++) << 16);
4284
0
    *ip |= ((ix_int64)(*cp++) <<  8);
4285
0
    *ip |=  (ix_int64)*cp;
4286
0
}
4287
4288
static void
4289
put_ix_int64(void *xp, const ix_int64 *ip)
4290
0
{
4291
0
    uchar *cp = (uchar *) xp;
4292
4293
0
    *cp++ = (uchar)((*ip) >> 56);
4294
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48);
4295
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40);
4296
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32);
4297
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24);
4298
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16);
4299
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >>  8);
4300
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffLL);
4301
0
}
4302
4303
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4304
static int
4305
ncx_get_longlong_longlong(const void *xp, longlong *ip)
4306
{
4307
    int err=NC_NOERR;
4308
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4309
    get_ix_int64(xp, (ix_int64 *)ip);
4310
#else
4311
    ix_int64 xx = 0;
4312
    get_ix_int64(xp, &xx);
4313
4314
#if IX_INT64_MAX > LONGLONG_MAX
4315
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
4316
#ifdef ERANGE_FILL
4317
        *ip = NC_FILL_INT64;
4318
        return NC_ERANGE;
4319
#else
4320
        err = NC_ERANGE;
4321
#endif
4322
    }
4323
#endif
4324
4325
4326
    *ip = (longlong) xx;
4327
#endif
4328
    return err;
4329
}
4330
4331
#endif
4332
static int
4333
ncx_get_longlong_schar(const void *xp, schar *ip)
4334
0
{
4335
0
    int err=NC_NOERR;
4336
0
    ix_int64 xx = 0;
4337
0
    get_ix_int64(xp, &xx);
4338
4339
0
#if IX_INT64_MAX > SCHAR_MAX
4340
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
4341
#ifdef ERANGE_FILL
4342
        *ip = NC_FILL_BYTE;
4343
        return NC_ERANGE;
4344
#else
4345
0
        err = NC_ERANGE;
4346
0
#endif
4347
0
    }
4348
0
#endif
4349
4350
4351
0
    *ip = (schar) xx;
4352
0
    return err;
4353
0
}
4354
4355
static int
4356
ncx_get_longlong_short(const void *xp, short *ip)
4357
0
{
4358
0
    int err=NC_NOERR;
4359
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4360
    get_ix_int64(xp, (ix_int64 *)ip);
4361
#else
4362
0
    ix_int64 xx = 0;
4363
0
    get_ix_int64(xp, &xx);
4364
4365
0
#if IX_INT64_MAX > SHORT_MAX
4366
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
4367
#ifdef ERANGE_FILL
4368
        *ip = NC_FILL_SHORT;
4369
        return NC_ERANGE;
4370
#else
4371
0
        err = NC_ERANGE;
4372
0
#endif
4373
0
    }
4374
0
#endif
4375
4376
4377
0
    *ip = (short) xx;
4378
0
#endif
4379
0
    return err;
4380
0
}
4381
4382
static int
4383
ncx_get_longlong_int(const void *xp, int *ip)
4384
0
{
4385
0
    int err=NC_NOERR;
4386
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4387
    get_ix_int64(xp, (ix_int64 *)ip);
4388
#else
4389
0
    ix_int64 xx = 0;
4390
0
    get_ix_int64(xp, &xx);
4391
4392
0
#if IX_INT64_MAX > INT_MAX
4393
0
    if (xx > INT_MAX || xx < INT_MIN) {
4394
#ifdef ERANGE_FILL
4395
        *ip = NC_FILL_INT;
4396
        return NC_ERANGE;
4397
#else
4398
0
        err = NC_ERANGE;
4399
0
#endif
4400
0
    }
4401
0
#endif
4402
4403
4404
0
    *ip = (int) xx;
4405
0
#endif
4406
0
    return err;
4407
0
}
4408
4409
static int
4410
ncx_get_longlong_long(const void *xp, long *ip)
4411
0
{
4412
0
    int err=NC_NOERR;
4413
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4414
0
    get_ix_int64(xp, (ix_int64 *)ip);
4415
#else
4416
    ix_int64 xx = 0;
4417
    get_ix_int64(xp, &xx);
4418
4419
#if IX_INT64_MAX > LONG_MAX
4420
    if (xx > LONG_MAX || xx < LONG_MIN) {
4421
#ifdef ERANGE_FILL
4422
        *ip = NC_FILL_INT;
4423
        return NC_ERANGE;
4424
#else
4425
        err = NC_ERANGE;
4426
#endif
4427
    }
4428
#endif
4429
4430
4431
    *ip = (long) xx;
4432
#endif
4433
0
    return err;
4434
0
}
4435
4436
static int
4437
ncx_get_longlong_ushort(const void *xp, ushort *ip)
4438
0
{
4439
0
    int err=NC_NOERR;
4440
0
    ix_int64 xx = 0;
4441
0
    get_ix_int64(xp, &xx);
4442
4443
0
#if IX_INT64_MAX > USHORT_MAX
4444
0
    if (xx > USHORT_MAX) {
4445
#ifdef ERANGE_FILL
4446
        *ip = NC_FILL_USHORT;
4447
        return NC_ERANGE;
4448
#else
4449
0
        err = NC_ERANGE;
4450
0
#endif
4451
0
    }
4452
0
#endif
4453
4454
0
    if (xx < 0) {
4455
#ifdef ERANGE_FILL
4456
        *ip = NC_FILL_USHORT;
4457
        return NC_ERANGE;
4458
#else
4459
0
        err = NC_ERANGE; /* because ip is unsigned */
4460
0
#endif
4461
0
    }
4462
0
    *ip = (ushort) xx;
4463
0
    return err;
4464
0
}
4465
4466
static int
4467
ncx_get_longlong_uchar(const void *xp, uchar *ip)
4468
0
{
4469
0
    int err=NC_NOERR;
4470
0
    ix_int64 xx = 0;
4471
0
    get_ix_int64(xp, &xx);
4472
4473
0
#if IX_INT64_MAX > UCHAR_MAX
4474
0
    if (xx > UCHAR_MAX) {
4475
#ifdef ERANGE_FILL
4476
        *ip = NC_FILL_UBYTE;
4477
        return NC_ERANGE;
4478
#else
4479
0
        err = NC_ERANGE;
4480
0
#endif
4481
0
    }
4482
0
#endif
4483
4484
0
    if (xx < 0) {
4485
#ifdef ERANGE_FILL
4486
        *ip = NC_FILL_UBYTE;
4487
        return NC_ERANGE;
4488
#else
4489
0
        err = NC_ERANGE; /* because ip is unsigned */
4490
0
#endif
4491
0
    }
4492
0
    *ip = (uchar) xx;
4493
0
    return err;
4494
0
}
4495
4496
static int
4497
ncx_get_longlong_uint(const void *xp, uint *ip)
4498
0
{
4499
0
    int err=NC_NOERR;
4500
0
    ix_int64 xx = 0;
4501
0
    get_ix_int64(xp, &xx);
4502
4503
0
#if IX_INT64_MAX > UINT_MAX
4504
0
    if (xx > UINT_MAX) {
4505
#ifdef ERANGE_FILL
4506
        *ip = NC_FILL_UINT;
4507
        return NC_ERANGE;
4508
#else
4509
0
        err = NC_ERANGE;
4510
0
#endif
4511
0
    }
4512
0
#endif
4513
4514
0
    if (xx < 0) {
4515
#ifdef ERANGE_FILL
4516
        *ip = NC_FILL_UINT;
4517
        return NC_ERANGE;
4518
#else
4519
0
        err = NC_ERANGE; /* because ip is unsigned */
4520
0
#endif
4521
0
    }
4522
0
    *ip = (uint) xx;
4523
0
    return err;
4524
0
}
4525
4526
static int
4527
ncx_get_longlong_ulonglong(const void *xp, ulonglong *ip)
4528
0
{
4529
0
    int err=NC_NOERR;
4530
0
    ix_int64 xx = 0;
4531
0
    get_ix_int64(xp, &xx);
4532
4533
#if IX_INT64_MAX > ULONGLONG_MAX
4534
    if (xx > ULONGLONG_MAX) {
4535
#ifdef ERANGE_FILL
4536
        *ip = NC_FILL_UINT64;
4537
        return NC_ERANGE;
4538
#else
4539
        err = NC_ERANGE;
4540
#endif
4541
    }
4542
#endif
4543
4544
0
    if (xx < 0) {
4545
#ifdef ERANGE_FILL
4546
        *ip = NC_FILL_UINT64;
4547
        return NC_ERANGE;
4548
#else
4549
0
        err = NC_ERANGE; /* because ip is unsigned */
4550
0
#endif
4551
0
    }
4552
0
    *ip = (ulonglong) xx;
4553
0
    return err;
4554
0
}
4555
4556
static int
4557
ncx_get_longlong_float(const void *xp, float *ip)
4558
0
{
4559
0
  ix_int64 xx = 0;
4560
0
  get_ix_int64(xp, &xx);
4561
0
  *ip = (float)xx;
4562
0
  return NC_NOERR;
4563
0
}
4564
4565
static int
4566
ncx_get_longlong_double(const void *xp, double *ip)
4567
0
{
4568
0
  ix_int64 xx = 0;
4569
0
  get_ix_int64(xp, &xx);
4570
0
  *ip = (double)xx;
4571
0
  return NC_NOERR;
4572
0
}
4573
4574
4575
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4576
static int
4577
ncx_put_longlong_longlong(void *xp, const longlong *ip, void *fillp)
4578
{
4579
    int err=NC_NOERR;
4580
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4581
    put_ix_int64(xp, (const ix_int64 *)ip);
4582
#else
4583
    ix_int64 xx = NC_FILL_INT64;
4584
4585
#if IX_INT64_MAX < LONGLONG_MAX
4586
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4587
        
4588
#ifdef ERANGE_FILL
4589
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4590
#endif
4591
        err = NC_ERANGE;
4592
    }
4593
#ifdef ERANGE_FILL
4594
    else
4595
#endif
4596
#endif
4597
        xx = (ix_int64)*ip;
4598
4599
    put_ix_int64(xp, &xx);
4600
#endif
4601
    return err;
4602
}
4603
4604
#endif
4605
static int
4606
ncx_put_longlong_schar(void *xp, const schar *ip, void *fillp)
4607
0
{
4608
0
    int err=NC_NOERR;
4609
0
    ix_int64 xx = NC_FILL_INT64;
4610
4611
#if IX_INT64_MAX < SCHAR_MAX
4612
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4613
        
4614
#ifdef ERANGE_FILL
4615
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4616
#endif
4617
        err = NC_ERANGE;
4618
    }
4619
#ifdef ERANGE_FILL
4620
    else
4621
#endif
4622
#endif
4623
0
        xx = (ix_int64)*ip;
4624
4625
0
    put_ix_int64(xp, &xx);
4626
0
    return err;
4627
0
}
4628
4629
static int
4630
ncx_put_longlong_short(void *xp, const short *ip, void *fillp)
4631
0
{
4632
0
    int err=NC_NOERR;
4633
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4634
    put_ix_int64(xp, (const ix_int64 *)ip);
4635
#else
4636
0
    ix_int64 xx = NC_FILL_INT64;
4637
4638
#if IX_INT64_MAX < SHORT_MAX
4639
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4640
        
4641
#ifdef ERANGE_FILL
4642
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4643
#endif
4644
        err = NC_ERANGE;
4645
    }
4646
#ifdef ERANGE_FILL
4647
    else
4648
#endif
4649
#endif
4650
0
        xx = (ix_int64)*ip;
4651
4652
0
    put_ix_int64(xp, &xx);
4653
0
#endif
4654
0
    return err;
4655
0
}
4656
4657
static int
4658
ncx_put_longlong_int(void *xp, const int *ip, void *fillp)
4659
0
{
4660
0
    int err=NC_NOERR;
4661
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4662
    put_ix_int64(xp, (const ix_int64 *)ip);
4663
#else
4664
0
    ix_int64 xx = NC_FILL_INT64;
4665
4666
#if IX_INT64_MAX < INT_MAX
4667
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4668
        
4669
#ifdef ERANGE_FILL
4670
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4671
#endif
4672
        err = NC_ERANGE;
4673
    }
4674
#ifdef ERANGE_FILL
4675
    else
4676
#endif
4677
#endif
4678
0
        xx = (ix_int64)*ip;
4679
4680
0
    put_ix_int64(xp, &xx);
4681
0
#endif
4682
0
    return err;
4683
0
}
4684
4685
static int
4686
ncx_put_longlong_long(void *xp, const long *ip, void *fillp)
4687
0
{
4688
0
    int err=NC_NOERR;
4689
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4690
0
    put_ix_int64(xp, (const ix_int64 *)ip);
4691
#else
4692
    ix_int64 xx = NC_FILL_INT64;
4693
4694
#if IX_INT64_MAX < LONG_MAX
4695
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4696
        
4697
#ifdef ERANGE_FILL
4698
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4699
#endif
4700
        err = NC_ERANGE;
4701
    }
4702
#ifdef ERANGE_FILL
4703
    else
4704
#endif
4705
#endif
4706
        xx = (ix_int64)*ip;
4707
4708
    put_ix_int64(xp, &xx);
4709
#endif
4710
0
    return err;
4711
0
}
4712
4713
static int
4714
ncx_put_longlong_ushort(void *xp, const ushort *ip, void *fillp)
4715
0
{
4716
0
    int err=NC_NOERR;
4717
0
    ix_int64 xx = NC_FILL_INT64;
4718
4719
#if IX_INT64_MAX < USHORT_MAX
4720
    if (*ip > IX_INT64_MAX) {
4721
        
4722
#ifdef ERANGE_FILL
4723
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4724
#endif
4725
        err = NC_ERANGE;
4726
    }
4727
#ifdef ERANGE_FILL
4728
    else
4729
#endif
4730
#endif
4731
0
        xx = (ix_int64)*ip;
4732
4733
0
    put_ix_int64(xp, &xx);
4734
0
    return err;
4735
0
}
4736
4737
static int
4738
ncx_put_longlong_uchar(void *xp, const uchar *ip, void *fillp)
4739
0
{
4740
0
    int err=NC_NOERR;
4741
0
    ix_int64 xx = NC_FILL_INT64;
4742
4743
#if IX_INT64_MAX < UCHAR_MAX
4744
    if (*ip > IX_INT64_MAX) {
4745
        
4746
#ifdef ERANGE_FILL
4747
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4748
#endif
4749
        err = NC_ERANGE;
4750
    }
4751
#ifdef ERANGE_FILL
4752
    else
4753
#endif
4754
#endif
4755
0
        xx = (ix_int64)*ip;
4756
4757
0
    put_ix_int64(xp, &xx);
4758
0
    return err;
4759
0
}
4760
4761
static int
4762
ncx_put_longlong_uint(void *xp, const uint *ip, void *fillp)
4763
0
{
4764
0
    int err=NC_NOERR;
4765
0
    ix_int64 xx = NC_FILL_INT64;
4766
4767
#if IX_INT64_MAX < UINT_MAX
4768
    if (*ip > IX_INT64_MAX) {
4769
        
4770
#ifdef ERANGE_FILL
4771
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4772
#endif
4773
        err = NC_ERANGE;
4774
    }
4775
#ifdef ERANGE_FILL
4776
    else
4777
#endif
4778
#endif
4779
0
        xx = (ix_int64)*ip;
4780
4781
0
    put_ix_int64(xp, &xx);
4782
0
    return err;
4783
0
}
4784
4785
static int
4786
ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4787
0
{
4788
0
    int err=NC_NOERR;
4789
0
    ix_int64 xx = NC_FILL_INT64;
4790
4791
0
#if IX_INT64_MAX < ULONGLONG_MAX
4792
0
    if (*ip > IX_INT64_MAX) {
4793
        
4794
#ifdef ERANGE_FILL
4795
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4796
#endif
4797
0
        err = NC_ERANGE;
4798
0
    }
4799
#ifdef ERANGE_FILL
4800
    else
4801
#endif
4802
0
#endif
4803
0
        xx = (ix_int64)*ip;
4804
4805
0
    put_ix_int64(xp, &xx);
4806
0
    return err;
4807
0
}
4808
4809
static int
4810
ncx_put_longlong_float(void *xp, const float *ip, void *fillp)
4811
0
{
4812
0
    int err=NC_NOERR;
4813
0
    ix_int64 xx = NC_FILL_INT64;
4814
4815
0
    if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
4816
        
4817
#ifdef ERANGE_FILL
4818
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4819
#endif
4820
0
        err = NC_ERANGE;
4821
0
    }
4822
#ifdef ERANGE_FILL
4823
    else
4824
#endif
4825
0
        xx = (ix_int64)*ip;
4826
4827
0
    put_ix_int64(xp, &xx);
4828
0
    return err;
4829
0
}
4830
4831
static int
4832
ncx_put_longlong_double(void *xp, const double *ip, void *fillp)
4833
0
{
4834
0
    int err=NC_NOERR;
4835
0
    ix_int64 xx = NC_FILL_INT64;
4836
4837
0
    if (*ip > X_INT64_MAX || *ip < X_INT64_MIN) {
4838
        
4839
#ifdef ERANGE_FILL
4840
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4841
#endif
4842
0
        err = NC_ERANGE;
4843
0
    }
4844
#ifdef ERANGE_FILL
4845
    else
4846
#endif
4847
0
        xx = (ix_int64)*ip;
4848
4849
0
    put_ix_int64(xp, &xx);
4850
0
    return err;
4851
0
}
4852
4853
4854
4855
/* external NC_UINT64 -------------------------------------------------------*/
4856
4857
#if USHORT_MAX == X_UINT64_MAX
4858
typedef ushort ix_uint64;
4859
#define SIZEOF_IX_UINT64 SIZEOF_USHORT
4860
#define IX_UINT64_MAX USHORT_MAX
4861
#elif ULONG_LONG_MAX  >= X_UINT64_MAX
4862
typedef ulonglong ix_uint64;
4863
#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
4864
#define IX_UINT64_MAX ULONG_LONG_MAX
4865
#elif ULONG_MAX  >= X_UINT64_MAX
4866
typedef ulong ix_uint64;
4867
#define SIZEOF_IX_UINT64 SIZEOF_ULONG
4868
#define IX_UINT64_MAX ULONG_MAX
4869
#else
4870
#error "ix_uint64 implementation"
4871
#endif
4872
4873
4874
static void
4875
get_ix_uint64(const void *xp, ix_uint64 *ip)
4876
0
{
4877
0
    const uchar *cp = (const uchar *) xp;
4878
4879
0
    *ip  = ((ix_uint64)(*cp++) << 56);
4880
0
    *ip |= ((ix_uint64)(*cp++) << 48);
4881
0
    *ip |= ((ix_uint64)(*cp++) << 40);
4882
0
    *ip |= ((ix_uint64)(*cp++) << 32);
4883
0
    *ip |= ((ix_uint64)(*cp++) << 24);
4884
0
    *ip |= ((ix_uint64)(*cp++) << 16);
4885
0
    *ip |= ((ix_uint64)(*cp++) <<  8);
4886
0
    *ip |=  (ix_uint64)*cp;
4887
0
}
4888
4889
static void
4890
put_ix_uint64(void *xp, const ix_uint64 *ip)
4891
0
{
4892
0
    uchar *cp = (uchar *) xp;
4893
4894
0
    *cp++ = (uchar)((*ip) >> 56);
4895
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48);
4896
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40);
4897
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32);
4898
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24);
4899
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16);
4900
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >>  8);
4901
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffULL);
4902
0
}
4903
4904
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4905
static int
4906
ncx_get_ulonglong_ulonglong(const void *xp, ulonglong *ip)
4907
{
4908
    int err=NC_NOERR;
4909
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4910
    get_ix_uint64(xp, (ix_uint64 *)ip);
4911
#else
4912
    ix_uint64 xx = 0;
4913
    get_ix_uint64(xp, &xx);
4914
4915
#if IX_UINT64_MAX > ULONGLONG_MAX
4916
    if (xx > ULONGLONG_MAX) {
4917
#ifdef ERANGE_FILL
4918
        *ip = NC_FILL_UINT64;
4919
        return NC_ERANGE;
4920
#else
4921
        err = NC_ERANGE;
4922
#endif
4923
    }
4924
#endif
4925
4926
4927
    *ip = (ulonglong) xx;
4928
#endif
4929
    return err;
4930
}
4931
4932
#endif
4933
static int
4934
ncx_get_ulonglong_schar(const void *xp, schar *ip)
4935
0
{
4936
0
    int err=NC_NOERR;
4937
0
    ix_uint64 xx = 0;
4938
0
    get_ix_uint64(xp, &xx);
4939
4940
0
#if IX_UINT64_MAX > SCHAR_MAX
4941
0
    if (xx > SCHAR_MAX) {
4942
#ifdef ERANGE_FILL
4943
        *ip = NC_FILL_BYTE;
4944
        return NC_ERANGE;
4945
#else
4946
0
        err = NC_ERANGE;
4947
0
#endif
4948
0
    }
4949
0
#endif
4950
4951
4952
0
    *ip = (schar) xx;
4953
0
    return err;
4954
0
}
4955
4956
static int
4957
ncx_get_ulonglong_short(const void *xp, short *ip)
4958
0
{
4959
0
    int err=NC_NOERR;
4960
0
    ix_uint64 xx = 0;
4961
0
    get_ix_uint64(xp, &xx);
4962
4963
0
#if IX_UINT64_MAX > SHORT_MAX
4964
0
    if (xx > SHORT_MAX) {
4965
#ifdef ERANGE_FILL
4966
        *ip = NC_FILL_SHORT;
4967
        return NC_ERANGE;
4968
#else
4969
0
        err = NC_ERANGE;
4970
0
#endif
4971
0
    }
4972
0
#endif
4973
4974
4975
0
    *ip = (short) xx;
4976
0
    return err;
4977
0
}
4978
4979
static int
4980
ncx_get_ulonglong_int(const void *xp, int *ip)
4981
0
{
4982
0
    int err=NC_NOERR;
4983
0
    ix_uint64 xx = 0;
4984
0
    get_ix_uint64(xp, &xx);
4985
4986
0
#if IX_UINT64_MAX > INT_MAX
4987
0
    if (xx > INT_MAX) {
4988
#ifdef ERANGE_FILL
4989
        *ip = NC_FILL_INT;
4990
        return NC_ERANGE;
4991
#else
4992
0
        err = NC_ERANGE;
4993
0
#endif
4994
0
    }
4995
0
#endif
4996
4997
4998
0
    *ip = (int) xx;
4999
0
    return err;
5000
0
}
5001
5002
static int
5003
ncx_get_ulonglong_long(const void *xp, long *ip)
5004
0
{
5005
0
    int err=NC_NOERR;
5006
0
    ix_uint64 xx = 0;
5007
0
    get_ix_uint64(xp, &xx);
5008
5009
0
#if IX_UINT64_MAX > LONG_MAX
5010
0
    if (xx > LONG_MAX) {
5011
#ifdef ERANGE_FILL
5012
        *ip = NC_FILL_INT;
5013
        return NC_ERANGE;
5014
#else
5015
0
        err = NC_ERANGE;
5016
0
#endif
5017
0
    }
5018
0
#endif
5019
5020
5021
0
    *ip = (long) xx;
5022
0
    return err;
5023
0
}
5024
5025
static int
5026
ncx_get_ulonglong_longlong(const void *xp, longlong *ip)
5027
0
{
5028
0
    int err=NC_NOERR;
5029
0
    ix_uint64 xx = 0;
5030
0
    get_ix_uint64(xp, &xx);
5031
5032
0
#if IX_UINT64_MAX > LONGLONG_MAX
5033
0
    if (xx > LONGLONG_MAX) {
5034
#ifdef ERANGE_FILL
5035
        *ip = NC_FILL_INT64;
5036
        return NC_ERANGE;
5037
#else
5038
0
        err = NC_ERANGE;
5039
0
#endif
5040
0
    }
5041
0
#endif
5042
5043
5044
0
    *ip = (longlong) xx;
5045
0
    return err;
5046
0
}
5047
5048
static int
5049
ncx_get_ulonglong_ushort(const void *xp, ushort *ip)
5050
0
{
5051
0
    int err=NC_NOERR;
5052
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5053
    get_ix_uint64(xp, (ix_uint64 *)ip);
5054
#else
5055
0
    ix_uint64 xx = 0;
5056
0
    get_ix_uint64(xp, &xx);
5057
5058
0
#if IX_UINT64_MAX > USHORT_MAX
5059
0
    if (xx > USHORT_MAX) {
5060
#ifdef ERANGE_FILL
5061
        *ip = NC_FILL_USHORT;
5062
        return NC_ERANGE;
5063
#else
5064
0
        err = NC_ERANGE;
5065
0
#endif
5066
0
    }
5067
0
#endif
5068
5069
5070
0
    *ip = (ushort) xx;
5071
0
#endif
5072
0
    return err;
5073
0
}
5074
5075
static int
5076
ncx_get_ulonglong_uchar(const void *xp, uchar *ip)
5077
0
{
5078
0
    int err=NC_NOERR;
5079
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5080
    get_ix_uint64(xp, (ix_uint64 *)ip);
5081
#else
5082
0
    ix_uint64 xx = 0;
5083
0
    get_ix_uint64(xp, &xx);
5084
5085
0
#if IX_UINT64_MAX > UCHAR_MAX
5086
0
    if (xx > UCHAR_MAX) {
5087
#ifdef ERANGE_FILL
5088
        *ip = NC_FILL_UBYTE;
5089
        return NC_ERANGE;
5090
#else
5091
0
        err = NC_ERANGE;
5092
0
#endif
5093
0
    }
5094
0
#endif
5095
5096
5097
0
    *ip = (uchar) xx;
5098
0
#endif
5099
0
    return err;
5100
0
}
5101
5102
static int
5103
ncx_get_ulonglong_uint(const void *xp, uint *ip)
5104
0
{
5105
0
    int err=NC_NOERR;
5106
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5107
    get_ix_uint64(xp, (ix_uint64 *)ip);
5108
#else
5109
0
    ix_uint64 xx = 0;
5110
0
    get_ix_uint64(xp, &xx);
5111
5112
0
#if IX_UINT64_MAX > UINT_MAX
5113
0
    if (xx > UINT_MAX) {
5114
#ifdef ERANGE_FILL
5115
        *ip = NC_FILL_UINT;
5116
        return NC_ERANGE;
5117
#else
5118
0
        err = NC_ERANGE;
5119
0
#endif
5120
0
    }
5121
0
#endif
5122
5123
5124
0
    *ip = (uint) xx;
5125
0
#endif
5126
0
    return err;
5127
0
}
5128
5129
static int
5130
ncx_get_ulonglong_float(const void *xp, float *ip)
5131
0
{
5132
0
  ix_uint64 xx = 0;
5133
0
  get_ix_uint64(xp, &xx);
5134
0
  *ip = (float)xx;
5135
0
  return NC_NOERR;
5136
0
}
5137
5138
static int
5139
ncx_get_ulonglong_double(const void *xp, double *ip)
5140
0
{
5141
0
  ix_uint64 xx = 0;
5142
0
  get_ix_uint64(xp, &xx);
5143
0
  *ip = (double)xx;
5144
0
  return NC_NOERR;
5145
0
}
5146
5147
5148
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
5149
static int
5150
ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
5151
{
5152
    int err=NC_NOERR;
5153
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
5154
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5155
#else
5156
    ix_uint64 xx = NC_FILL_UINT64;
5157
5158
#if IX_UINT64_MAX < ULONGLONG_MAX
5159
    if (*ip > IX_UINT64_MAX) {
5160
        
5161
#ifdef ERANGE_FILL
5162
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5163
#endif
5164
        err = NC_ERANGE;
5165
    }
5166
#ifdef ERANGE_FILL
5167
    else
5168
#endif
5169
#endif
5170
        xx = (ix_uint64)*ip;
5171
5172
    put_ix_uint64(xp, &xx);
5173
#endif
5174
    return err;
5175
}
5176
5177
#endif
5178
static int
5179
ncx_put_ulonglong_schar(void *xp, const schar *ip, void *fillp)
5180
0
{
5181
0
    int err=NC_NOERR;
5182
0
    ix_uint64 xx = NC_FILL_UINT64;
5183
5184
#if IX_UINT64_MAX < SCHAR_MAX
5185
    if (*ip > IX_UINT64_MAX) {
5186
        
5187
#ifdef ERANGE_FILL
5188
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5189
#endif
5190
        err = NC_ERANGE;
5191
    }
5192
#ifdef ERANGE_FILL
5193
    else
5194
#endif
5195
#endif
5196
0
    if (*ip < 0) {
5197
        
5198
#ifdef ERANGE_FILL
5199
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5200
#endif
5201
0
        err = NC_ERANGE; /* because xp is unsigned */
5202
0
    }
5203
#ifdef ERANGE_FILL
5204
    else
5205
#endif
5206
0
        xx = (ix_uint64)*ip;
5207
5208
0
    put_ix_uint64(xp, &xx);
5209
0
    return err;
5210
0
}
5211
5212
static int
5213
ncx_put_ulonglong_short(void *xp, const short *ip, void *fillp)
5214
0
{
5215
0
    int err=NC_NOERR;
5216
0
    ix_uint64 xx = NC_FILL_UINT64;
5217
5218
#if IX_UINT64_MAX < SHORT_MAX
5219
    if (*ip > IX_UINT64_MAX) {
5220
        
5221
#ifdef ERANGE_FILL
5222
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5223
#endif
5224
        err = NC_ERANGE;
5225
    }
5226
#ifdef ERANGE_FILL
5227
    else
5228
#endif
5229
#endif
5230
0
    if (*ip < 0) {
5231
        
5232
#ifdef ERANGE_FILL
5233
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5234
#endif
5235
0
        err = NC_ERANGE; /* because xp is unsigned */
5236
0
    }
5237
#ifdef ERANGE_FILL
5238
    else
5239
#endif
5240
0
        xx = (ix_uint64)*ip;
5241
5242
0
    put_ix_uint64(xp, &xx);
5243
0
    return err;
5244
0
}
5245
5246
static int
5247
ncx_put_ulonglong_int(void *xp, const int *ip, void *fillp)
5248
0
{
5249
0
    int err=NC_NOERR;
5250
0
    ix_uint64 xx = NC_FILL_UINT64;
5251
5252
#if IX_UINT64_MAX < INT_MAX
5253
    if (*ip > IX_UINT64_MAX) {
5254
        
5255
#ifdef ERANGE_FILL
5256
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5257
#endif
5258
        err = NC_ERANGE;
5259
    }
5260
#ifdef ERANGE_FILL
5261
    else
5262
#endif
5263
#endif
5264
0
    if (*ip < 0) {
5265
        
5266
#ifdef ERANGE_FILL
5267
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5268
#endif
5269
0
        err = NC_ERANGE; /* because xp is unsigned */
5270
0
    }
5271
#ifdef ERANGE_FILL
5272
    else
5273
#endif
5274
0
        xx = (ix_uint64)*ip;
5275
5276
0
    put_ix_uint64(xp, &xx);
5277
0
    return err;
5278
0
}
5279
5280
static int
5281
ncx_put_ulonglong_long(void *xp, const long *ip, void *fillp)
5282
0
{
5283
0
    int err=NC_NOERR;
5284
0
    ix_uint64 xx = NC_FILL_UINT64;
5285
5286
#if IX_UINT64_MAX < LONG_MAX
5287
    if (*ip > IX_UINT64_MAX) {
5288
        
5289
#ifdef ERANGE_FILL
5290
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5291
#endif
5292
        err = NC_ERANGE;
5293
    }
5294
#ifdef ERANGE_FILL
5295
    else
5296
#endif
5297
#endif
5298
0
    if (*ip < 0) {
5299
        
5300
#ifdef ERANGE_FILL
5301
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5302
#endif
5303
0
        err = NC_ERANGE; /* because xp is unsigned */
5304
0
    }
5305
#ifdef ERANGE_FILL
5306
    else
5307
#endif
5308
0
        xx = (ix_uint64)*ip;
5309
5310
0
    put_ix_uint64(xp, &xx);
5311
0
    return err;
5312
0
}
5313
5314
static int
5315
ncx_put_ulonglong_longlong(void *xp, const longlong *ip, void *fillp)
5316
0
{
5317
0
    int err=NC_NOERR;
5318
0
    ix_uint64 xx = NC_FILL_UINT64;
5319
5320
#if IX_UINT64_MAX < LONGLONG_MAX
5321
    if (*ip > IX_UINT64_MAX) {
5322
        
5323
#ifdef ERANGE_FILL
5324
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5325
#endif
5326
        err = NC_ERANGE;
5327
    }
5328
#ifdef ERANGE_FILL
5329
    else
5330
#endif
5331
#endif
5332
0
    if (*ip < 0) {
5333
        
5334
#ifdef ERANGE_FILL
5335
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5336
#endif
5337
0
        err = NC_ERANGE; /* because xp is unsigned */
5338
0
    }
5339
#ifdef ERANGE_FILL
5340
    else
5341
#endif
5342
0
        xx = (ix_uint64)*ip;
5343
5344
0
    put_ix_uint64(xp, &xx);
5345
0
    return err;
5346
0
}
5347
5348
static int
5349
ncx_put_ulonglong_uchar(void *xp, const uchar *ip, void *fillp)
5350
0
{
5351
0
    int err=NC_NOERR;
5352
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5353
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5354
#else
5355
0
    ix_uint64 xx = NC_FILL_UINT64;
5356
5357
#if IX_UINT64_MAX < UCHAR_MAX
5358
    if (*ip > IX_UINT64_MAX) {
5359
        
5360
#ifdef ERANGE_FILL
5361
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5362
#endif
5363
        err = NC_ERANGE;
5364
    }
5365
#ifdef ERANGE_FILL
5366
    else
5367
#endif
5368
#endif
5369
0
        xx = (ix_uint64)*ip;
5370
5371
0
    put_ix_uint64(xp, &xx);
5372
0
#endif
5373
0
    return err;
5374
0
}
5375
5376
static int
5377
ncx_put_ulonglong_ushort(void *xp, const ushort *ip, void *fillp)
5378
0
{
5379
0
    int err=NC_NOERR;
5380
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5381
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5382
#else
5383
0
    ix_uint64 xx = NC_FILL_UINT64;
5384
5385
#if IX_UINT64_MAX < USHORT_MAX
5386
    if (*ip > IX_UINT64_MAX) {
5387
        
5388
#ifdef ERANGE_FILL
5389
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5390
#endif
5391
        err = NC_ERANGE;
5392
    }
5393
#ifdef ERANGE_FILL
5394
    else
5395
#endif
5396
#endif
5397
0
        xx = (ix_uint64)*ip;
5398
5399
0
    put_ix_uint64(xp, &xx);
5400
0
#endif
5401
0
    return err;
5402
0
}
5403
5404
static int
5405
ncx_put_ulonglong_uint(void *xp, const uint *ip, void *fillp)
5406
0
{
5407
0
    int err=NC_NOERR;
5408
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5409
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5410
#else
5411
0
    ix_uint64 xx = NC_FILL_UINT64;
5412
5413
#if IX_UINT64_MAX < UINT_MAX
5414
    if (*ip > IX_UINT64_MAX) {
5415
        
5416
#ifdef ERANGE_FILL
5417
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5418
#endif
5419
        err = NC_ERANGE;
5420
    }
5421
#ifdef ERANGE_FILL
5422
    else
5423
#endif
5424
#endif
5425
0
        xx = (ix_uint64)*ip;
5426
5427
0
    put_ix_uint64(xp, &xx);
5428
0
#endif
5429
0
    return err;
5430
0
}
5431
5432
static int
5433
ncx_put_ulonglong_float(void *xp, const float *ip, void *fillp)
5434
0
{
5435
0
    int err=NC_NOERR;
5436
0
    ix_uint64 xx = NC_FILL_UINT64;
5437
5438
0
    if (*ip > (double)X_UINT64_MAX || *ip < 0) {
5439
        
5440
#ifdef ERANGE_FILL
5441
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5442
#endif
5443
0
        err = NC_ERANGE;
5444
0
    }
5445
#ifdef ERANGE_FILL
5446
    else
5447
#endif
5448
0
        xx = (ix_uint64)*ip;
5449
5450
0
    put_ix_uint64(xp, &xx);
5451
0
    return err;
5452
0
}
5453
5454
static int
5455
ncx_put_ulonglong_double(void *xp, const double *ip, void *fillp)
5456
0
{
5457
0
    int err=NC_NOERR;
5458
0
    ix_uint64 xx = NC_FILL_UINT64;
5459
5460
0
    if (*ip > X_UINT64_MAX || *ip < 0) {
5461
        
5462
#ifdef ERANGE_FILL
5463
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5464
#endif
5465
0
        err = NC_ERANGE;
5466
0
    }
5467
#ifdef ERANGE_FILL
5468
    else
5469
#endif
5470
0
        xx = (ix_uint64)*ip;
5471
5472
0
    put_ix_uint64(xp, &xx);
5473
0
    return err;
5474
0
}
5475
5476
5477
5478
/* x_size_t */
5479
5480
#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
5481
#error "x_size_t implementation"
5482
/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
5483
#endif
5484
5485
int
5486
ncx_put_size_t(void **xpp, const size_t *ulp)
5487
544k
{
5488
  /* similar to put_ix_int() */
5489
544k
  uchar *cp = (uchar *) *xpp;
5490
544k
  assert(*ulp <= X_SIZE_MAX);
5491
5492
544k
  *cp++ = (uchar)((*ulp) >> 24);
5493
544k
  *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
5494
544k
  *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
5495
544k
  *cp   = (uchar)((*ulp) & 0x000000ff);
5496
5497
544k
  *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
5498
544k
  return NC_NOERR;
5499
544k
}
5500
5501
int
5502
ncx_get_size_t(const void **xpp,  size_t *ulp)
5503
504k
{
5504
  /* similar to get_ix_int */
5505
504k
  const uchar *cp = (const uchar *) *xpp;
5506
5507
504k
  *ulp  = (unsigned)(*cp++) << 24;
5508
504k
  *ulp |= (*cp++ << 16);
5509
504k
  *ulp |= (*cp++ << 8);
5510
504k
  *ulp |= *cp;
5511
5512
504k
  *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
5513
504k
  return NC_NOERR;
5514
504k
}
5515
5516
/* x_off_t */
5517
5518
int
5519
ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
5520
60.5k
{
5521
  /* similar to put_ix_int() */
5522
60.5k
  uchar *cp = (uchar *) *xpp;
5523
5524
  /* No negative offsets stored in netcdf */
5525
60.5k
  if (*lp < 0) {
5526
    /* Assume this is an overflow of a 32-bit int... */
5527
0
    return NC_ERANGE;
5528
0
  }
5529
5530
60.5k
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5531
5532
60.5k
  if (sizeof_off_t == 4) {
5533
60.5k
    *cp++ = (uchar) ((*lp)               >> 24);
5534
60.5k
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5535
60.5k
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5536
60.5k
    *cp   = (uchar)( (*lp) & 0x000000ff);
5537
60.5k
  } else {
5538
#if SIZEOF_OFF_T == 4
5539
/* Write a 64-bit offset on a system with only a 32-bit offset */
5540
    *cp++ = (uchar)0;
5541
    *cp++ = (uchar)0;
5542
    *cp++ = (uchar)0;
5543
    *cp++ = (uchar)0;
5544
5545
    *cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
5546
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5547
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5548
    *cp   = (uchar)( (*lp) & 0x000000ff);
5549
#else
5550
0
    *cp++ = (uchar) ((*lp)                          >> 56);
5551
0
    *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48);
5552
0
    *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40);
5553
0
    *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32);
5554
0
    *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24);
5555
0
    *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16);
5556
0
    *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >>  8);
5557
0
    *cp   = (uchar)( (*lp) & 0x00000000000000ffLL);
5558
0
#endif
5559
0
  }
5560
60.5k
  *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
5561
60.5k
  return NC_NOERR;
5562
60.5k
}
5563
5564
int
5565
ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
5566
60.5k
{
5567
  /* similar to get_ix_int() */
5568
60.5k
  const uchar *cp = (const uchar *) *xpp;
5569
60.5k
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5570
5571
60.5k
  if (sizeof_off_t == 4) {
5572
60.5k
    *lp =  (off_t)(*cp++ << 24);
5573
60.5k
    *lp |= (off_t)(*cp++ << 16);
5574
60.5k
    *lp |= (off_t)(*cp++ <<  8);
5575
60.5k
    *lp |= (off_t)*cp;
5576
60.5k
  } else {
5577
#if SIZEOF_OFF_T == 4
5578
/* Read a 64-bit offset on a system with only a 32-bit offset */
5579
/* If the offset overflows, set an error code and return */
5580
    *lp =  ((off_t)(*cp++) << 24);
5581
    *lp |= ((off_t)(*cp++) << 16);
5582
    *lp |= ((off_t)(*cp++) <<  8);
5583
    *lp |= ((off_t)(*cp++));
5584
/*
5585
 * lp now contains the upper 32-bits of the 64-bit offset.  if lp is
5586
 * not zero, then the dataset is larger than can be represented
5587
 * on this system.  Set an error code and return.
5588
 */
5589
    if (*lp != 0) {
5590
      return NC_ERANGE;
5591
    }
5592
5593
    *lp  = ((off_t)(*cp++) << 24);
5594
    *lp |= ((off_t)(*cp++) << 16);
5595
    *lp |= ((off_t)(*cp++) <<  8);
5596
    *lp |=  (off_t)*cp;
5597
5598
    if (*lp < 0) {
5599
      /*
5600
       * If this fails, then the offset is >2^31, but less
5601
       * than 2^32 which is not allowed, but is not caught
5602
       * by the previous check
5603
       */
5604
      return NC_ERANGE;
5605
    }
5606
#else
5607
0
    *lp =  ((off_t)(*cp++) << 56);
5608
0
    *lp |= ((off_t)(*cp++) << 48);
5609
0
    *lp |= ((off_t)(*cp++) << 40);
5610
0
    *lp |= ((off_t)(*cp++) << 32);
5611
0
    *lp |= ((off_t)(*cp++) << 24);
5612
0
    *lp |= ((off_t)(*cp++) << 16);
5613
0
    *lp |= ((off_t)(*cp++) <<  8);
5614
0
    *lp |=  (off_t)*cp;
5615
0
#endif
5616
0
  }
5617
60.5k
  *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
5618
60.5k
  return NC_NOERR;
5619
60.5k
}
5620
5621
/*----< ncx_get_uint32() >------------------------------------------*/
5622
int
5623
ncx_get_uint32(const void **xpp, uint *ip)
5624
244k
{
5625
#ifdef WORDS_BIGENDIAN
5626
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5627
     * some system, such as HPUX */
5628
    (void) memcpy(ip, *xpp, SIZEOF_UINT);
5629
#else
5630
244k
    const uchar *cp = (const uchar *) *xpp;
5631
5632
244k
    *ip = (uint)(*cp++ << 24);
5633
244k
    *ip = (uint)(*ip | (uint)(*cp++ << 16));
5634
244k
    *ip = (uint)(*ip | (uint)(*cp++ <<  8));
5635
244k
    *ip = (uint)(*ip | *cp);
5636
244k
#endif
5637
    /* advance *xpp 4 bytes */
5638
244k
    *xpp = (void *)((const char *)(*xpp) + 4);
5639
5640
244k
    return NC_NOERR;
5641
244k
}
5642
5643
/*----< ncx_get_uint64() >------------------------------------------*/
5644
int
5645
ncx_get_uint64(const void **xpp, unsigned long long *ullp)
5646
0
{
5647
#ifdef WORDS_BIGENDIAN
5648
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5649
     * some system, such as HPUX */
5650
    (void) memcpy(ullp, *xpp, SIZEOF_UINT64);
5651
#else
5652
0
    const uchar *cp = (const uchar *) *xpp;
5653
5654
    /* below is the same as calling swap8b(ullp, *xpp) */
5655
0
    *ullp = (unsigned long long)(*cp++) << 56;
5656
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48);
5657
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40);
5658
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32);
5659
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24);
5660
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16);
5661
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) <<  8);
5662
0
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp));
5663
0
#endif
5664
    /* advance *xpp 8 bytes */
5665
0
    *xpp = (void *)((const char *)(*xpp) + 8);
5666
5667
0
    return NC_NOERR;
5668
0
}
5669
5670
/*---< ncx_put_uint32() >-------------------------------------------*/
5671
/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
5672
 * form and advance *xpp 4 bytes
5673
 */
5674
int
5675
ncx_put_uint32(void **xpp, const unsigned int ip)
5676
274k
{
5677
#ifdef WORDS_BIGENDIAN
5678
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5679
     * some system, such as HPUX */
5680
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
5681
#else
5682
    /* bitwise shifts below are to produce an integer in Big Endian */
5683
274k
    uchar *cp = (uchar *) *xpp;
5684
274k
    *cp++ = (uchar)((ip & 0xff000000) >> 24);
5685
274k
    *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
5686
274k
    *cp++ = (uchar)((ip & 0x0000ff00) >>  8);
5687
274k
    *cp   = (uchar)( ip & 0x000000ff);
5688
274k
#endif
5689
    /* advance *xpp 4 bytes */
5690
274k
    *xpp  = (void *)((char *)(*xpp) + 4);
5691
5692
274k
    return NC_NOERR;
5693
274k
}
5694
5695
/*---< ncx_put_uint64() >-------------------------------------------*/
5696
/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
5697
 * form and advance *xpp 8 bytes
5698
 */
5699
int
5700
ncx_put_uint64(void **xpp, const unsigned long long ip)
5701
0
{
5702
#ifdef WORDS_BIGENDIAN
5703
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5704
     * some system, such as HPUX */
5705
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
5706
#else
5707
0
    uchar *cp = (uchar *) *xpp;
5708
    /* below is the same as calling swap8b(*xpp, &ip) */
5709
0
    *cp++ = (uchar) (ip                         >> 56);
5710
0
    *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48);
5711
0
    *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40);
5712
0
    *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32);
5713
0
    *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24);
5714
0
    *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16);
5715
0
    *cp++ = (uchar)((ip & 0x000000000000ff00LL) >>  8);
5716
0
    *cp   = (uchar) (ip & 0x00000000000000ffLL);
5717
0
#endif
5718
    /* advance *xpp 8 bytes */
5719
0
    *xpp  = (void *)((char *)(*xpp) + 8);
5720
5721
0
    return NC_NOERR;
5722
0
}
5723
5724
5725
/*
5726
 * Aggregate numeric conversion functions.
5727
 */
5728
5729
5730
5731
/* schar ---------------------------------------------------------------------*/
5732
5733
int
5734
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5735
2.55M
{
5736
2.55M
    (void) memcpy(tp, *xpp, (size_t)nelems);
5737
2.55M
  *xpp = (void *)((char *)(*xpp) + nelems);
5738
2.55M
  return NC_NOERR;
5739
5740
2.55M
}
5741
int
5742
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5743
0
{
5744
0
    int status = NC_NOERR;
5745
0
    schar *xp = (schar *)(*xpp);
5746
5747
0
    while (nelems-- != 0) {
5748
        
5749
0
        if (*xp < 0) {
5750
#ifdef ERANGE_FILL
5751
            *tp = NC_FILL_UBYTE;
5752
#endif
5753
0
            status = NC_ERANGE; /* because tp is unsigned */
5754
            
5755
#ifdef ERANGE_FILL
5756
            xp++; tp++; continue;
5757
#endif
5758
0
        }
5759
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5760
0
    }
5761
5762
0
    *xpp = (const void *)xp;
5763
0
    return status;
5764
0
}
5765
5766
int
5767
ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5768
0
{
5769
0
    int status = NC_NOERR;
5770
0
    schar *xp = (schar *)(*xpp);
5771
5772
0
    while (nelems-- != 0) {
5773
        
5774
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5775
0
    }
5776
5777
0
    *xpp = (const void *)xp;
5778
0
    return status;
5779
0
}
5780
5781
int
5782
ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5783
0
{
5784
0
    int status = NC_NOERR;
5785
0
    schar *xp = (schar *)(*xpp);
5786
5787
0
    while (nelems-- != 0) {
5788
        
5789
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5790
0
    }
5791
5792
0
    *xpp = (const void *)xp;
5793
0
    return status;
5794
0
}
5795
5796
int
5797
ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5798
0
{
5799
0
    int status = NC_NOERR;
5800
0
    schar *xp = (schar *)(*xpp);
5801
5802
0
    while (nelems-- != 0) {
5803
        
5804
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5805
0
    }
5806
5807
0
    *xpp = (const void *)xp;
5808
0
    return status;
5809
0
}
5810
5811
int
5812
ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5813
0
{
5814
0
    int status = NC_NOERR;
5815
0
    schar *xp = (schar *)(*xpp);
5816
5817
0
    while (nelems-- != 0) {
5818
        
5819
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5820
0
    }
5821
5822
0
    *xpp = (const void *)xp;
5823
0
    return status;
5824
0
}
5825
5826
int
5827
ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5828
1
{
5829
1
    int status = NC_NOERR;
5830
1
    schar *xp = (schar *)(*xpp);
5831
5832
3
    while (nelems-- != 0) {
5833
        
5834
2
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5835
2
    }
5836
5837
1
    *xpp = (const void *)xp;
5838
1
    return status;
5839
1
}
5840
5841
int
5842
ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5843
0
{
5844
0
    int status = NC_NOERR;
5845
0
    schar *xp = (schar *)(*xpp);
5846
5847
0
    while (nelems-- != 0) {
5848
        
5849
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5850
0
    }
5851
5852
0
    *xpp = (const void *)xp;
5853
0
    return status;
5854
0
}
5855
5856
int
5857
ncx_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5858
0
{
5859
0
    int status = NC_NOERR;
5860
0
    schar *xp = (schar *)(*xpp);
5861
5862
0
    while (nelems-- != 0) {
5863
        
5864
0
        if (*xp < 0) {
5865
#ifdef ERANGE_FILL
5866
            *tp = NC_FILL_USHORT;
5867
#endif
5868
0
            status = NC_ERANGE; /* because tp is unsigned */
5869
            
5870
#ifdef ERANGE_FILL
5871
            xp++; tp++; continue;
5872
#endif
5873
0
        }
5874
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5875
0
    }
5876
5877
0
    *xpp = (const void *)xp;
5878
0
    return status;
5879
0
}
5880
5881
int
5882
ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5883
0
{
5884
0
    int status = NC_NOERR;
5885
0
    schar *xp = (schar *)(*xpp);
5886
5887
0
    while (nelems-- != 0) {
5888
        
5889
0
        if (*xp < 0) {
5890
#ifdef ERANGE_FILL
5891
            *tp = NC_FILL_UINT;
5892
#endif
5893
0
            status = NC_ERANGE; /* because tp is unsigned */
5894
            
5895
#ifdef ERANGE_FILL
5896
            xp++; tp++; continue;
5897
#endif
5898
0
        }
5899
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5900
0
    }
5901
5902
0
    *xpp = (const void *)xp;
5903
0
    return status;
5904
0
}
5905
5906
int
5907
ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5908
0
{
5909
0
    int status = NC_NOERR;
5910
0
    schar *xp = (schar *)(*xpp);
5911
5912
0
    while (nelems-- != 0) {
5913
        
5914
0
        if (*xp < 0) {
5915
#ifdef ERANGE_FILL
5916
            *tp = NC_FILL_UINT64;
5917
#endif
5918
0
            status = NC_ERANGE; /* because tp is unsigned */
5919
            
5920
#ifdef ERANGE_FILL
5921
            xp++; tp++; continue;
5922
#endif
5923
0
        }
5924
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5925
0
    }
5926
5927
0
    *xpp = (const void *)xp;
5928
0
    return status;
5929
0
}
5930
5931
5932
int
5933
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5934
7.66k
{
5935
7.66k
    size_t rndup = nelems % X_ALIGN;
5936
5937
7.66k
  if (rndup)
5938
7.66k
    rndup = X_ALIGN - rndup;
5939
5940
7.66k
  (void) memcpy(tp, *xpp, (size_t)nelems);
5941
7.66k
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
5942
5943
7.66k
  return NC_NOERR;
5944
5945
7.66k
}
5946
int
5947
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5948
0
{
5949
0
    int status = NC_NOERR;
5950
0
    size_t rndup = nelems % X_ALIGN;
5951
0
    schar *xp = (schar *) *xpp;
5952
5953
0
    if (rndup)
5954
0
        rndup = X_ALIGN - rndup;
5955
5956
0
    while (nelems-- != 0) {
5957
        
5958
0
        if (*xp < 0) {
5959
#ifdef ERANGE_FILL
5960
            *tp = NC_FILL_UBYTE;
5961
#endif
5962
0
            status = NC_ERANGE; /* because tp is unsigned */
5963
            
5964
#ifdef ERANGE_FILL
5965
            xp++; tp++; continue;
5966
#endif
5967
0
        }
5968
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5969
0
    }
5970
5971
0
    *xpp = (void *)(xp + rndup);
5972
0
    return status;
5973
0
}
5974
5975
int
5976
ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5977
0
{
5978
0
    int status = NC_NOERR;
5979
0
    size_t rndup = nelems % X_ALIGN;
5980
0
    schar *xp = (schar *) *xpp;
5981
5982
0
    if (rndup)
5983
0
        rndup = X_ALIGN - rndup;
5984
5985
0
    while (nelems-- != 0) {
5986
        
5987
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5988
0
    }
5989
5990
0
    *xpp = (void *)(xp + rndup);
5991
0
    return status;
5992
0
}
5993
5994
int
5995
ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5996
0
{
5997
0
    int status = NC_NOERR;
5998
0
    size_t rndup = nelems % X_ALIGN;
5999
0
    schar *xp = (schar *) *xpp;
6000
6001
0
    if (rndup)
6002
0
        rndup = X_ALIGN - rndup;
6003
6004
0
    while (nelems-- != 0) {
6005
        
6006
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
6007
0
    }
6008
6009
0
    *xpp = (void *)(xp + rndup);
6010
0
    return status;
6011
0
}
6012
6013
int
6014
ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
6015
0
{
6016
0
    int status = NC_NOERR;
6017
0
    size_t rndup = nelems % X_ALIGN;
6018
0
    schar *xp = (schar *) *xpp;
6019
6020
0
    if (rndup)
6021
0
        rndup = X_ALIGN - rndup;
6022
6023
0
    while (nelems-- != 0) {
6024
        
6025
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
6026
0
    }
6027
6028
0
    *xpp = (void *)(xp + rndup);
6029
0
    return status;
6030
0
}
6031
6032
int
6033
ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
6034
0
{
6035
0
    int status = NC_NOERR;
6036
0
    size_t rndup = nelems % X_ALIGN;
6037
0
    schar *xp = (schar *) *xpp;
6038
6039
0
    if (rndup)
6040
0
        rndup = X_ALIGN - rndup;
6041
6042
0
    while (nelems-- != 0) {
6043
        
6044
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
6045
0
    }
6046
6047
0
    *xpp = (void *)(xp + rndup);
6048
0
    return status;
6049
0
}
6050
6051
int
6052
ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
6053
0
{
6054
0
    int status = NC_NOERR;
6055
0
    size_t rndup = nelems % X_ALIGN;
6056
0
    schar *xp = (schar *) *xpp;
6057
6058
0
    if (rndup)
6059
0
        rndup = X_ALIGN - rndup;
6060
6061
0
    while (nelems-- != 0) {
6062
        
6063
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
6064
0
    }
6065
6066
0
    *xpp = (void *)(xp + rndup);
6067
0
    return status;
6068
0
}
6069
6070
int
6071
ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
6072
0
{
6073
0
    int status = NC_NOERR;
6074
0
    size_t rndup = nelems % X_ALIGN;
6075
0
    schar *xp = (schar *) *xpp;
6076
6077
0
    if (rndup)
6078
0
        rndup = X_ALIGN - rndup;
6079
6080
0
    while (nelems-- != 0) {
6081
        
6082
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
6083
0
    }
6084
6085
0
    *xpp = (void *)(xp + rndup);
6086
0
    return status;
6087
0
}
6088
6089
int
6090
ncx_pad_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
6091
0
{
6092
0
    int status = NC_NOERR;
6093
0
    size_t rndup = nelems % X_ALIGN;
6094
0
    schar *xp = (schar *) *xpp;
6095
6096
0
    if (rndup)
6097
0
        rndup = X_ALIGN - rndup;
6098
6099
0
    while (nelems-- != 0) {
6100
        
6101
0
        if (*xp < 0) {
6102
#ifdef ERANGE_FILL
6103
            *tp = NC_FILL_USHORT;
6104
#endif
6105
0
            status = NC_ERANGE; /* because tp is unsigned */
6106
            
6107
#ifdef ERANGE_FILL
6108
            xp++; tp++; continue;
6109
#endif
6110
0
        }
6111
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
6112
0
    }
6113
6114
0
    *xpp = (void *)(xp + rndup);
6115
0
    return status;
6116
0
}
6117
6118
int
6119
ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
6120
0
{
6121
0
    int status = NC_NOERR;
6122
0
    size_t rndup = nelems % X_ALIGN;
6123
0
    schar *xp = (schar *) *xpp;
6124
6125
0
    if (rndup)
6126
0
        rndup = X_ALIGN - rndup;
6127
6128
0
    while (nelems-- != 0) {
6129
        
6130
0
        if (*xp < 0) {
6131
#ifdef ERANGE_FILL
6132
            *tp = NC_FILL_UINT;
6133
#endif
6134
0
            status = NC_ERANGE; /* because tp is unsigned */
6135
            
6136
#ifdef ERANGE_FILL
6137
            xp++; tp++; continue;
6138
#endif
6139
0
        }
6140
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
6141
0
    }
6142
6143
0
    *xpp = (void *)(xp + rndup);
6144
0
    return status;
6145
0
}
6146
6147
int
6148
ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6149
0
{
6150
0
    int status = NC_NOERR;
6151
0
    size_t rndup = nelems % X_ALIGN;
6152
0
    schar *xp = (schar *) *xpp;
6153
6154
0
    if (rndup)
6155
0
        rndup = X_ALIGN - rndup;
6156
6157
0
    while (nelems-- != 0) {
6158
        
6159
0
        if (*xp < 0) {
6160
#ifdef ERANGE_FILL
6161
            *tp = NC_FILL_UINT64;
6162
#endif
6163
0
            status = NC_ERANGE; /* because tp is unsigned */
6164
            
6165
#ifdef ERANGE_FILL
6166
            xp++; tp++; continue;
6167
#endif
6168
0
        }
6169
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
6170
0
    }
6171
6172
0
    *xpp = (void *)(xp + rndup);
6173
0
    return status;
6174
0
}
6175
6176
6177
int
6178
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6179
74.2k
{
6180
74.2k
    (void) memcpy(*xpp, tp, (size_t)nelems);
6181
74.2k
  *xpp = (void *)((char *)(*xpp) + nelems);
6182
6183
74.2k
  return NC_NOERR;
6184
6185
74.2k
}
6186
int
6187
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6188
0
{
6189
0
    int status = NC_NOERR;
6190
0
    schar *xp = (schar *) *xpp;
6191
6192
0
    while (nelems-- != 0) {
6193
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
6194
            
6195
#ifdef ERANGE_FILL
6196
            if (fillp != NULL) memcpy(xp, fillp, 1);
6197
#endif
6198
0
            status = NC_ERANGE;
6199
            
6200
#ifdef ERANGE_FILL
6201
            xp++; tp++; continue;
6202
#endif
6203
0
        }
6204
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6205
0
    }
6206
6207
0
    *xpp = (void *)xp;
6208
0
    return status;
6209
0
}
6210
6211
int
6212
ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6213
0
{
6214
0
    int status = NC_NOERR;
6215
0
    schar *xp = (schar *) *xpp;
6216
6217
0
    while (nelems-- != 0) {
6218
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6219
            
6220
#ifdef ERANGE_FILL
6221
            if (fillp != NULL) memcpy(xp, fillp, 1);
6222
#endif
6223
0
            status = NC_ERANGE;
6224
            
6225
#ifdef ERANGE_FILL
6226
            xp++; tp++; continue;
6227
#endif
6228
0
        }
6229
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6230
0
    }
6231
6232
0
    *xpp = (void *)xp;
6233
0
    return status;
6234
0
}
6235
6236
int
6237
ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6238
0
{
6239
0
    int status = NC_NOERR;
6240
0
    schar *xp = (schar *) *xpp;
6241
6242
0
    while (nelems-- != 0) {
6243
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6244
            
6245
#ifdef ERANGE_FILL
6246
            if (fillp != NULL) memcpy(xp, fillp, 1);
6247
#endif
6248
0
            status = NC_ERANGE;
6249
            
6250
#ifdef ERANGE_FILL
6251
            xp++; tp++; continue;
6252
#endif
6253
0
        }
6254
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6255
0
    }
6256
6257
0
    *xpp = (void *)xp;
6258
0
    return status;
6259
0
}
6260
6261
int
6262
ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6263
0
{
6264
0
    int status = NC_NOERR;
6265
0
    schar *xp = (schar *) *xpp;
6266
6267
0
    while (nelems-- != 0) {
6268
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6269
            
6270
#ifdef ERANGE_FILL
6271
            if (fillp != NULL) memcpy(xp, fillp, 1);
6272
#endif
6273
0
            status = NC_ERANGE;
6274
            
6275
#ifdef ERANGE_FILL
6276
            xp++; tp++; continue;
6277
#endif
6278
0
        }
6279
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6280
0
    }
6281
6282
0
    *xpp = (void *)xp;
6283
0
    return status;
6284
0
}
6285
6286
int
6287
ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6288
0
{
6289
0
    int status = NC_NOERR;
6290
0
    schar *xp = (schar *) *xpp;
6291
6292
0
    while (nelems-- != 0) {
6293
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6294
            
6295
#ifdef ERANGE_FILL
6296
            if (fillp != NULL) memcpy(xp, fillp, 1);
6297
#endif
6298
0
            status = NC_ERANGE;
6299
            
6300
#ifdef ERANGE_FILL
6301
            xp++; tp++; continue;
6302
#endif
6303
0
        }
6304
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6305
0
    }
6306
6307
0
    *xpp = (void *)xp;
6308
0
    return status;
6309
0
}
6310
6311
int
6312
ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6313
0
{
6314
0
    int status = NC_NOERR;
6315
0
    schar *xp = (schar *) *xpp;
6316
6317
0
    while (nelems-- != 0) {
6318
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6319
            
6320
#ifdef ERANGE_FILL
6321
            if (fillp != NULL) memcpy(xp, fillp, 1);
6322
#endif
6323
0
            status = NC_ERANGE;
6324
            
6325
#ifdef ERANGE_FILL
6326
            xp++; tp++; continue;
6327
#endif
6328
0
        }
6329
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6330
0
    }
6331
6332
0
    *xpp = (void *)xp;
6333
0
    return status;
6334
0
}
6335
6336
int
6337
ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6338
0
{
6339
0
    int status = NC_NOERR;
6340
0
    schar *xp = (schar *) *xpp;
6341
6342
0
    while (nelems-- != 0) {
6343
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6344
            
6345
#ifdef ERANGE_FILL
6346
            if (fillp != NULL) memcpy(xp, fillp, 1);
6347
#endif
6348
0
            status = NC_ERANGE;
6349
            
6350
#ifdef ERANGE_FILL
6351
            xp++; tp++; continue;
6352
#endif
6353
0
        }
6354
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6355
0
    }
6356
6357
0
    *xpp = (void *)xp;
6358
0
    return status;
6359
0
}
6360
6361
int
6362
ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6363
0
{
6364
0
    int status = NC_NOERR;
6365
0
    schar *xp = (schar *) *xpp;
6366
6367
0
    while (nelems-- != 0) {
6368
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6369
            
6370
#ifdef ERANGE_FILL
6371
            if (fillp != NULL) memcpy(xp, fillp, 1);
6372
#endif
6373
0
            status = NC_ERANGE;
6374
            
6375
#ifdef ERANGE_FILL
6376
            xp++; tp++; continue;
6377
#endif
6378
0
        }
6379
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6380
0
    }
6381
6382
0
    *xpp = (void *)xp;
6383
0
    return status;
6384
0
}
6385
6386
int
6387
ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6388
0
{
6389
0
    int status = NC_NOERR;
6390
0
    schar *xp = (schar *) *xpp;
6391
6392
0
    while (nelems-- != 0) {
6393
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6394
            
6395
#ifdef ERANGE_FILL
6396
            if (fillp != NULL) memcpy(xp, fillp, 1);
6397
#endif
6398
0
            status = NC_ERANGE;
6399
            
6400
#ifdef ERANGE_FILL
6401
            xp++; tp++; continue;
6402
#endif
6403
0
        }
6404
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6405
0
    }
6406
6407
0
    *xpp = (void *)xp;
6408
0
    return status;
6409
0
}
6410
6411
int
6412
ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6413
0
{
6414
0
    int status = NC_NOERR;
6415
0
    schar *xp = (schar *) *xpp;
6416
6417
0
    while (nelems-- != 0) {
6418
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6419
            
6420
#ifdef ERANGE_FILL
6421
            if (fillp != NULL) memcpy(xp, fillp, 1);
6422
#endif
6423
0
            status = NC_ERANGE;
6424
            
6425
#ifdef ERANGE_FILL
6426
            xp++; tp++; continue;
6427
#endif
6428
0
        }
6429
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6430
0
    }
6431
6432
0
    *xpp = (void *)xp;
6433
0
    return status;
6434
0
}
6435
6436
6437
int
6438
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6439
7.54k
{
6440
7.54k
    size_t rndup = nelems % X_ALIGN;
6441
6442
7.54k
  if (rndup)
6443
7.54k
    rndup = X_ALIGN - rndup;
6444
6445
7.54k
  (void) memcpy(*xpp, tp, (size_t)nelems);
6446
7.54k
  *xpp = (void *)((char *)(*xpp) + nelems);
6447
6448
7.54k
  if (rndup)
6449
7.54k
  {
6450
7.54k
    (void) memcpy(*xpp, nada, (size_t)rndup);
6451
7.54k
    *xpp = (void *)((char *)(*xpp) + rndup);
6452
7.54k
  }
6453
6454
7.54k
  return NC_NOERR;
6455
6456
7.54k
}
6457
int
6458
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6459
0
{
6460
0
    int status = NC_NOERR;
6461
0
    size_t rndup = nelems % X_ALIGN;
6462
0
    schar *xp = (schar *) *xpp;
6463
6464
0
    if (rndup) rndup = X_ALIGN - rndup;
6465
6466
0
    while (nelems-- != 0) {
6467
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
6468
            
6469
#ifdef ERANGE_FILL
6470
            if (fillp != NULL) memcpy(xp, fillp, 1);
6471
#endif
6472
0
            status = NC_ERANGE;
6473
            
6474
#ifdef ERANGE_FILL
6475
            xp++; tp++; continue;
6476
#endif
6477
0
        }
6478
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6479
0
    }
6480
6481
6482
0
    if (rndup) {
6483
0
        (void) memcpy(xp, nada, (size_t)rndup);
6484
0
        xp += rndup;
6485
0
    }
6486
6487
0
    *xpp = (void *)xp;
6488
0
    return status;
6489
0
}
6490
6491
int
6492
ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6493
0
{
6494
0
    int status = NC_NOERR;
6495
0
    size_t rndup = nelems % X_ALIGN;
6496
0
    schar *xp = (schar *) *xpp;
6497
6498
0
    if (rndup) rndup = X_ALIGN - rndup;
6499
6500
0
    while (nelems-- != 0) {
6501
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6502
            
6503
#ifdef ERANGE_FILL
6504
            if (fillp != NULL) memcpy(xp, fillp, 1);
6505
#endif
6506
0
            status = NC_ERANGE;
6507
            
6508
#ifdef ERANGE_FILL
6509
            xp++; tp++; continue;
6510
#endif
6511
0
        }
6512
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6513
0
    }
6514
6515
6516
0
    if (rndup) {
6517
0
        (void) memcpy(xp, nada, (size_t)rndup);
6518
0
        xp += rndup;
6519
0
    }
6520
6521
0
    *xpp = (void *)xp;
6522
0
    return status;
6523
0
}
6524
6525
int
6526
ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6527
0
{
6528
0
    int status = NC_NOERR;
6529
0
    size_t rndup = nelems % X_ALIGN;
6530
0
    schar *xp = (schar *) *xpp;
6531
6532
0
    if (rndup) rndup = X_ALIGN - rndup;
6533
6534
0
    while (nelems-- != 0) {
6535
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6536
            
6537
#ifdef ERANGE_FILL
6538
            if (fillp != NULL) memcpy(xp, fillp, 1);
6539
#endif
6540
0
            status = NC_ERANGE;
6541
            
6542
#ifdef ERANGE_FILL
6543
            xp++; tp++; continue;
6544
#endif
6545
0
        }
6546
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6547
0
    }
6548
6549
6550
0
    if (rndup) {
6551
0
        (void) memcpy(xp, nada, (size_t)rndup);
6552
0
        xp += rndup;
6553
0
    }
6554
6555
0
    *xpp = (void *)xp;
6556
0
    return status;
6557
0
}
6558
6559
int
6560
ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6561
0
{
6562
0
    int status = NC_NOERR;
6563
0
    size_t rndup = nelems % X_ALIGN;
6564
0
    schar *xp = (schar *) *xpp;
6565
6566
0
    if (rndup) rndup = X_ALIGN - rndup;
6567
6568
0
    while (nelems-- != 0) {
6569
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6570
            
6571
#ifdef ERANGE_FILL
6572
            if (fillp != NULL) memcpy(xp, fillp, 1);
6573
#endif
6574
0
            status = NC_ERANGE;
6575
            
6576
#ifdef ERANGE_FILL
6577
            xp++; tp++; continue;
6578
#endif
6579
0
        }
6580
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6581
0
    }
6582
6583
6584
0
    if (rndup) {
6585
0
        (void) memcpy(xp, nada, (size_t)rndup);
6586
0
        xp += rndup;
6587
0
    }
6588
6589
0
    *xpp = (void *)xp;
6590
0
    return status;
6591
0
}
6592
6593
int
6594
ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6595
0
{
6596
0
    int status = NC_NOERR;
6597
0
    size_t rndup = nelems % X_ALIGN;
6598
0
    schar *xp = (schar *) *xpp;
6599
6600
0
    if (rndup) rndup = X_ALIGN - rndup;
6601
6602
0
    while (nelems-- != 0) {
6603
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6604
            
6605
#ifdef ERANGE_FILL
6606
            if (fillp != NULL) memcpy(xp, fillp, 1);
6607
#endif
6608
0
            status = NC_ERANGE;
6609
            
6610
#ifdef ERANGE_FILL
6611
            xp++; tp++; continue;
6612
#endif
6613
0
        }
6614
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6615
0
    }
6616
6617
6618
0
    if (rndup) {
6619
0
        (void) memcpy(xp, nada, (size_t)rndup);
6620
0
        xp += rndup;
6621
0
    }
6622
6623
0
    *xpp = (void *)xp;
6624
0
    return status;
6625
0
}
6626
6627
int
6628
ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6629
0
{
6630
0
    int status = NC_NOERR;
6631
0
    size_t rndup = nelems % X_ALIGN;
6632
0
    schar *xp = (schar *) *xpp;
6633
6634
0
    if (rndup) rndup = X_ALIGN - rndup;
6635
6636
0
    while (nelems-- != 0) {
6637
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6638
            
6639
#ifdef ERANGE_FILL
6640
            if (fillp != NULL) memcpy(xp, fillp, 1);
6641
#endif
6642
0
            status = NC_ERANGE;
6643
            
6644
#ifdef ERANGE_FILL
6645
            xp++; tp++; continue;
6646
#endif
6647
0
        }
6648
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6649
0
    }
6650
6651
6652
0
    if (rndup) {
6653
0
        (void) memcpy(xp, nada, (size_t)rndup);
6654
0
        xp += rndup;
6655
0
    }
6656
6657
0
    *xpp = (void *)xp;
6658
0
    return status;
6659
0
}
6660
6661
int
6662
ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6663
0
{
6664
0
    int status = NC_NOERR;
6665
0
    size_t rndup = nelems % X_ALIGN;
6666
0
    schar *xp = (schar *) *xpp;
6667
6668
0
    if (rndup) rndup = X_ALIGN - rndup;
6669
6670
0
    while (nelems-- != 0) {
6671
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6672
            
6673
#ifdef ERANGE_FILL
6674
            if (fillp != NULL) memcpy(xp, fillp, 1);
6675
#endif
6676
0
            status = NC_ERANGE;
6677
            
6678
#ifdef ERANGE_FILL
6679
            xp++; tp++; continue;
6680
#endif
6681
0
        }
6682
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6683
0
    }
6684
6685
6686
0
    if (rndup) {
6687
0
        (void) memcpy(xp, nada, (size_t)rndup);
6688
0
        xp += rndup;
6689
0
    }
6690
6691
0
    *xpp = (void *)xp;
6692
0
    return status;
6693
0
}
6694
6695
int
6696
ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6697
0
{
6698
0
    int status = NC_NOERR;
6699
0
    size_t rndup = nelems % X_ALIGN;
6700
0
    schar *xp = (schar *) *xpp;
6701
6702
0
    if (rndup) rndup = X_ALIGN - rndup;
6703
6704
0
    while (nelems-- != 0) {
6705
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6706
            
6707
#ifdef ERANGE_FILL
6708
            if (fillp != NULL) memcpy(xp, fillp, 1);
6709
#endif
6710
0
            status = NC_ERANGE;
6711
            
6712
#ifdef ERANGE_FILL
6713
            xp++; tp++; continue;
6714
#endif
6715
0
        }
6716
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6717
0
    }
6718
6719
6720
0
    if (rndup) {
6721
0
        (void) memcpy(xp, nada, (size_t)rndup);
6722
0
        xp += rndup;
6723
0
    }
6724
6725
0
    *xpp = (void *)xp;
6726
0
    return status;
6727
0
}
6728
6729
int
6730
ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6731
0
{
6732
0
    int status = NC_NOERR;
6733
0
    size_t rndup = nelems % X_ALIGN;
6734
0
    schar *xp = (schar *) *xpp;
6735
6736
0
    if (rndup) rndup = X_ALIGN - rndup;
6737
6738
0
    while (nelems-- != 0) {
6739
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6740
            
6741
#ifdef ERANGE_FILL
6742
            if (fillp != NULL) memcpy(xp, fillp, 1);
6743
#endif
6744
0
            status = NC_ERANGE;
6745
            
6746
#ifdef ERANGE_FILL
6747
            xp++; tp++; continue;
6748
#endif
6749
0
        }
6750
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6751
0
    }
6752
6753
6754
0
    if (rndup) {
6755
0
        (void) memcpy(xp, nada, (size_t)rndup);
6756
0
        xp += rndup;
6757
0
    }
6758
6759
0
    *xpp = (void *)xp;
6760
0
    return status;
6761
0
}
6762
6763
int
6764
ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6765
0
{
6766
0
    int status = NC_NOERR;
6767
0
    size_t rndup = nelems % X_ALIGN;
6768
0
    schar *xp = (schar *) *xpp;
6769
6770
0
    if (rndup) rndup = X_ALIGN - rndup;
6771
6772
0
    while (nelems-- != 0) {
6773
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6774
            
6775
#ifdef ERANGE_FILL
6776
            if (fillp != NULL) memcpy(xp, fillp, 1);
6777
#endif
6778
0
            status = NC_ERANGE;
6779
            
6780
#ifdef ERANGE_FILL
6781
            xp++; tp++; continue;
6782
#endif
6783
0
        }
6784
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6785
0
    }
6786
6787
6788
0
    if (rndup) {
6789
0
        (void) memcpy(xp, nada, (size_t)rndup);
6790
0
        xp += rndup;
6791
0
    }
6792
6793
0
    *xpp = (void *)xp;
6794
0
    return status;
6795
0
}
6796
6797
6798
6799
/* uchar ---------------------------------------------------------------------*/
6800
int
6801
ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6802
0
{
6803
0
    int status = NC_NOERR;
6804
0
    uchar *xp = (uchar *)(*xpp);
6805
6806
0
    while (nelems-- != 0) {
6807
0
        if (*xp > SCHAR_MAX) {
6808
0
            *tp = NC_FILL_BYTE;
6809
0
            status = NC_ERANGE;
6810
            
6811
#ifdef ERANGE_FILL
6812
            xp++; tp++; continue;
6813
#endif
6814
0
        }
6815
0
  *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6816
0
    }
6817
6818
0
    *xpp = (const void *)xp;
6819
0
    return status;
6820
0
}
6821
int
6822
ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6823
1.66k
{
6824
1.66k
    (void) memcpy(tp, *xpp, (size_t)nelems);
6825
1.66k
  *xpp = (void *)((char *)(*xpp) + nelems);
6826
1.66k
  return NC_NOERR;
6827
6828
1.66k
}
6829
int
6830
ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6831
0
{
6832
0
    int status = NC_NOERR;
6833
0
    uchar *xp = (uchar *)(*xpp);
6834
6835
0
    while (nelems-- != 0) {
6836
        
6837
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6838
0
    }
6839
6840
0
    *xpp = (const void *)xp;
6841
0
    return status;
6842
0
}
6843
6844
int
6845
ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6846
0
{
6847
0
    int status = NC_NOERR;
6848
0
    uchar *xp = (uchar *)(*xpp);
6849
6850
0
    while (nelems-- != 0) {
6851
        
6852
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6853
0
    }
6854
6855
0
    *xpp = (const void *)xp;
6856
0
    return status;
6857
0
}
6858
6859
int
6860
ncx_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6861
0
{
6862
0
    int status = NC_NOERR;
6863
0
    uchar *xp = (uchar *)(*xpp);
6864
6865
0
    while (nelems-- != 0) {
6866
        
6867
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6868
0
    }
6869
6870
0
    *xpp = (const void *)xp;
6871
0
    return status;
6872
0
}
6873
6874
int
6875
ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6876
0
{
6877
0
    int status = NC_NOERR;
6878
0
    uchar *xp = (uchar *)(*xpp);
6879
6880
0
    while (nelems-- != 0) {
6881
        
6882
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6883
0
    }
6884
6885
0
    *xpp = (const void *)xp;
6886
0
    return status;
6887
0
}
6888
6889
int
6890
ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6891
0
{
6892
0
    int status = NC_NOERR;
6893
0
    uchar *xp = (uchar *)(*xpp);
6894
6895
0
    while (nelems-- != 0) {
6896
        
6897
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6898
0
    }
6899
6900
0
    *xpp = (const void *)xp;
6901
0
    return status;
6902
0
}
6903
6904
int
6905
ncx_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6906
0
{
6907
0
    int status = NC_NOERR;
6908
0
    uchar *xp = (uchar *)(*xpp);
6909
6910
0
    while (nelems-- != 0) {
6911
        
6912
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6913
0
    }
6914
6915
0
    *xpp = (const void *)xp;
6916
0
    return status;
6917
0
}
6918
6919
int
6920
ncx_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6921
0
{
6922
0
    int status = NC_NOERR;
6923
0
    uchar *xp = (uchar *)(*xpp);
6924
6925
0
    while (nelems-- != 0) {
6926
        
6927
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6928
0
    }
6929
6930
0
    *xpp = (const void *)xp;
6931
0
    return status;
6932
0
}
6933
6934
int
6935
ncx_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6936
0
{
6937
0
    int status = NC_NOERR;
6938
0
    uchar *xp = (uchar *)(*xpp);
6939
6940
0
    while (nelems-- != 0) {
6941
        
6942
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6943
0
    }
6944
6945
0
    *xpp = (const void *)xp;
6946
0
    return status;
6947
0
}
6948
6949
int
6950
ncx_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6951
0
{
6952
0
    int status = NC_NOERR;
6953
0
    uchar *xp = (uchar *)(*xpp);
6954
6955
0
    while (nelems-- != 0) {
6956
        
6957
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6958
0
    }
6959
6960
0
    *xpp = (const void *)xp;
6961
0
    return status;
6962
0
}
6963
6964
6965
int
6966
ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6967
0
{
6968
0
    int status = NC_NOERR;
6969
0
    size_t rndup = nelems % X_ALIGN;
6970
0
    uchar *xp = (uchar *) *xpp;
6971
6972
0
    if (rndup) rndup = X_ALIGN - rndup;
6973
6974
0
    while (nelems-- != 0) {
6975
0
        if (*xp > SCHAR_MAX) {
6976
0
            *tp = NC_FILL_BYTE;
6977
0
            status = NC_ERANGE;
6978
            
6979
#ifdef ERANGE_FILL
6980
            xp++; tp++; continue;
6981
#endif
6982
0
        }
6983
0
        *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6984
0
    }
6985
6986
0
    *xpp = (void *)(xp + rndup);
6987
0
    return status;
6988
0
}
6989
int
6990
ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6991
0
{
6992
0
    size_t rndup = nelems % X_ALIGN;
6993
6994
0
  if (rndup)
6995
0
    rndup = X_ALIGN - rndup;
6996
6997
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
6998
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
6999
7000
0
  return NC_NOERR;
7001
7002
0
}
7003
int
7004
ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
7005
0
{
7006
0
    int status = NC_NOERR;
7007
0
    size_t rndup = nelems % X_ALIGN;
7008
0
    uchar *xp = (uchar *) *xpp;
7009
7010
0
    if (rndup)
7011
0
        rndup = X_ALIGN - rndup;
7012
7013
0
    while (nelems-- != 0) {
7014
        
7015
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
7016
0
    }
7017
7018
0
    *xpp = (void *)(xp + rndup);
7019
0
    return status;
7020
0
}
7021
7022
int
7023
ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
7024
0
{
7025
0
    int status = NC_NOERR;
7026
0
    size_t rndup = nelems % X_ALIGN;
7027
0
    uchar *xp = (uchar *) *xpp;
7028
7029
0
    if (rndup)
7030
0
        rndup = X_ALIGN - rndup;
7031
7032
0
    while (nelems-- != 0) {
7033
        
7034
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
7035
0
    }
7036
7037
0
    *xpp = (void *)(xp + rndup);
7038
0
    return status;
7039
0
}
7040
7041
int
7042
ncx_pad_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
7043
0
{
7044
0
    int status = NC_NOERR;
7045
0
    size_t rndup = nelems % X_ALIGN;
7046
0
    uchar *xp = (uchar *) *xpp;
7047
7048
0
    if (rndup)
7049
0
        rndup = X_ALIGN - rndup;
7050
7051
0
    while (nelems-- != 0) {
7052
        
7053
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
7054
0
    }
7055
7056
0
    *xpp = (void *)(xp + rndup);
7057
0
    return status;
7058
0
}
7059
7060
int
7061
ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
7062
0
{
7063
0
    int status = NC_NOERR;
7064
0
    size_t rndup = nelems % X_ALIGN;
7065
0
    uchar *xp = (uchar *) *xpp;
7066
7067
0
    if (rndup)
7068
0
        rndup = X_ALIGN - rndup;
7069
7070
0
    while (nelems-- != 0) {
7071
        
7072
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
7073
0
    }
7074
7075
0
    *xpp = (void *)(xp + rndup);
7076
0
    return status;
7077
0
}
7078
7079
int
7080
ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
7081
0
{
7082
0
    int status = NC_NOERR;
7083
0
    size_t rndup = nelems % X_ALIGN;
7084
0
    uchar *xp = (uchar *) *xpp;
7085
7086
0
    if (rndup)
7087
0
        rndup = X_ALIGN - rndup;
7088
7089
0
    while (nelems-- != 0) {
7090
        
7091
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
7092
0
    }
7093
7094
0
    *xpp = (void *)(xp + rndup);
7095
0
    return status;
7096
0
}
7097
7098
int
7099
ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
7100
0
{
7101
0
    int status = NC_NOERR;
7102
0
    size_t rndup = nelems % X_ALIGN;
7103
0
    uchar *xp = (uchar *) *xpp;
7104
7105
0
    if (rndup)
7106
0
        rndup = X_ALIGN - rndup;
7107
7108
0
    while (nelems-- != 0) {
7109
        
7110
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
7111
0
    }
7112
7113
0
    *xpp = (void *)(xp + rndup);
7114
0
    return status;
7115
0
}
7116
7117
int
7118
ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
7119
0
{
7120
0
    int status = NC_NOERR;
7121
0
    size_t rndup = nelems % X_ALIGN;
7122
0
    uchar *xp = (uchar *) *xpp;
7123
7124
0
    if (rndup)
7125
0
        rndup = X_ALIGN - rndup;
7126
7127
0
    while (nelems-- != 0) {
7128
        
7129
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
7130
0
    }
7131
7132
0
    *xpp = (void *)(xp + rndup);
7133
0
    return status;
7134
0
}
7135
7136
int
7137
ncx_pad_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
7138
0
{
7139
0
    int status = NC_NOERR;
7140
0
    size_t rndup = nelems % X_ALIGN;
7141
0
    uchar *xp = (uchar *) *xpp;
7142
7143
0
    if (rndup)
7144
0
        rndup = X_ALIGN - rndup;
7145
7146
0
    while (nelems-- != 0) {
7147
        
7148
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
7149
0
    }
7150
7151
0
    *xpp = (void *)(xp + rndup);
7152
0
    return status;
7153
0
}
7154
7155
int
7156
ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
7157
0
{
7158
0
    int status = NC_NOERR;
7159
0
    size_t rndup = nelems % X_ALIGN;
7160
0
    uchar *xp = (uchar *) *xpp;
7161
7162
0
    if (rndup)
7163
0
        rndup = X_ALIGN - rndup;
7164
7165
0
    while (nelems-- != 0) {
7166
        
7167
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
7168
0
    }
7169
7170
0
    *xpp = (void *)(xp + rndup);
7171
0
    return status;
7172
0
}
7173
7174
7175
int
7176
ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7177
0
{
7178
0
    int status = NC_NOERR;
7179
0
    uchar *xp = (uchar *) *xpp;
7180
7181
0
    while (nelems-- != 0) {
7182
0
        if (*tp < 0) {
7183
            
7184
#ifdef ERANGE_FILL
7185
            if (fillp != NULL) memcpy(xp, fillp, 1);
7186
#endif
7187
0
            status = NC_ERANGE;
7188
            
7189
#ifdef ERANGE_FILL
7190
            xp++; tp++; continue;
7191
#endif
7192
0
        }
7193
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7194
0
    }
7195
7196
0
    *xpp = (void *)xp;
7197
0
    return status;
7198
0
}
7199
int
7200
ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7201
0
{
7202
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
7203
0
  *xpp = (void *)((char *)(*xpp) + nelems);
7204
7205
0
  return NC_NOERR;
7206
7207
0
}
7208
int
7209
ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7210
0
{
7211
0
    int status = NC_NOERR;
7212
0
    uchar *xp = (uchar *) *xpp;
7213
7214
0
    while (nelems-- != 0) {
7215
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7216
            
7217
#ifdef ERANGE_FILL
7218
            if (fillp != NULL) memcpy(xp, fillp, 1);
7219
#endif
7220
0
            status = NC_ERANGE;
7221
            
7222
#ifdef ERANGE_FILL
7223
            xp++; tp++; continue;
7224
#endif
7225
0
        }
7226
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7227
0
    }
7228
7229
0
    *xpp = (void *)xp;
7230
0
    return status;
7231
0
}
7232
7233
int
7234
ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7235
0
{
7236
0
    int status = NC_NOERR;
7237
0
    uchar *xp = (uchar *) *xpp;
7238
7239
0
    while (nelems-- != 0) {
7240
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7241
            
7242
#ifdef ERANGE_FILL
7243
            if (fillp != NULL) memcpy(xp, fillp, 1);
7244
#endif
7245
0
            status = NC_ERANGE;
7246
            
7247
#ifdef ERANGE_FILL
7248
            xp++; tp++; continue;
7249
#endif
7250
0
        }
7251
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7252
0
    }
7253
7254
0
    *xpp = (void *)xp;
7255
0
    return status;
7256
0
}
7257
7258
int
7259
ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7260
0
{
7261
0
    int status = NC_NOERR;
7262
0
    uchar *xp = (uchar *) *xpp;
7263
7264
0
    while (nelems-- != 0) {
7265
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7266
            
7267
#ifdef ERANGE_FILL
7268
            if (fillp != NULL) memcpy(xp, fillp, 1);
7269
#endif
7270
0
            status = NC_ERANGE;
7271
            
7272
#ifdef ERANGE_FILL
7273
            xp++; tp++; continue;
7274
#endif
7275
0
        }
7276
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7277
0
    }
7278
7279
0
    *xpp = (void *)xp;
7280
0
    return status;
7281
0
}
7282
7283
int
7284
ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7285
0
{
7286
0
    int status = NC_NOERR;
7287
0
    uchar *xp = (uchar *) *xpp;
7288
7289
0
    while (nelems-- != 0) {
7290
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7291
            
7292
#ifdef ERANGE_FILL
7293
            if (fillp != NULL) memcpy(xp, fillp, 1);
7294
#endif
7295
0
            status = NC_ERANGE;
7296
            
7297
#ifdef ERANGE_FILL
7298
            xp++; tp++; continue;
7299
#endif
7300
0
        }
7301
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7302
0
    }
7303
7304
0
    *xpp = (void *)xp;
7305
0
    return status;
7306
0
}
7307
7308
int
7309
ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7310
0
{
7311
0
    int status = NC_NOERR;
7312
0
    uchar *xp = (uchar *) *xpp;
7313
7314
0
    while (nelems-- != 0) {
7315
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7316
            
7317
#ifdef ERANGE_FILL
7318
            if (fillp != NULL) memcpy(xp, fillp, 1);
7319
#endif
7320
0
            status = NC_ERANGE;
7321
            
7322
#ifdef ERANGE_FILL
7323
            xp++; tp++; continue;
7324
#endif
7325
0
        }
7326
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7327
0
    }
7328
7329
0
    *xpp = (void *)xp;
7330
0
    return status;
7331
0
}
7332
7333
int
7334
ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7335
0
{
7336
0
    int status = NC_NOERR;
7337
0
    uchar *xp = (uchar *) *xpp;
7338
7339
0
    while (nelems-- != 0) {
7340
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7341
            
7342
#ifdef ERANGE_FILL
7343
            if (fillp != NULL) memcpy(xp, fillp, 1);
7344
#endif
7345
0
            status = NC_ERANGE;
7346
            
7347
#ifdef ERANGE_FILL
7348
            xp++; tp++; continue;
7349
#endif
7350
0
        }
7351
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7352
0
    }
7353
7354
0
    *xpp = (void *)xp;
7355
0
    return status;
7356
0
}
7357
7358
int
7359
ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7360
0
{
7361
0
    int status = NC_NOERR;
7362
0
    uchar *xp = (uchar *) *xpp;
7363
7364
0
    while (nelems-- != 0) {
7365
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7366
            
7367
#ifdef ERANGE_FILL
7368
            if (fillp != NULL) memcpy(xp, fillp, 1);
7369
#endif
7370
0
            status = NC_ERANGE;
7371
            
7372
#ifdef ERANGE_FILL
7373
            xp++; tp++; continue;
7374
#endif
7375
0
        }
7376
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7377
0
    }
7378
7379
0
    *xpp = (void *)xp;
7380
0
    return status;
7381
0
}
7382
7383
int
7384
ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7385
0
{
7386
0
    int status = NC_NOERR;
7387
0
    uchar *xp = (uchar *) *xpp;
7388
7389
0
    while (nelems-- != 0) {
7390
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7391
            
7392
#ifdef ERANGE_FILL
7393
            if (fillp != NULL) memcpy(xp, fillp, 1);
7394
#endif
7395
0
            status = NC_ERANGE;
7396
            
7397
#ifdef ERANGE_FILL
7398
            xp++; tp++; continue;
7399
#endif
7400
0
        }
7401
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7402
0
    }
7403
7404
0
    *xpp = (void *)xp;
7405
0
    return status;
7406
0
}
7407
7408
int
7409
ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7410
0
{
7411
0
    int status = NC_NOERR;
7412
0
    uchar *xp = (uchar *) *xpp;
7413
7414
0
    while (nelems-- != 0) {
7415
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7416
            
7417
#ifdef ERANGE_FILL
7418
            if (fillp != NULL) memcpy(xp, fillp, 1);
7419
#endif
7420
0
            status = NC_ERANGE;
7421
            
7422
#ifdef ERANGE_FILL
7423
            xp++; tp++; continue;
7424
#endif
7425
0
        }
7426
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7427
0
    }
7428
7429
0
    *xpp = (void *)xp;
7430
0
    return status;
7431
0
}
7432
7433
7434
int
7435
ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7436
0
{
7437
0
    int status = NC_NOERR;
7438
0
    size_t rndup = nelems % X_ALIGN;
7439
0
    uchar *xp = (uchar *) *xpp;
7440
7441
0
    if (rndup) rndup = X_ALIGN - rndup;
7442
7443
0
    while (nelems-- != 0) {
7444
0
        if (*tp < 0) {
7445
            
7446
#ifdef ERANGE_FILL
7447
            if (fillp != NULL) memcpy(xp, fillp, 1);
7448
#endif
7449
0
            status = NC_ERANGE;
7450
            
7451
#ifdef ERANGE_FILL
7452
            xp++; tp++; continue;
7453
#endif
7454
0
        }
7455
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7456
0
    }
7457
7458
0
    if (rndup) {
7459
0
        (void) memcpy(xp, nada, (size_t)rndup);
7460
0
        xp += rndup;
7461
0
    }
7462
7463
0
    *xpp = (void *)xp;
7464
0
    return status;
7465
0
}
7466
int
7467
ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7468
0
{
7469
0
    size_t rndup = nelems % X_ALIGN;
7470
7471
0
  if (rndup)
7472
0
    rndup = X_ALIGN - rndup;
7473
7474
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
7475
0
  *xpp = (void *)((char *)(*xpp) + nelems);
7476
7477
0
  if (rndup)
7478
0
  {
7479
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
7480
0
    *xpp = (void *)((char *)(*xpp) + rndup);
7481
0
  }
7482
7483
0
  return NC_NOERR;
7484
7485
0
}
7486
int
7487
ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7488
0
{
7489
0
    int status = NC_NOERR;
7490
0
    size_t rndup = nelems % X_ALIGN;
7491
0
    uchar *xp = (uchar *) *xpp;
7492
7493
0
    if (rndup) rndup = X_ALIGN - rndup;
7494
7495
0
    while (nelems-- != 0) {
7496
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7497
            
7498
#ifdef ERANGE_FILL
7499
            if (fillp != NULL) memcpy(xp, fillp, 1);
7500
#endif
7501
0
            status = NC_ERANGE;
7502
            
7503
#ifdef ERANGE_FILL
7504
            xp++; tp++; continue;
7505
#endif
7506
0
        }
7507
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7508
0
    }
7509
7510
7511
0
    if (rndup) {
7512
0
        (void) memcpy(xp, nada, (size_t)rndup);
7513
0
        xp += rndup;
7514
0
    }
7515
7516
0
    *xpp = (void *)xp;
7517
0
    return status;
7518
0
}
7519
7520
int
7521
ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7522
0
{
7523
0
    int status = NC_NOERR;
7524
0
    size_t rndup = nelems % X_ALIGN;
7525
0
    uchar *xp = (uchar *) *xpp;
7526
7527
0
    if (rndup) rndup = X_ALIGN - rndup;
7528
7529
0
    while (nelems-- != 0) {
7530
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7531
            
7532
#ifdef ERANGE_FILL
7533
            if (fillp != NULL) memcpy(xp, fillp, 1);
7534
#endif
7535
0
            status = NC_ERANGE;
7536
            
7537
#ifdef ERANGE_FILL
7538
            xp++; tp++; continue;
7539
#endif
7540
0
        }
7541
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7542
0
    }
7543
7544
7545
0
    if (rndup) {
7546
0
        (void) memcpy(xp, nada, (size_t)rndup);
7547
0
        xp += rndup;
7548
0
    }
7549
7550
0
    *xpp = (void *)xp;
7551
0
    return status;
7552
0
}
7553
7554
int
7555
ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7556
0
{
7557
0
    int status = NC_NOERR;
7558
0
    size_t rndup = nelems % X_ALIGN;
7559
0
    uchar *xp = (uchar *) *xpp;
7560
7561
0
    if (rndup) rndup = X_ALIGN - rndup;
7562
7563
0
    while (nelems-- != 0) {
7564
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7565
            
7566
#ifdef ERANGE_FILL
7567
            if (fillp != NULL) memcpy(xp, fillp, 1);
7568
#endif
7569
0
            status = NC_ERANGE;
7570
            
7571
#ifdef ERANGE_FILL
7572
            xp++; tp++; continue;
7573
#endif
7574
0
        }
7575
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7576
0
    }
7577
7578
7579
0
    if (rndup) {
7580
0
        (void) memcpy(xp, nada, (size_t)rndup);
7581
0
        xp += rndup;
7582
0
    }
7583
7584
0
    *xpp = (void *)xp;
7585
0
    return status;
7586
0
}
7587
7588
int
7589
ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7590
0
{
7591
0
    int status = NC_NOERR;
7592
0
    size_t rndup = nelems % X_ALIGN;
7593
0
    uchar *xp = (uchar *) *xpp;
7594
7595
0
    if (rndup) rndup = X_ALIGN - rndup;
7596
7597
0
    while (nelems-- != 0) {
7598
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7599
            
7600
#ifdef ERANGE_FILL
7601
            if (fillp != NULL) memcpy(xp, fillp, 1);
7602
#endif
7603
0
            status = NC_ERANGE;
7604
            
7605
#ifdef ERANGE_FILL
7606
            xp++; tp++; continue;
7607
#endif
7608
0
        }
7609
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7610
0
    }
7611
7612
7613
0
    if (rndup) {
7614
0
        (void) memcpy(xp, nada, (size_t)rndup);
7615
0
        xp += rndup;
7616
0
    }
7617
7618
0
    *xpp = (void *)xp;
7619
0
    return status;
7620
0
}
7621
7622
int
7623
ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7624
0
{
7625
0
    int status = NC_NOERR;
7626
0
    size_t rndup = nelems % X_ALIGN;
7627
0
    uchar *xp = (uchar *) *xpp;
7628
7629
0
    if (rndup) rndup = X_ALIGN - rndup;
7630
7631
0
    while (nelems-- != 0) {
7632
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7633
            
7634
#ifdef ERANGE_FILL
7635
            if (fillp != NULL) memcpy(xp, fillp, 1);
7636
#endif
7637
0
            status = NC_ERANGE;
7638
            
7639
#ifdef ERANGE_FILL
7640
            xp++; tp++; continue;
7641
#endif
7642
0
        }
7643
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7644
0
    }
7645
7646
7647
0
    if (rndup) {
7648
0
        (void) memcpy(xp, nada, (size_t)rndup);
7649
0
        xp += rndup;
7650
0
    }
7651
7652
0
    *xpp = (void *)xp;
7653
0
    return status;
7654
0
}
7655
7656
int
7657
ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7658
0
{
7659
0
    int status = NC_NOERR;
7660
0
    size_t rndup = nelems % X_ALIGN;
7661
0
    uchar *xp = (uchar *) *xpp;
7662
7663
0
    if (rndup) rndup = X_ALIGN - rndup;
7664
7665
0
    while (nelems-- != 0) {
7666
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7667
            
7668
#ifdef ERANGE_FILL
7669
            if (fillp != NULL) memcpy(xp, fillp, 1);
7670
#endif
7671
0
            status = NC_ERANGE;
7672
            
7673
#ifdef ERANGE_FILL
7674
            xp++; tp++; continue;
7675
#endif
7676
0
        }
7677
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7678
0
    }
7679
7680
7681
0
    if (rndup) {
7682
0
        (void) memcpy(xp, nada, (size_t)rndup);
7683
0
        xp += rndup;
7684
0
    }
7685
7686
0
    *xpp = (void *)xp;
7687
0
    return status;
7688
0
}
7689
7690
int
7691
ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7692
0
{
7693
0
    int status = NC_NOERR;
7694
0
    size_t rndup = nelems % X_ALIGN;
7695
0
    uchar *xp = (uchar *) *xpp;
7696
7697
0
    if (rndup) rndup = X_ALIGN - rndup;
7698
7699
0
    while (nelems-- != 0) {
7700
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7701
            
7702
#ifdef ERANGE_FILL
7703
            if (fillp != NULL) memcpy(xp, fillp, 1);
7704
#endif
7705
0
            status = NC_ERANGE;
7706
            
7707
#ifdef ERANGE_FILL
7708
            xp++; tp++; continue;
7709
#endif
7710
0
        }
7711
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7712
0
    }
7713
7714
7715
0
    if (rndup) {
7716
0
        (void) memcpy(xp, nada, (size_t)rndup);
7717
0
        xp += rndup;
7718
0
    }
7719
7720
0
    *xpp = (void *)xp;
7721
0
    return status;
7722
0
}
7723
7724
int
7725
ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7726
0
{
7727
0
    int status = NC_NOERR;
7728
0
    size_t rndup = nelems % X_ALIGN;
7729
0
    uchar *xp = (uchar *) *xpp;
7730
7731
0
    if (rndup) rndup = X_ALIGN - rndup;
7732
7733
0
    while (nelems-- != 0) {
7734
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7735
            
7736
#ifdef ERANGE_FILL
7737
            if (fillp != NULL) memcpy(xp, fillp, 1);
7738
#endif
7739
0
            status = NC_ERANGE;
7740
            
7741
#ifdef ERANGE_FILL
7742
            xp++; tp++; continue;
7743
#endif
7744
0
        }
7745
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7746
0
    }
7747
7748
7749
0
    if (rndup) {
7750
0
        (void) memcpy(xp, nada, (size_t)rndup);
7751
0
        xp += rndup;
7752
0
    }
7753
7754
0
    *xpp = (void *)xp;
7755
0
    return status;
7756
0
}
7757
7758
int
7759
ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7760
0
{
7761
0
    int status = NC_NOERR;
7762
0
    size_t rndup = nelems % X_ALIGN;
7763
0
    uchar *xp = (uchar *) *xpp;
7764
7765
0
    if (rndup) rndup = X_ALIGN - rndup;
7766
7767
0
    while (nelems-- != 0) {
7768
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7769
            
7770
#ifdef ERANGE_FILL
7771
            if (fillp != NULL) memcpy(xp, fillp, 1);
7772
#endif
7773
0
            status = NC_ERANGE;
7774
            
7775
#ifdef ERANGE_FILL
7776
            xp++; tp++; continue;
7777
#endif
7778
0
        }
7779
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7780
0
    }
7781
7782
7783
0
    if (rndup) {
7784
0
        (void) memcpy(xp, nada, (size_t)rndup);
7785
0
        xp += rndup;
7786
0
    }
7787
7788
0
    *xpp = (void *)xp;
7789
0
    return status;
7790
0
}
7791
7792
7793
/* short ---------------------------------------------------------------------*/
7794
7795
#if X_SIZEOF_SHORT == SIZEOF_SHORT
7796
/* optimized version */
7797
int
7798
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7799
0
{
7800
#ifdef WORDS_BIGENDIAN
7801
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
7802
# else
7803
0
  swapn2b(tp, *xpp, nelems);
7804
0
# endif
7805
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
7806
0
  return NC_NOERR;
7807
0
}
7808
#else
7809
int
7810
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7811
{
7812
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7813
7814
 /* basic algorithm is:
7815
  *   - ensure sane alignment of input data
7816
  *   - copy (conversion happens automatically) input data
7817
  *     to output
7818
  *   - update xpp to point at next unconverted input, and tp to point
7819
  *     at next location for converted output
7820
  */
7821
  long i, j, ni;
7822
  short tmp[LOOPCNT];        /* in case input is misaligned */
7823
  short *xp;
7824
  int nrange = 0;         /* number of range errors */
7825
  int realign = 0;        /* "do we need to fix input data alignment?" */
7826
  long cxp = (long) *((char**)xpp);
7827
7828
  realign = (cxp & 7) % SIZEOF_SHORT;
7829
  /* sjl: manually stripmine so we can limit amount of
7830
   * vector work space reserved to LOOPCNT elements. Also
7831
   * makes vectorisation easy */
7832
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7833
    ni=Min(nelems-j,LOOPCNT);
7834
    if (realign) {
7835
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7836
      xp = tmp;
7837
    } else {
7838
      xp = (short *) *xpp;
7839
    }
7840
   /* copy the next block */
7841
#pragma cdir loopcnt=LOOPCNT
7842
#pragma cdir shortloop
7843
    for (i=0; i<ni; i++) {
7844
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
7845
     /* test for range errors (not always needed but do it anyway) */
7846
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7847
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7848
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
7849
    }
7850
   /* update xpp and tp */
7851
    if (realign) xp = (short *) *xpp;
7852
    xp += ni;
7853
    tp += ni;
7854
    *xpp = (void*)xp;
7855
  }
7856
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7857
7858
#else   /* not SX */
7859
  const char *xp = (const char *) *xpp;
7860
  int status = NC_NOERR;
7861
7862
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7863
  {
7864
    const int lstatus = ncx_get_short_short(xp, tp);
7865
    if (status == NC_NOERR) /* report the first encountered error */
7866
      status = lstatus;
7867
  }
7868
7869
  *xpp = (const void *)xp;
7870
  return status;
7871
#endif
7872
}
7873
7874
#endif
7875
int
7876
ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
7877
0
{
7878
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7879
7880
 /* basic algorithm is:
7881
  *   - ensure sane alignment of input data
7882
  *   - copy (conversion happens automatically) input data
7883
  *     to output
7884
  *   - update xpp to point at next unconverted input, and tp to point
7885
  *     at next location for converted output
7886
  */
7887
  long i, j, ni;
7888
  short tmp[LOOPCNT];        /* in case input is misaligned */
7889
  short *xp;
7890
  int nrange = 0;         /* number of range errors */
7891
  int realign = 0;        /* "do we need to fix input data alignment?" */
7892
  long cxp = (long) *((char**)xpp);
7893
7894
  realign = (cxp & 7) % SIZEOF_SHORT;
7895
  /* sjl: manually stripmine so we can limit amount of
7896
   * vector work space reserved to LOOPCNT elements. Also
7897
   * makes vectorisation easy */
7898
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7899
    ni=Min(nelems-j,LOOPCNT);
7900
    if (realign) {
7901
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7902
      xp = tmp;
7903
    } else {
7904
      xp = (short *) *xpp;
7905
    }
7906
   /* copy the next block */
7907
#pragma cdir loopcnt=LOOPCNT
7908
#pragma cdir shortloop
7909
    for (i=0; i<ni; i++) {
7910
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
7911
     /* test for range errors (not always needed but do it anyway) */
7912
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7913
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7914
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
7915
    }
7916
   /* update xpp and tp */
7917
    if (realign) xp = (short *) *xpp;
7918
    xp += ni;
7919
    tp += ni;
7920
    *xpp = (void*)xp;
7921
  }
7922
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7923
7924
#else   /* not SX */
7925
0
  const char *xp = (const char *) *xpp;
7926
0
  int status = NC_NOERR;
7927
7928
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7929
0
  {
7930
0
    const int lstatus = ncx_get_short_schar(xp, tp);
7931
0
    if (status == NC_NOERR) /* report the first encountered error */
7932
0
      status = lstatus;
7933
0
  }
7934
7935
0
  *xpp = (const void *)xp;
7936
0
  return status;
7937
0
#endif
7938
0
}
7939
7940
int
7941
ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
7942
0
{
7943
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7944
7945
 /* basic algorithm is:
7946
  *   - ensure sane alignment of input data
7947
  *   - copy (conversion happens automatically) input data
7948
  *     to output
7949
  *   - update xpp to point at next unconverted input, and tp to point
7950
  *     at next location for converted output
7951
  */
7952
  long i, j, ni;
7953
  short tmp[LOOPCNT];        /* in case input is misaligned */
7954
  short *xp;
7955
  int nrange = 0;         /* number of range errors */
7956
  int realign = 0;        /* "do we need to fix input data alignment?" */
7957
  long cxp = (long) *((char**)xpp);
7958
7959
  realign = (cxp & 7) % SIZEOF_SHORT;
7960
  /* sjl: manually stripmine so we can limit amount of
7961
   * vector work space reserved to LOOPCNT elements. Also
7962
   * makes vectorisation easy */
7963
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7964
    ni=Min(nelems-j,LOOPCNT);
7965
    if (realign) {
7966
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7967
      xp = tmp;
7968
    } else {
7969
      xp = (short *) *xpp;
7970
    }
7971
   /* copy the next block */
7972
#pragma cdir loopcnt=LOOPCNT
7973
#pragma cdir shortloop
7974
    for (i=0; i<ni; i++) {
7975
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
7976
     /* test for range errors (not always needed but do it anyway) */
7977
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7978
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7979
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
7980
    }
7981
   /* update xpp and tp */
7982
    if (realign) xp = (short *) *xpp;
7983
    xp += ni;
7984
    tp += ni;
7985
    *xpp = (void*)xp;
7986
  }
7987
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7988
7989
#else   /* not SX */
7990
0
  const char *xp = (const char *) *xpp;
7991
0
  int status = NC_NOERR;
7992
7993
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7994
0
  {
7995
0
    const int lstatus = ncx_get_short_int(xp, tp);
7996
0
    if (status == NC_NOERR) /* report the first encountered error */
7997
0
      status = lstatus;
7998
0
  }
7999
8000
0
  *xpp = (const void *)xp;
8001
0
  return status;
8002
0
#endif
8003
0
}
8004
8005
int
8006
ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
8007
0
{
8008
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8009
8010
 /* basic algorithm is:
8011
  *   - ensure sane alignment of input data
8012
  *   - copy (conversion happens automatically) input data
8013
  *     to output
8014
  *   - update xpp to point at next unconverted input, and tp to point
8015
  *     at next location for converted output
8016
  */
8017
  long i, j, ni;
8018
  short tmp[LOOPCNT];        /* in case input is misaligned */
8019
  short *xp;
8020
  int nrange = 0;         /* number of range errors */
8021
  int realign = 0;        /* "do we need to fix input data alignment?" */
8022
  long cxp = (long) *((char**)xpp);
8023
8024
  realign = (cxp & 7) % SIZEOF_SHORT;
8025
  /* sjl: manually stripmine so we can limit amount of
8026
   * vector work space reserved to LOOPCNT elements. Also
8027
   * makes vectorisation easy */
8028
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8029
    ni=Min(nelems-j,LOOPCNT);
8030
    if (realign) {
8031
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8032
      xp = tmp;
8033
    } else {
8034
      xp = (short *) *xpp;
8035
    }
8036
   /* copy the next block */
8037
#pragma cdir loopcnt=LOOPCNT
8038
#pragma cdir shortloop
8039
    for (i=0; i<ni; i++) {
8040
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
8041
     /* test for range errors (not always needed but do it anyway) */
8042
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8043
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8044
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
8045
    }
8046
   /* update xpp and tp */
8047
    if (realign) xp = (short *) *xpp;
8048
    xp += ni;
8049
    tp += ni;
8050
    *xpp = (void*)xp;
8051
  }
8052
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8053
8054
#else   /* not SX */
8055
0
  const char *xp = (const char *) *xpp;
8056
0
  int status = NC_NOERR;
8057
8058
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8059
0
  {
8060
0
    const int lstatus = ncx_get_short_long(xp, tp);
8061
0
    if (status == NC_NOERR) /* report the first encountered error */
8062
0
      status = lstatus;
8063
0
  }
8064
8065
0
  *xpp = (const void *)xp;
8066
0
  return status;
8067
0
#endif
8068
0
}
8069
8070
int
8071
ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
8072
0
{
8073
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8074
8075
 /* basic algorithm is:
8076
  *   - ensure sane alignment of input data
8077
  *   - copy (conversion happens automatically) input data
8078
  *     to output
8079
  *   - update xpp to point at next unconverted input, and tp to point
8080
  *     at next location for converted output
8081
  */
8082
  long i, j, ni;
8083
  short tmp[LOOPCNT];        /* in case input is misaligned */
8084
  short *xp;
8085
  int nrange = 0;         /* number of range errors */
8086
  int realign = 0;        /* "do we need to fix input data alignment?" */
8087
  long cxp = (long) *((char**)xpp);
8088
8089
  realign = (cxp & 7) % SIZEOF_SHORT;
8090
  /* sjl: manually stripmine so we can limit amount of
8091
   * vector work space reserved to LOOPCNT elements. Also
8092
   * makes vectorisation easy */
8093
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8094
    ni=Min(nelems-j,LOOPCNT);
8095
    if (realign) {
8096
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8097
      xp = tmp;
8098
    } else {
8099
      xp = (short *) *xpp;
8100
    }
8101
   /* copy the next block */
8102
#pragma cdir loopcnt=LOOPCNT
8103
#pragma cdir shortloop
8104
    for (i=0; i<ni; i++) {
8105
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
8106
     /* test for range errors (not always needed but do it anyway) */
8107
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8108
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8109
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
8110
    }
8111
   /* update xpp and tp */
8112
    if (realign) xp = (short *) *xpp;
8113
    xp += ni;
8114
    tp += ni;
8115
    *xpp = (void*)xp;
8116
  }
8117
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8118
8119
#else   /* not SX */
8120
0
  const char *xp = (const char *) *xpp;
8121
0
  int status = NC_NOERR;
8122
8123
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8124
0
  {
8125
0
    const int lstatus = ncx_get_short_float(xp, tp);
8126
0
    if (status == NC_NOERR) /* report the first encountered error */
8127
0
      status = lstatus;
8128
0
  }
8129
8130
0
  *xpp = (const void *)xp;
8131
0
  return status;
8132
0
#endif
8133
0
}
8134
8135
int
8136
ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
8137
0
{
8138
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8139
8140
 /* basic algorithm is:
8141
  *   - ensure sane alignment of input data
8142
  *   - copy (conversion happens automatically) input data
8143
  *     to output
8144
  *   - update xpp to point at next unconverted input, and tp to point
8145
  *     at next location for converted output
8146
  */
8147
  long i, j, ni;
8148
  short tmp[LOOPCNT];        /* in case input is misaligned */
8149
  short *xp;
8150
  int nrange = 0;         /* number of range errors */
8151
  int realign = 0;        /* "do we need to fix input data alignment?" */
8152
  long cxp = (long) *((char**)xpp);
8153
8154
  realign = (cxp & 7) % SIZEOF_SHORT;
8155
  /* sjl: manually stripmine so we can limit amount of
8156
   * vector work space reserved to LOOPCNT elements. Also
8157
   * makes vectorisation easy */
8158
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8159
    ni=Min(nelems-j,LOOPCNT);
8160
    if (realign) {
8161
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8162
      xp = tmp;
8163
    } else {
8164
      xp = (short *) *xpp;
8165
    }
8166
   /* copy the next block */
8167
#pragma cdir loopcnt=LOOPCNT
8168
#pragma cdir shortloop
8169
    for (i=0; i<ni; i++) {
8170
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
8171
     /* test for range errors (not always needed but do it anyway) */
8172
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8173
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8174
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
8175
    }
8176
   /* update xpp and tp */
8177
    if (realign) xp = (short *) *xpp;
8178
    xp += ni;
8179
    tp += ni;
8180
    *xpp = (void*)xp;
8181
  }
8182
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8183
8184
#else   /* not SX */
8185
0
  const char *xp = (const char *) *xpp;
8186
0
  int status = NC_NOERR;
8187
8188
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8189
0
  {
8190
0
    const int lstatus = ncx_get_short_double(xp, tp);
8191
0
    if (status == NC_NOERR) /* report the first encountered error */
8192
0
      status = lstatus;
8193
0
  }
8194
8195
0
  *xpp = (const void *)xp;
8196
0
  return status;
8197
0
#endif
8198
0
}
8199
8200
int
8201
ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8202
0
{
8203
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8204
8205
 /* basic algorithm is:
8206
  *   - ensure sane alignment of input data
8207
  *   - copy (conversion happens automatically) input data
8208
  *     to output
8209
  *   - update xpp to point at next unconverted input, and tp to point
8210
  *     at next location for converted output
8211
  */
8212
  long i, j, ni;
8213
  short tmp[LOOPCNT];        /* in case input is misaligned */
8214
  short *xp;
8215
  int nrange = 0;         /* number of range errors */
8216
  int realign = 0;        /* "do we need to fix input data alignment?" */
8217
  long cxp = (long) *((char**)xpp);
8218
8219
  realign = (cxp & 7) % SIZEOF_SHORT;
8220
  /* sjl: manually stripmine so we can limit amount of
8221
   * vector work space reserved to LOOPCNT elements. Also
8222
   * makes vectorisation easy */
8223
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8224
    ni=Min(nelems-j,LOOPCNT);
8225
    if (realign) {
8226
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8227
      xp = tmp;
8228
    } else {
8229
      xp = (short *) *xpp;
8230
    }
8231
   /* copy the next block */
8232
#pragma cdir loopcnt=LOOPCNT
8233
#pragma cdir shortloop
8234
    for (i=0; i<ni; i++) {
8235
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
8236
     /* test for range errors (not always needed but do it anyway) */
8237
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8238
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8239
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
8240
    }
8241
   /* update xpp and tp */
8242
    if (realign) xp = (short *) *xpp;
8243
    xp += ni;
8244
    tp += ni;
8245
    *xpp = (void*)xp;
8246
  }
8247
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8248
8249
#else   /* not SX */
8250
0
  const char *xp = (const char *) *xpp;
8251
0
  int status = NC_NOERR;
8252
8253
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8254
0
  {
8255
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8256
0
    if (status == NC_NOERR) /* report the first encountered error */
8257
0
      status = lstatus;
8258
0
  }
8259
8260
0
  *xpp = (const void *)xp;
8261
0
  return status;
8262
0
#endif
8263
0
}
8264
8265
int
8266
ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8267
0
{
8268
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8269
8270
 /* basic algorithm is:
8271
  *   - ensure sane alignment of input data
8272
  *   - copy (conversion happens automatically) input data
8273
  *     to output
8274
  *   - update xpp to point at next unconverted input, and tp to point
8275
  *     at next location for converted output
8276
  */
8277
  long i, j, ni;
8278
  short tmp[LOOPCNT];        /* in case input is misaligned */
8279
  short *xp;
8280
  int nrange = 0;         /* number of range errors */
8281
  int realign = 0;        /* "do we need to fix input data alignment?" */
8282
  long cxp = (long) *((char**)xpp);
8283
8284
  realign = (cxp & 7) % SIZEOF_SHORT;
8285
  /* sjl: manually stripmine so we can limit amount of
8286
   * vector work space reserved to LOOPCNT elements. Also
8287
   * makes vectorisation easy */
8288
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8289
    ni=Min(nelems-j,LOOPCNT);
8290
    if (realign) {
8291
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8292
      xp = tmp;
8293
    } else {
8294
      xp = (short *) *xpp;
8295
    }
8296
   /* copy the next block */
8297
#pragma cdir loopcnt=LOOPCNT
8298
#pragma cdir shortloop
8299
    for (i=0; i<ni; i++) {
8300
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
8301
     /* test for range errors (not always needed but do it anyway) */
8302
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8303
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8304
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
8305
    }
8306
   /* update xpp and tp */
8307
    if (realign) xp = (short *) *xpp;
8308
    xp += ni;
8309
    tp += ni;
8310
    *xpp = (void*)xp;
8311
  }
8312
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8313
8314
#else   /* not SX */
8315
0
  const char *xp = (const char *) *xpp;
8316
0
  int status = NC_NOERR;
8317
8318
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8319
0
  {
8320
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8321
0
    if (status == NC_NOERR) /* report the first encountered error */
8322
0
      status = lstatus;
8323
0
  }
8324
8325
0
  *xpp = (const void *)xp;
8326
0
  return status;
8327
0
#endif
8328
0
}
8329
8330
int
8331
ncx_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8332
0
{
8333
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8334
8335
 /* basic algorithm is:
8336
  *   - ensure sane alignment of input data
8337
  *   - copy (conversion happens automatically) input data
8338
  *     to output
8339
  *   - update xpp to point at next unconverted input, and tp to point
8340
  *     at next location for converted output
8341
  */
8342
  long i, j, ni;
8343
  short tmp[LOOPCNT];        /* in case input is misaligned */
8344
  short *xp;
8345
  int nrange = 0;         /* number of range errors */
8346
  int realign = 0;        /* "do we need to fix input data alignment?" */
8347
  long cxp = (long) *((char**)xpp);
8348
8349
  realign = (cxp & 7) % SIZEOF_SHORT;
8350
  /* sjl: manually stripmine so we can limit amount of
8351
   * vector work space reserved to LOOPCNT elements. Also
8352
   * makes vectorisation easy */
8353
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8354
    ni=Min(nelems-j,LOOPCNT);
8355
    if (realign) {
8356
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8357
      xp = tmp;
8358
    } else {
8359
      xp = (short *) *xpp;
8360
    }
8361
   /* copy the next block */
8362
#pragma cdir loopcnt=LOOPCNT
8363
#pragma cdir shortloop
8364
    for (i=0; i<ni; i++) {
8365
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
8366
     /* test for range errors (not always needed but do it anyway) */
8367
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8368
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8369
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
8370
    }
8371
   /* update xpp and tp */
8372
    if (realign) xp = (short *) *xpp;
8373
    xp += ni;
8374
    tp += ni;
8375
    *xpp = (void*)xp;
8376
  }
8377
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8378
8379
#else   /* not SX */
8380
0
  const char *xp = (const char *) *xpp;
8381
0
  int status = NC_NOERR;
8382
8383
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8384
0
  {
8385
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8386
0
    if (status == NC_NOERR) /* report the first encountered error */
8387
0
      status = lstatus;
8388
0
  }
8389
8390
0
  *xpp = (const void *)xp;
8391
0
  return status;
8392
0
#endif
8393
0
}
8394
8395
int
8396
ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8397
0
{
8398
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8399
8400
 /* basic algorithm is:
8401
  *   - ensure sane alignment of input data
8402
  *   - copy (conversion happens automatically) input data
8403
  *     to output
8404
  *   - update xpp to point at next unconverted input, and tp to point
8405
  *     at next location for converted output
8406
  */
8407
  long i, j, ni;
8408
  short tmp[LOOPCNT];        /* in case input is misaligned */
8409
  short *xp;
8410
  int nrange = 0;         /* number of range errors */
8411
  int realign = 0;        /* "do we need to fix input data alignment?" */
8412
  long cxp = (long) *((char**)xpp);
8413
8414
  realign = (cxp & 7) % SIZEOF_SHORT;
8415
  /* sjl: manually stripmine so we can limit amount of
8416
   * vector work space reserved to LOOPCNT elements. Also
8417
   * makes vectorisation easy */
8418
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8419
    ni=Min(nelems-j,LOOPCNT);
8420
    if (realign) {
8421
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8422
      xp = tmp;
8423
    } else {
8424
      xp = (short *) *xpp;
8425
    }
8426
   /* copy the next block */
8427
#pragma cdir loopcnt=LOOPCNT
8428
#pragma cdir shortloop
8429
    for (i=0; i<ni; i++) {
8430
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
8431
     /* test for range errors (not always needed but do it anyway) */
8432
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8433
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8434
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
8435
    }
8436
   /* update xpp and tp */
8437
    if (realign) xp = (short *) *xpp;
8438
    xp += ni;
8439
    tp += ni;
8440
    *xpp = (void*)xp;
8441
  }
8442
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8443
8444
#else   /* not SX */
8445
0
  const char *xp = (const char *) *xpp;
8446
0
  int status = NC_NOERR;
8447
8448
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8449
0
  {
8450
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8451
0
    if (status == NC_NOERR) /* report the first encountered error */
8452
0
      status = lstatus;
8453
0
  }
8454
8455
0
  *xpp = (const void *)xp;
8456
0
  return status;
8457
0
#endif
8458
0
}
8459
8460
int
8461
ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8462
0
{
8463
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8464
8465
 /* basic algorithm is:
8466
  *   - ensure sane alignment of input data
8467
  *   - copy (conversion happens automatically) input data
8468
  *     to output
8469
  *   - update xpp to point at next unconverted input, and tp to point
8470
  *     at next location for converted output
8471
  */
8472
  long i, j, ni;
8473
  short tmp[LOOPCNT];        /* in case input is misaligned */
8474
  short *xp;
8475
  int nrange = 0;         /* number of range errors */
8476
  int realign = 0;        /* "do we need to fix input data alignment?" */
8477
  long cxp = (long) *((char**)xpp);
8478
8479
  realign = (cxp & 7) % SIZEOF_SHORT;
8480
  /* sjl: manually stripmine so we can limit amount of
8481
   * vector work space reserved to LOOPCNT elements. Also
8482
   * makes vectorisation easy */
8483
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8484
    ni=Min(nelems-j,LOOPCNT);
8485
    if (realign) {
8486
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8487
      xp = tmp;
8488
    } else {
8489
      xp = (short *) *xpp;
8490
    }
8491
   /* copy the next block */
8492
#pragma cdir loopcnt=LOOPCNT
8493
#pragma cdir shortloop
8494
    for (i=0; i<ni; i++) {
8495
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
8496
     /* test for range errors (not always needed but do it anyway) */
8497
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8498
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8499
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
8500
    }
8501
   /* update xpp and tp */
8502
    if (realign) xp = (short *) *xpp;
8503
    xp += ni;
8504
    tp += ni;
8505
    *xpp = (void*)xp;
8506
  }
8507
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8508
8509
#else   /* not SX */
8510
0
  const char *xp = (const char *) *xpp;
8511
0
  int status = NC_NOERR;
8512
8513
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8514
0
  {
8515
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8516
0
    if (status == NC_NOERR) /* report the first encountered error */
8517
0
      status = lstatus;
8518
0
  }
8519
8520
0
  *xpp = (const void *)xp;
8521
0
  return status;
8522
0
#endif
8523
0
}
8524
8525
8526
int
8527
ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
8528
0
{
8529
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8530
8531
0
  const char *xp = (const char *) *xpp;
8532
0
  int status = NC_NOERR;
8533
8534
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8535
0
  {
8536
0
    const int lstatus = ncx_get_short_schar(xp, tp);
8537
0
    if (status == NC_NOERR) /* report the first encountered error */
8538
0
      status = lstatus;
8539
0
  }
8540
8541
0
  if (rndup != 0)
8542
0
    xp += X_SIZEOF_SHORT;
8543
8544
0
  *xpp = (void *)xp;
8545
0
  return status;
8546
0
}
8547
8548
int
8549
ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8550
0
{
8551
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8552
8553
0
  const char *xp = (const char *) *xpp;
8554
0
  int status = NC_NOERR;
8555
8556
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8557
0
  {
8558
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8559
0
    if (status == NC_NOERR) /* report the first encountered error */
8560
0
      status = lstatus;
8561
0
  }
8562
8563
0
  if (rndup != 0)
8564
0
    xp += X_SIZEOF_SHORT;
8565
8566
0
  *xpp = (void *)xp;
8567
0
  return status;
8568
0
}
8569
8570
int
8571
ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
8572
10.5k
{
8573
10.5k
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8574
8575
10.5k
  const char *xp = (const char *) *xpp;
8576
10.5k
  int status = NC_NOERR;
8577
8578
21.0k
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8579
10.5k
  {
8580
10.5k
    const int lstatus = ncx_get_short_short(xp, tp);
8581
10.5k
    if (status == NC_NOERR) /* report the first encountered error */
8582
10.5k
      status = lstatus;
8583
10.5k
  }
8584
8585
10.5k
  if (rndup != 0)
8586
10.5k
    xp += X_SIZEOF_SHORT;
8587
8588
10.5k
  *xpp = (void *)xp;
8589
10.5k
  return status;
8590
10.5k
}
8591
8592
int
8593
ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
8594
0
{
8595
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8596
8597
0
  const char *xp = (const char *) *xpp;
8598
0
  int status = NC_NOERR;
8599
8600
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8601
0
  {
8602
0
    const int lstatus = ncx_get_short_int(xp, tp);
8603
0
    if (status == NC_NOERR) /* report the first encountered error */
8604
0
      status = lstatus;
8605
0
  }
8606
8607
0
  if (rndup != 0)
8608
0
    xp += X_SIZEOF_SHORT;
8609
8610
0
  *xpp = (void *)xp;
8611
0
  return status;
8612
0
}
8613
8614
int
8615
ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
8616
0
{
8617
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8618
8619
0
  const char *xp = (const char *) *xpp;
8620
0
  int status = NC_NOERR;
8621
8622
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8623
0
  {
8624
0
    const int lstatus = ncx_get_short_long(xp, tp);
8625
0
    if (status == NC_NOERR) /* report the first encountered error */
8626
0
      status = lstatus;
8627
0
  }
8628
8629
0
  if (rndup != 0)
8630
0
    xp += X_SIZEOF_SHORT;
8631
8632
0
  *xpp = (void *)xp;
8633
0
  return status;
8634
0
}
8635
8636
int
8637
ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
8638
0
{
8639
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8640
8641
0
  const char *xp = (const char *) *xpp;
8642
0
  int status = NC_NOERR;
8643
8644
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8645
0
  {
8646
0
    const int lstatus = ncx_get_short_float(xp, tp);
8647
0
    if (status == NC_NOERR) /* report the first encountered error */
8648
0
      status = lstatus;
8649
0
  }
8650
8651
0
  if (rndup != 0)
8652
0
    xp += X_SIZEOF_SHORT;
8653
8654
0
  *xpp = (void *)xp;
8655
0
  return status;
8656
0
}
8657
8658
int
8659
ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
8660
0
{
8661
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8662
8663
0
  const char *xp = (const char *) *xpp;
8664
0
  int status = NC_NOERR;
8665
8666
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8667
0
  {
8668
0
    const int lstatus = ncx_get_short_double(xp, tp);
8669
0
    if (status == NC_NOERR) /* report the first encountered error */
8670
0
      status = lstatus;
8671
0
  }
8672
8673
0
  if (rndup != 0)
8674
0
    xp += X_SIZEOF_SHORT;
8675
8676
0
  *xpp = (void *)xp;
8677
0
  return status;
8678
0
}
8679
8680
int
8681
ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8682
0
{
8683
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8684
8685
0
  const char *xp = (const char *) *xpp;
8686
0
  int status = NC_NOERR;
8687
8688
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8689
0
  {
8690
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8691
0
    if (status == NC_NOERR) /* report the first encountered error */
8692
0
      status = lstatus;
8693
0
  }
8694
8695
0
  if (rndup != 0)
8696
0
    xp += X_SIZEOF_SHORT;
8697
8698
0
  *xpp = (void *)xp;
8699
0
  return status;
8700
0
}
8701
8702
int
8703
ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8704
0
{
8705
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8706
8707
0
  const char *xp = (const char *) *xpp;
8708
0
  int status = NC_NOERR;
8709
8710
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8711
0
  {
8712
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8713
0
    if (status == NC_NOERR) /* report the first encountered error */
8714
0
      status = lstatus;
8715
0
  }
8716
8717
0
  if (rndup != 0)
8718
0
    xp += X_SIZEOF_SHORT;
8719
8720
0
  *xpp = (void *)xp;
8721
0
  return status;
8722
0
}
8723
8724
int
8725
ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8726
0
{
8727
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8728
8729
0
  const char *xp = (const char *) *xpp;
8730
0
  int status = NC_NOERR;
8731
8732
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8733
0
  {
8734
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8735
0
    if (status == NC_NOERR) /* report the first encountered error */
8736
0
      status = lstatus;
8737
0
  }
8738
8739
0
  if (rndup != 0)
8740
0
    xp += X_SIZEOF_SHORT;
8741
8742
0
  *xpp = (void *)xp;
8743
0
  return status;
8744
0
}
8745
8746
int
8747
ncx_pad_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8748
0
{
8749
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8750
8751
0
  const char *xp = (const char *) *xpp;
8752
0
  int status = NC_NOERR;
8753
8754
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8755
0
  {
8756
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8757
0
    if (status == NC_NOERR) /* report the first encountered error */
8758
0
      status = lstatus;
8759
0
  }
8760
8761
0
  if (rndup != 0)
8762
0
    xp += X_SIZEOF_SHORT;
8763
8764
0
  *xpp = (void *)xp;
8765
0
  return status;
8766
0
}
8767
8768
8769
#if X_SIZEOF_SHORT == SIZEOF_SHORT
8770
/* optimized version */
8771
int
8772
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8773
4
{
8774
#ifdef WORDS_BIGENDIAN
8775
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
8776
# else
8777
4
  swapn2b(*xpp, tp, nelems);
8778
4
# endif
8779
4
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
8780
4
  return NC_NOERR;
8781
4
}
8782
#else
8783
int
8784
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8785
{
8786
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8787
8788
 /* basic algorithm is:
8789
  *   - ensure sane alignment of output data
8790
  *   - copy (conversion happens automatically) input data
8791
  *     to output
8792
  *   - update tp to point at next unconverted input, and xpp to point
8793
  *     at next location for converted output
8794
  */
8795
  long i, j, ni;
8796
  short tmp[LOOPCNT];        /* in case input is misaligned */
8797
  short *xp;
8798
  int nrange = 0;         /* number of range errors */
8799
  int realign = 0;        /* "do we need to fix input data alignment?" */
8800
  long cxp = (long) *((char**)xpp);
8801
8802
  realign = (cxp & 7) % SIZEOF_SHORT;
8803
  /* sjl: manually stripmine so we can limit amount of
8804
   * vector work space reserved to LOOPCNT elements. Also
8805
   * makes vectorisation easy */
8806
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8807
    ni=Min(nelems-j,LOOPCNT);
8808
    if (realign) {
8809
      xp = tmp;
8810
    } else {
8811
      xp = (short *) *xpp;
8812
    }
8813
   /* copy the next block */
8814
#pragma cdir loopcnt=LOOPCNT
8815
#pragma cdir shortloop
8816
    for (i=0; i<ni; i++) {
8817
      /* the normal case: */
8818
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8819
     /* test for range errors (not always needed but do it anyway) */
8820
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8821
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8822
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8823
    }
8824
   /* copy workspace back if necessary */
8825
    if (realign) {
8826
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8827
      xp = (short *) *xpp;
8828
    }
8829
   /* update xpp and tp */
8830
    xp += ni;
8831
    tp += ni;
8832
    *xpp = (void*)xp;
8833
  }
8834
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8835
8836
#else   /* not SX */
8837
8838
  char *xp = (char *) *xpp;
8839
  int status = NC_NOERR;
8840
8841
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8842
  {
8843
    int lstatus = ncx_put_short_short(xp, tp, fillp);
8844
    if (status == NC_NOERR) /* report the first encountered error */
8845
      status = lstatus;
8846
  }
8847
8848
  *xpp = (void *)xp;
8849
  return status;
8850
#endif
8851
}
8852
8853
#endif
8854
int
8855
ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
8856
0
{
8857
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8858
8859
 /* basic algorithm is:
8860
  *   - ensure sane alignment of output data
8861
  *   - copy (conversion happens automatically) input data
8862
  *     to output
8863
  *   - update tp to point at next unconverted input, and xpp to point
8864
  *     at next location for converted output
8865
  */
8866
  long i, j, ni;
8867
  short tmp[LOOPCNT];        /* in case input is misaligned */
8868
  short *xp;
8869
  int nrange = 0;         /* number of range errors */
8870
  int realign = 0;        /* "do we need to fix input data alignment?" */
8871
  long cxp = (long) *((char**)xpp);
8872
8873
  realign = (cxp & 7) % SIZEOF_SHORT;
8874
  /* sjl: manually stripmine so we can limit amount of
8875
   * vector work space reserved to LOOPCNT elements. Also
8876
   * makes vectorisation easy */
8877
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8878
    ni=Min(nelems-j,LOOPCNT);
8879
    if (realign) {
8880
      xp = tmp;
8881
    } else {
8882
      xp = (short *) *xpp;
8883
    }
8884
   /* copy the next block */
8885
#pragma cdir loopcnt=LOOPCNT
8886
#pragma cdir shortloop
8887
    for (i=0; i<ni; i++) {
8888
      /* the normal case: */
8889
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8890
     /* test for range errors (not always needed but do it anyway) */
8891
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8892
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8893
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8894
    }
8895
   /* copy workspace back if necessary */
8896
    if (realign) {
8897
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8898
      xp = (short *) *xpp;
8899
    }
8900
   /* update xpp and tp */
8901
    xp += ni;
8902
    tp += ni;
8903
    *xpp = (void*)xp;
8904
  }
8905
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8906
8907
#else   /* not SX */
8908
8909
0
  char *xp = (char *) *xpp;
8910
0
  int status = NC_NOERR;
8911
8912
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8913
0
  {
8914
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
8915
0
    if (status == NC_NOERR) /* report the first encountered error */
8916
0
      status = lstatus;
8917
0
  }
8918
8919
0
  *xpp = (void *)xp;
8920
0
  return status;
8921
0
#endif
8922
0
}
8923
8924
int
8925
ncx_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
8926
0
{
8927
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8928
8929
 /* basic algorithm is:
8930
  *   - ensure sane alignment of output data
8931
  *   - copy (conversion happens automatically) input data
8932
  *     to output
8933
  *   - update tp to point at next unconverted input, and xpp to point
8934
  *     at next location for converted output
8935
  */
8936
  long i, j, ni;
8937
  short tmp[LOOPCNT];        /* in case input is misaligned */
8938
  short *xp;
8939
  int nrange = 0;         /* number of range errors */
8940
  int realign = 0;        /* "do we need to fix input data alignment?" */
8941
  long cxp = (long) *((char**)xpp);
8942
8943
  realign = (cxp & 7) % SIZEOF_SHORT;
8944
  /* sjl: manually stripmine so we can limit amount of
8945
   * vector work space reserved to LOOPCNT elements. Also
8946
   * makes vectorisation easy */
8947
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8948
    ni=Min(nelems-j,LOOPCNT);
8949
    if (realign) {
8950
      xp = tmp;
8951
    } else {
8952
      xp = (short *) *xpp;
8953
    }
8954
   /* copy the next block */
8955
#pragma cdir loopcnt=LOOPCNT
8956
#pragma cdir shortloop
8957
    for (i=0; i<ni; i++) {
8958
      /* the normal case: */
8959
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8960
     /* test for range errors (not always needed but do it anyway) */
8961
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8962
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8963
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8964
    }
8965
   /* copy workspace back if necessary */
8966
    if (realign) {
8967
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8968
      xp = (short *) *xpp;
8969
    }
8970
   /* update xpp and tp */
8971
    xp += ni;
8972
    tp += ni;
8973
    *xpp = (void*)xp;
8974
  }
8975
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8976
8977
#else   /* not SX */
8978
8979
0
  char *xp = (char *) *xpp;
8980
0
  int status = NC_NOERR;
8981
8982
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8983
0
  {
8984
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
8985
0
    if (status == NC_NOERR) /* report the first encountered error */
8986
0
      status = lstatus;
8987
0
  }
8988
8989
0
  *xpp = (void *)xp;
8990
0
  return status;
8991
0
#endif
8992
0
}
8993
8994
int
8995
ncx_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
8996
0
{
8997
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8998
8999
 /* basic algorithm is:
9000
  *   - ensure sane alignment of output data
9001
  *   - copy (conversion happens automatically) input data
9002
  *     to output
9003
  *   - update tp to point at next unconverted input, and xpp to point
9004
  *     at next location for converted output
9005
  */
9006
  long i, j, ni;
9007
  short tmp[LOOPCNT];        /* in case input is misaligned */
9008
  short *xp;
9009
  int nrange = 0;         /* number of range errors */
9010
  int realign = 0;        /* "do we need to fix input data alignment?" */
9011
  long cxp = (long) *((char**)xpp);
9012
9013
  realign = (cxp & 7) % SIZEOF_SHORT;
9014
  /* sjl: manually stripmine so we can limit amount of
9015
   * vector work space reserved to LOOPCNT elements. Also
9016
   * makes vectorisation easy */
9017
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9018
    ni=Min(nelems-j,LOOPCNT);
9019
    if (realign) {
9020
      xp = tmp;
9021
    } else {
9022
      xp = (short *) *xpp;
9023
    }
9024
   /* copy the next block */
9025
#pragma cdir loopcnt=LOOPCNT
9026
#pragma cdir shortloop
9027
    for (i=0; i<ni; i++) {
9028
      /* the normal case: */
9029
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9030
     /* test for range errors (not always needed but do it anyway) */
9031
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9032
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9033
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9034
    }
9035
   /* copy workspace back if necessary */
9036
    if (realign) {
9037
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9038
      xp = (short *) *xpp;
9039
    }
9040
   /* update xpp and tp */
9041
    xp += ni;
9042
    tp += ni;
9043
    *xpp = (void*)xp;
9044
  }
9045
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9046
9047
#else   /* not SX */
9048
9049
0
  char *xp = (char *) *xpp;
9050
0
  int status = NC_NOERR;
9051
9052
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9053
0
  {
9054
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
9055
0
    if (status == NC_NOERR) /* report the first encountered error */
9056
0
      status = lstatus;
9057
0
  }
9058
9059
0
  *xpp = (void *)xp;
9060
0
  return status;
9061
0
#endif
9062
0
}
9063
9064
int
9065
ncx_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9066
0
{
9067
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9068
9069
 /* basic algorithm is:
9070
  *   - ensure sane alignment of output data
9071
  *   - copy (conversion happens automatically) input data
9072
  *     to output
9073
  *   - update tp to point at next unconverted input, and xpp to point
9074
  *     at next location for converted output
9075
  */
9076
  long i, j, ni;
9077
  short tmp[LOOPCNT];        /* in case input is misaligned */
9078
  short *xp;
9079
  int nrange = 0;         /* number of range errors */
9080
  int realign = 0;        /* "do we need to fix input data alignment?" */
9081
  long cxp = (long) *((char**)xpp);
9082
9083
  realign = (cxp & 7) % SIZEOF_SHORT;
9084
  /* sjl: manually stripmine so we can limit amount of
9085
   * vector work space reserved to LOOPCNT elements. Also
9086
   * makes vectorisation easy */
9087
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9088
    ni=Min(nelems-j,LOOPCNT);
9089
    if (realign) {
9090
      xp = tmp;
9091
    } else {
9092
      xp = (short *) *xpp;
9093
    }
9094
   /* copy the next block */
9095
#pragma cdir loopcnt=LOOPCNT
9096
#pragma cdir shortloop
9097
    for (i=0; i<ni; i++) {
9098
      /* the normal case: */
9099
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9100
     /* test for range errors (not always needed but do it anyway) */
9101
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9102
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9103
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9104
    }
9105
   /* copy workspace back if necessary */
9106
    if (realign) {
9107
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9108
      xp = (short *) *xpp;
9109
    }
9110
   /* update xpp and tp */
9111
    xp += ni;
9112
    tp += ni;
9113
    *xpp = (void*)xp;
9114
  }
9115
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9116
9117
#else   /* not SX */
9118
9119
0
  char *xp = (char *) *xpp;
9120
0
  int status = NC_NOERR;
9121
9122
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9123
0
  {
9124
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
9125
0
    if (status == NC_NOERR) /* report the first encountered error */
9126
0
      status = lstatus;
9127
0
  }
9128
9129
0
  *xpp = (void *)xp;
9130
0
  return status;
9131
0
#endif
9132
0
}
9133
9134
int
9135
ncx_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9136
0
{
9137
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9138
9139
 /* basic algorithm is:
9140
  *   - ensure sane alignment of output data
9141
  *   - copy (conversion happens automatically) input data
9142
  *     to output
9143
  *   - update tp to point at next unconverted input, and xpp to point
9144
  *     at next location for converted output
9145
  */
9146
  long i, j, ni;
9147
  short tmp[LOOPCNT];        /* in case input is misaligned */
9148
  short *xp;
9149
  int nrange = 0;         /* number of range errors */
9150
  int realign = 0;        /* "do we need to fix input data alignment?" */
9151
  long cxp = (long) *((char**)xpp);
9152
9153
  realign = (cxp & 7) % SIZEOF_SHORT;
9154
  /* sjl: manually stripmine so we can limit amount of
9155
   * vector work space reserved to LOOPCNT elements. Also
9156
   * makes vectorisation easy */
9157
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9158
    ni=Min(nelems-j,LOOPCNT);
9159
    if (realign) {
9160
      xp = tmp;
9161
    } else {
9162
      xp = (short *) *xpp;
9163
    }
9164
   /* copy the next block */
9165
#pragma cdir loopcnt=LOOPCNT
9166
#pragma cdir shortloop
9167
    for (i=0; i<ni; i++) {
9168
      /* the normal case: */
9169
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9170
     /* test for range errors (not always needed but do it anyway) */
9171
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9172
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9173
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9174
    }
9175
   /* copy workspace back if necessary */
9176
    if (realign) {
9177
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9178
      xp = (short *) *xpp;
9179
    }
9180
   /* update xpp and tp */
9181
    xp += ni;
9182
    tp += ni;
9183
    *xpp = (void*)xp;
9184
  }
9185
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9186
9187
#else   /* not SX */
9188
9189
0
  char *xp = (char *) *xpp;
9190
0
  int status = NC_NOERR;
9191
9192
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9193
0
  {
9194
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
9195
0
    if (status == NC_NOERR) /* report the first encountered error */
9196
0
      status = lstatus;
9197
0
  }
9198
9199
0
  *xpp = (void *)xp;
9200
0
  return status;
9201
0
#endif
9202
0
}
9203
9204
int
9205
ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9206
0
{
9207
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9208
9209
 /* basic algorithm is:
9210
  *   - ensure sane alignment of output data
9211
  *   - copy (conversion happens automatically) input data
9212
  *     to output
9213
  *   - update tp to point at next unconverted input, and xpp to point
9214
  *     at next location for converted output
9215
  */
9216
  long i, j, ni;
9217
  short tmp[LOOPCNT];        /* in case input is misaligned */
9218
  short *xp;
9219
  int nrange = 0;         /* number of range errors */
9220
  int realign = 0;        /* "do we need to fix input data alignment?" */
9221
  long cxp = (long) *((char**)xpp);
9222
9223
  realign = (cxp & 7) % SIZEOF_SHORT;
9224
  /* sjl: manually stripmine so we can limit amount of
9225
   * vector work space reserved to LOOPCNT elements. Also
9226
   * makes vectorisation easy */
9227
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9228
    ni=Min(nelems-j,LOOPCNT);
9229
    if (realign) {
9230
      xp = tmp;
9231
    } else {
9232
      xp = (short *) *xpp;
9233
    }
9234
   /* copy the next block */
9235
#pragma cdir loopcnt=LOOPCNT
9236
#pragma cdir shortloop
9237
    for (i=0; i<ni; i++) {
9238
      /* the normal case: */
9239
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9240
     /* test for range errors (not always needed but do it anyway) */
9241
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9242
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9243
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9244
    }
9245
   /* copy workspace back if necessary */
9246
    if (realign) {
9247
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9248
      xp = (short *) *xpp;
9249
    }
9250
   /* update xpp and tp */
9251
    xp += ni;
9252
    tp += ni;
9253
    *xpp = (void*)xp;
9254
  }
9255
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9256
9257
#else   /* not SX */
9258
9259
0
  char *xp = (char *) *xpp;
9260
0
  int status = NC_NOERR;
9261
9262
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9263
0
  {
9264
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9265
0
    if (status == NC_NOERR) /* report the first encountered error */
9266
0
      status = lstatus;
9267
0
  }
9268
9269
0
  *xpp = (void *)xp;
9270
0
  return status;
9271
0
#endif
9272
0
}
9273
9274
int
9275
ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9276
0
{
9277
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9278
9279
 /* basic algorithm is:
9280
  *   - ensure sane alignment of output data
9281
  *   - copy (conversion happens automatically) input data
9282
  *     to output
9283
  *   - update tp to point at next unconverted input, and xpp to point
9284
  *     at next location for converted output
9285
  */
9286
  long i, j, ni;
9287
  short tmp[LOOPCNT];        /* in case input is misaligned */
9288
  short *xp;
9289
  int nrange = 0;         /* number of range errors */
9290
  int realign = 0;        /* "do we need to fix input data alignment?" */
9291
  long cxp = (long) *((char**)xpp);
9292
9293
  realign = (cxp & 7) % SIZEOF_SHORT;
9294
  /* sjl: manually stripmine so we can limit amount of
9295
   * vector work space reserved to LOOPCNT elements. Also
9296
   * makes vectorisation easy */
9297
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9298
    ni=Min(nelems-j,LOOPCNT);
9299
    if (realign) {
9300
      xp = tmp;
9301
    } else {
9302
      xp = (short *) *xpp;
9303
    }
9304
   /* copy the next block */
9305
#pragma cdir loopcnt=LOOPCNT
9306
#pragma cdir shortloop
9307
    for (i=0; i<ni; i++) {
9308
      /* the normal case: */
9309
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9310
     /* test for range errors (not always needed but do it anyway) */
9311
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9312
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9313
      nrange += tp[i] > X_SHORT_MAX ;
9314
    }
9315
   /* copy workspace back if necessary */
9316
    if (realign) {
9317
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9318
      xp = (short *) *xpp;
9319
    }
9320
   /* update xpp and tp */
9321
    xp += ni;
9322
    tp += ni;
9323
    *xpp = (void*)xp;
9324
  }
9325
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9326
9327
#else   /* not SX */
9328
9329
0
  char *xp = (char *) *xpp;
9330
0
  int status = NC_NOERR;
9331
9332
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9333
0
  {
9334
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9335
0
    if (status == NC_NOERR) /* report the first encountered error */
9336
0
      status = lstatus;
9337
0
  }
9338
9339
0
  *xpp = (void *)xp;
9340
0
  return status;
9341
0
#endif
9342
0
}
9343
9344
int
9345
ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9346
0
{
9347
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9348
9349
 /* basic algorithm is:
9350
  *   - ensure sane alignment of output data
9351
  *   - copy (conversion happens automatically) input data
9352
  *     to output
9353
  *   - update tp to point at next unconverted input, and xpp to point
9354
  *     at next location for converted output
9355
  */
9356
  long i, j, ni;
9357
  short tmp[LOOPCNT];        /* in case input is misaligned */
9358
  short *xp;
9359
  int nrange = 0;         /* number of range errors */
9360
  int realign = 0;        /* "do we need to fix input data alignment?" */
9361
  long cxp = (long) *((char**)xpp);
9362
9363
  realign = (cxp & 7) % SIZEOF_SHORT;
9364
  /* sjl: manually stripmine so we can limit amount of
9365
   * vector work space reserved to LOOPCNT elements. Also
9366
   * makes vectorisation easy */
9367
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9368
    ni=Min(nelems-j,LOOPCNT);
9369
    if (realign) {
9370
      xp = tmp;
9371
    } else {
9372
      xp = (short *) *xpp;
9373
    }
9374
   /* copy the next block */
9375
#pragma cdir loopcnt=LOOPCNT
9376
#pragma cdir shortloop
9377
    for (i=0; i<ni; i++) {
9378
      /* the normal case: */
9379
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9380
     /* test for range errors (not always needed but do it anyway) */
9381
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9382
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9383
      nrange += tp[i] > X_SHORT_MAX ;
9384
    }
9385
   /* copy workspace back if necessary */
9386
    if (realign) {
9387
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9388
      xp = (short *) *xpp;
9389
    }
9390
   /* update xpp and tp */
9391
    xp += ni;
9392
    tp += ni;
9393
    *xpp = (void*)xp;
9394
  }
9395
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9396
9397
#else   /* not SX */
9398
9399
0
  char *xp = (char *) *xpp;
9400
0
  int status = NC_NOERR;
9401
9402
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9403
0
  {
9404
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9405
0
    if (status == NC_NOERR) /* report the first encountered error */
9406
0
      status = lstatus;
9407
0
  }
9408
9409
0
  *xpp = (void *)xp;
9410
0
  return status;
9411
0
#endif
9412
0
}
9413
9414
int
9415
ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9416
0
{
9417
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9418
9419
 /* basic algorithm is:
9420
  *   - ensure sane alignment of output data
9421
  *   - copy (conversion happens automatically) input data
9422
  *     to output
9423
  *   - update tp to point at next unconverted input, and xpp to point
9424
  *     at next location for converted output
9425
  */
9426
  long i, j, ni;
9427
  short tmp[LOOPCNT];        /* in case input is misaligned */
9428
  short *xp;
9429
  int nrange = 0;         /* number of range errors */
9430
  int realign = 0;        /* "do we need to fix input data alignment?" */
9431
  long cxp = (long) *((char**)xpp);
9432
9433
  realign = (cxp & 7) % SIZEOF_SHORT;
9434
  /* sjl: manually stripmine so we can limit amount of
9435
   * vector work space reserved to LOOPCNT elements. Also
9436
   * makes vectorisation easy */
9437
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9438
    ni=Min(nelems-j,LOOPCNT);
9439
    if (realign) {
9440
      xp = tmp;
9441
    } else {
9442
      xp = (short *) *xpp;
9443
    }
9444
   /* copy the next block */
9445
#pragma cdir loopcnt=LOOPCNT
9446
#pragma cdir shortloop
9447
    for (i=0; i<ni; i++) {
9448
      /* the normal case: */
9449
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9450
     /* test for range errors (not always needed but do it anyway) */
9451
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9452
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9453
      nrange += tp[i] > X_SHORT_MAX ;
9454
    }
9455
   /* copy workspace back if necessary */
9456
    if (realign) {
9457
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9458
      xp = (short *) *xpp;
9459
    }
9460
   /* update xpp and tp */
9461
    xp += ni;
9462
    tp += ni;
9463
    *xpp = (void*)xp;
9464
  }
9465
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9466
9467
#else   /* not SX */
9468
9469
0
  char *xp = (char *) *xpp;
9470
0
  int status = NC_NOERR;
9471
9472
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9473
0
  {
9474
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9475
0
    if (status == NC_NOERR) /* report the first encountered error */
9476
0
      status = lstatus;
9477
0
  }
9478
9479
0
  *xpp = (void *)xp;
9480
0
  return status;
9481
0
#endif
9482
0
}
9483
9484
int
9485
ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9486
0
{
9487
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9488
9489
 /* basic algorithm is:
9490
  *   - ensure sane alignment of output data
9491
  *   - copy (conversion happens automatically) input data
9492
  *     to output
9493
  *   - update tp to point at next unconverted input, and xpp to point
9494
  *     at next location for converted output
9495
  */
9496
  long i, j, ni;
9497
  short tmp[LOOPCNT];        /* in case input is misaligned */
9498
  short *xp;
9499
  int nrange = 0;         /* number of range errors */
9500
  int realign = 0;        /* "do we need to fix input data alignment?" */
9501
  long cxp = (long) *((char**)xpp);
9502
9503
  realign = (cxp & 7) % SIZEOF_SHORT;
9504
  /* sjl: manually stripmine so we can limit amount of
9505
   * vector work space reserved to LOOPCNT elements. Also
9506
   * makes vectorisation easy */
9507
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9508
    ni=Min(nelems-j,LOOPCNT);
9509
    if (realign) {
9510
      xp = tmp;
9511
    } else {
9512
      xp = (short *) *xpp;
9513
    }
9514
   /* copy the next block */
9515
#pragma cdir loopcnt=LOOPCNT
9516
#pragma cdir shortloop
9517
    for (i=0; i<ni; i++) {
9518
      /* the normal case: */
9519
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9520
     /* test for range errors (not always needed but do it anyway) */
9521
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9522
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9523
      nrange += tp[i] > X_SHORT_MAX ;
9524
    }
9525
   /* copy workspace back if necessary */
9526
    if (realign) {
9527
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9528
      xp = (short *) *xpp;
9529
    }
9530
   /* update xpp and tp */
9531
    xp += ni;
9532
    tp += ni;
9533
    *xpp = (void*)xp;
9534
  }
9535
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9536
9537
#else   /* not SX */
9538
9539
0
  char *xp = (char *) *xpp;
9540
0
  int status = NC_NOERR;
9541
9542
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9543
0
  {
9544
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9545
0
    if (status == NC_NOERR) /* report the first encountered error */
9546
0
      status = lstatus;
9547
0
  }
9548
9549
0
  *xpp = (void *)xp;
9550
0
  return status;
9551
0
#endif
9552
0
}
9553
9554
9555
int
9556
ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
9557
0
{
9558
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9559
9560
0
  char *xp = (char *) *xpp;
9561
0
  int status = NC_NOERR;
9562
9563
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9564
0
  {
9565
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
9566
0
    if (status == NC_NOERR) /* report the first encountered error */
9567
0
      status = lstatus;
9568
0
  }
9569
9570
0
  if (rndup != 0)
9571
0
  {
9572
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9573
0
    xp += X_SIZEOF_SHORT;
9574
0
  }
9575
9576
0
  *xpp = (void *)xp;
9577
0
  return status;
9578
0
}
9579
9580
int
9581
ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9582
0
{
9583
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9584
9585
0
  char *xp = (char *) *xpp;
9586
0
  int status = NC_NOERR;
9587
9588
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9589
0
  {
9590
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9591
0
    if (status == NC_NOERR) /* report the first encountered error */
9592
0
      status = lstatus;
9593
0
  }
9594
9595
0
  if (rndup != 0)
9596
0
  {
9597
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9598
0
    xp += X_SIZEOF_SHORT;
9599
0
  }
9600
9601
0
  *xpp = (void *)xp;
9602
0
  return status;
9603
0
}
9604
9605
int
9606
ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
9607
10.5k
{
9608
10.5k
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9609
9610
10.5k
  char *xp = (char *) *xpp;
9611
10.5k
  int status = NC_NOERR;
9612
9613
21.0k
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9614
10.5k
  {
9615
10.5k
    int lstatus = ncx_put_short_short(xp, tp, fillp);
9616
10.5k
    if (status == NC_NOERR) /* report the first encountered error */
9617
10.5k
      status = lstatus;
9618
10.5k
  }
9619
9620
10.5k
  if (rndup != 0)
9621
10.5k
  {
9622
10.5k
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9623
10.5k
    xp += X_SIZEOF_SHORT;
9624
10.5k
  }
9625
9626
10.5k
  *xpp = (void *)xp;
9627
10.5k
  return status;
9628
10.5k
}
9629
9630
int
9631
ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
9632
0
{
9633
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9634
9635
0
  char *xp = (char *) *xpp;
9636
0
  int status = NC_NOERR;
9637
9638
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9639
0
  {
9640
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
9641
0
    if (status == NC_NOERR) /* report the first encountered error */
9642
0
      status = lstatus;
9643
0
  }
9644
9645
0
  if (rndup != 0)
9646
0
  {
9647
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9648
0
    xp += X_SIZEOF_SHORT;
9649
0
  }
9650
9651
0
  *xpp = (void *)xp;
9652
0
  return status;
9653
0
}
9654
9655
int
9656
ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
9657
0
{
9658
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9659
9660
0
  char *xp = (char *) *xpp;
9661
0
  int status = NC_NOERR;
9662
9663
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9664
0
  {
9665
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
9666
0
    if (status == NC_NOERR) /* report the first encountered error */
9667
0
      status = lstatus;
9668
0
  }
9669
9670
0
  if (rndup != 0)
9671
0
  {
9672
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9673
0
    xp += X_SIZEOF_SHORT;
9674
0
  }
9675
9676
0
  *xpp = (void *)xp;
9677
0
  return status;
9678
0
}
9679
9680
int
9681
ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9682
0
{
9683
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9684
9685
0
  char *xp = (char *) *xpp;
9686
0
  int status = NC_NOERR;
9687
9688
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9689
0
  {
9690
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
9691
0
    if (status == NC_NOERR) /* report the first encountered error */
9692
0
      status = lstatus;
9693
0
  }
9694
9695
0
  if (rndup != 0)
9696
0
  {
9697
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9698
0
    xp += X_SIZEOF_SHORT;
9699
0
  }
9700
9701
0
  *xpp = (void *)xp;
9702
0
  return status;
9703
0
}
9704
9705
int
9706
ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9707
0
{
9708
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9709
9710
0
  char *xp = (char *) *xpp;
9711
0
  int status = NC_NOERR;
9712
9713
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9714
0
  {
9715
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
9716
0
    if (status == NC_NOERR) /* report the first encountered error */
9717
0
      status = lstatus;
9718
0
  }
9719
9720
0
  if (rndup != 0)
9721
0
  {
9722
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9723
0
    xp += X_SIZEOF_SHORT;
9724
0
  }
9725
9726
0
  *xpp = (void *)xp;
9727
0
  return status;
9728
0
}
9729
9730
int
9731
ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9732
0
{
9733
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9734
9735
0
  char *xp = (char *) *xpp;
9736
0
  int status = NC_NOERR;
9737
9738
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9739
0
  {
9740
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9741
0
    if (status == NC_NOERR) /* report the first encountered error */
9742
0
      status = lstatus;
9743
0
  }
9744
9745
0
  if (rndup != 0)
9746
0
  {
9747
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9748
0
    xp += X_SIZEOF_SHORT;
9749
0
  }
9750
9751
0
  *xpp = (void *)xp;
9752
0
  return status;
9753
0
}
9754
9755
int
9756
ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9757
0
{
9758
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9759
9760
0
  char *xp = (char *) *xpp;
9761
0
  int status = NC_NOERR;
9762
9763
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9764
0
  {
9765
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9766
0
    if (status == NC_NOERR) /* report the first encountered error */
9767
0
      status = lstatus;
9768
0
  }
9769
9770
0
  if (rndup != 0)
9771
0
  {
9772
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9773
0
    xp += X_SIZEOF_SHORT;
9774
0
  }
9775
9776
0
  *xpp = (void *)xp;
9777
0
  return status;
9778
0
}
9779
9780
int
9781
ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9782
0
{
9783
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9784
9785
0
  char *xp = (char *) *xpp;
9786
0
  int status = NC_NOERR;
9787
9788
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9789
0
  {
9790
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9791
0
    if (status == NC_NOERR) /* report the first encountered error */
9792
0
      status = lstatus;
9793
0
  }
9794
9795
0
  if (rndup != 0)
9796
0
  {
9797
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9798
0
    xp += X_SIZEOF_SHORT;
9799
0
  }
9800
9801
0
  *xpp = (void *)xp;
9802
0
  return status;
9803
0
}
9804
9805
int
9806
ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9807
0
{
9808
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9809
9810
0
  char *xp = (char *) *xpp;
9811
0
  int status = NC_NOERR;
9812
9813
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9814
0
  {
9815
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9816
0
    if (status == NC_NOERR) /* report the first encountered error */
9817
0
      status = lstatus;
9818
0
  }
9819
9820
0
  if (rndup != 0)
9821
0
  {
9822
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9823
0
    xp += X_SIZEOF_SHORT;
9824
0
  }
9825
9826
0
  *xpp = (void *)xp;
9827
0
  return status;
9828
0
}
9829
9830
9831
9832
/* ushort --------------------------------------------------------------------*/
9833
9834
#if X_SIZEOF_USHORT == SIZEOF_USHORT
9835
/* optimized version */
9836
int
9837
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
9838
0
{
9839
#ifdef WORDS_BIGENDIAN
9840
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
9841
# else
9842
0
  swapn2b(tp, *xpp, nelems);
9843
0
# endif
9844
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
9845
0
  return NC_NOERR;
9846
0
}
9847
#else
9848
int
9849
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
9850
{
9851
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9852
9853
 /* basic algorithm is:
9854
  *   - ensure sane alignment of input data
9855
  *   - copy (conversion happens automatically) input data
9856
  *     to output
9857
  *   - update xpp to point at next unconverted input, and tp to point
9858
  *     at next location for converted output
9859
  */
9860
  long i, j, ni;
9861
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9862
  ushort *xp;
9863
  int nrange = 0;         /* number of range errors */
9864
  int realign = 0;        /* "do we need to fix input data alignment?" */
9865
  long cxp = (long) *((char**)xpp);
9866
9867
  realign = (cxp & 7) % SIZEOF_USHORT;
9868
  /* sjl: manually stripmine so we can limit amount of
9869
   * vector work space reserved to LOOPCNT elements. Also
9870
   * makes vectorisation easy */
9871
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9872
    ni=Min(nelems-j,LOOPCNT);
9873
    if (realign) {
9874
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9875
      xp = tmp;
9876
    } else {
9877
      xp = (ushort *) *xpp;
9878
    }
9879
   /* copy the next block */
9880
#pragma cdir loopcnt=LOOPCNT
9881
#pragma cdir shortloop
9882
    for (i=0; i<ni; i++) {
9883
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
9884
     /* test for range errors (not always needed but do it anyway) */
9885
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9886
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9887
      nrange += xp[i] > USHORT_MAX ;
9888
    }
9889
   /* update xpp and tp */
9890
    if (realign) xp = (ushort *) *xpp;
9891
    xp += ni;
9892
    tp += ni;
9893
    *xpp = (void*)xp;
9894
  }
9895
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9896
9897
#else   /* not SX */
9898
  const char *xp = (const char *) *xpp;
9899
  int status = NC_NOERR;
9900
9901
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9902
  {
9903
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
9904
    if (status == NC_NOERR) /* report the first encountered error */
9905
      status = lstatus;
9906
  }
9907
9908
  *xpp = (const void *)xp;
9909
  return status;
9910
#endif
9911
}
9912
9913
#endif
9914
int
9915
ncx_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
9916
0
{
9917
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9918
9919
 /* basic algorithm is:
9920
  *   - ensure sane alignment of input data
9921
  *   - copy (conversion happens automatically) input data
9922
  *     to output
9923
  *   - update xpp to point at next unconverted input, and tp to point
9924
  *     at next location for converted output
9925
  */
9926
  long i, j, ni;
9927
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9928
  ushort *xp;
9929
  int nrange = 0;         /* number of range errors */
9930
  int realign = 0;        /* "do we need to fix input data alignment?" */
9931
  long cxp = (long) *((char**)xpp);
9932
9933
  realign = (cxp & 7) % SIZEOF_USHORT;
9934
  /* sjl: manually stripmine so we can limit amount of
9935
   * vector work space reserved to LOOPCNT elements. Also
9936
   * makes vectorisation easy */
9937
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9938
    ni=Min(nelems-j,LOOPCNT);
9939
    if (realign) {
9940
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9941
      xp = tmp;
9942
    } else {
9943
      xp = (ushort *) *xpp;
9944
    }
9945
   /* copy the next block */
9946
#pragma cdir loopcnt=LOOPCNT
9947
#pragma cdir shortloop
9948
    for (i=0; i<ni; i++) {
9949
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
9950
     /* test for range errors (not always needed but do it anyway) */
9951
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9952
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9953
      nrange += xp[i] > SCHAR_MAX ;
9954
    }
9955
   /* update xpp and tp */
9956
    if (realign) xp = (ushort *) *xpp;
9957
    xp += ni;
9958
    tp += ni;
9959
    *xpp = (void*)xp;
9960
  }
9961
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9962
9963
#else   /* not SX */
9964
0
  const char *xp = (const char *) *xpp;
9965
0
  int status = NC_NOERR;
9966
9967
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9968
0
  {
9969
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
9970
0
    if (status == NC_NOERR) /* report the first encountered error */
9971
0
      status = lstatus;
9972
0
  }
9973
9974
0
  *xpp = (const void *)xp;
9975
0
  return status;
9976
0
#endif
9977
0
}
9978
9979
int
9980
ncx_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
9981
0
{
9982
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9983
9984
 /* basic algorithm is:
9985
  *   - ensure sane alignment of input data
9986
  *   - copy (conversion happens automatically) input data
9987
  *     to output
9988
  *   - update xpp to point at next unconverted input, and tp to point
9989
  *     at next location for converted output
9990
  */
9991
  long i, j, ni;
9992
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9993
  ushort *xp;
9994
  int nrange = 0;         /* number of range errors */
9995
  int realign = 0;        /* "do we need to fix input data alignment?" */
9996
  long cxp = (long) *((char**)xpp);
9997
9998
  realign = (cxp & 7) % SIZEOF_USHORT;
9999
  /* sjl: manually stripmine so we can limit amount of
10000
   * vector work space reserved to LOOPCNT elements. Also
10001
   * makes vectorisation easy */
10002
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10003
    ni=Min(nelems-j,LOOPCNT);
10004
    if (realign) {
10005
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10006
      xp = tmp;
10007
    } else {
10008
      xp = (ushort *) *xpp;
10009
    }
10010
   /* copy the next block */
10011
#pragma cdir loopcnt=LOOPCNT
10012
#pragma cdir shortloop
10013
    for (i=0; i<ni; i++) {
10014
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
10015
     /* test for range errors (not always needed but do it anyway) */
10016
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10017
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10018
      nrange += xp[i] > SHORT_MAX ;
10019
    }
10020
   /* update xpp and tp */
10021
    if (realign) xp = (ushort *) *xpp;
10022
    xp += ni;
10023
    tp += ni;
10024
    *xpp = (void*)xp;
10025
  }
10026
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10027
10028
#else   /* not SX */
10029
0
  const char *xp = (const char *) *xpp;
10030
0
  int status = NC_NOERR;
10031
10032
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10033
0
  {
10034
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
10035
0
    if (status == NC_NOERR) /* report the first encountered error */
10036
0
      status = lstatus;
10037
0
  }
10038
10039
0
  *xpp = (const void *)xp;
10040
0
  return status;
10041
0
#endif
10042
0
}
10043
10044
int
10045
ncx_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10046
0
{
10047
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10048
10049
 /* basic algorithm is:
10050
  *   - ensure sane alignment of input data
10051
  *   - copy (conversion happens automatically) input data
10052
  *     to output
10053
  *   - update xpp to point at next unconverted input, and tp to point
10054
  *     at next location for converted output
10055
  */
10056
  long i, j, ni;
10057
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10058
  ushort *xp;
10059
  int nrange = 0;         /* number of range errors */
10060
  int realign = 0;        /* "do we need to fix input data alignment?" */
10061
  long cxp = (long) *((char**)xpp);
10062
10063
  realign = (cxp & 7) % SIZEOF_USHORT;
10064
  /* sjl: manually stripmine so we can limit amount of
10065
   * vector work space reserved to LOOPCNT elements. Also
10066
   * makes vectorisation easy */
10067
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10068
    ni=Min(nelems-j,LOOPCNT);
10069
    if (realign) {
10070
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10071
      xp = tmp;
10072
    } else {
10073
      xp = (ushort *) *xpp;
10074
    }
10075
   /* copy the next block */
10076
#pragma cdir loopcnt=LOOPCNT
10077
#pragma cdir shortloop
10078
    for (i=0; i<ni; i++) {
10079
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
10080
     /* test for range errors (not always needed but do it anyway) */
10081
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10082
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10083
      nrange += xp[i] > INT_MAX ;
10084
    }
10085
   /* update xpp and tp */
10086
    if (realign) xp = (ushort *) *xpp;
10087
    xp += ni;
10088
    tp += ni;
10089
    *xpp = (void*)xp;
10090
  }
10091
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10092
10093
#else   /* not SX */
10094
0
  const char *xp = (const char *) *xpp;
10095
0
  int status = NC_NOERR;
10096
10097
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10098
0
  {
10099
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
10100
0
    if (status == NC_NOERR) /* report the first encountered error */
10101
0
      status = lstatus;
10102
0
  }
10103
10104
0
  *xpp = (const void *)xp;
10105
0
  return status;
10106
0
#endif
10107
0
}
10108
10109
int
10110
ncx_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10111
0
{
10112
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10113
10114
 /* basic algorithm is:
10115
  *   - ensure sane alignment of input data
10116
  *   - copy (conversion happens automatically) input data
10117
  *     to output
10118
  *   - update xpp to point at next unconverted input, and tp to point
10119
  *     at next location for converted output
10120
  */
10121
  long i, j, ni;
10122
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10123
  ushort *xp;
10124
  int nrange = 0;         /* number of range errors */
10125
  int realign = 0;        /* "do we need to fix input data alignment?" */
10126
  long cxp = (long) *((char**)xpp);
10127
10128
  realign = (cxp & 7) % SIZEOF_USHORT;
10129
  /* sjl: manually stripmine so we can limit amount of
10130
   * vector work space reserved to LOOPCNT elements. Also
10131
   * makes vectorisation easy */
10132
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10133
    ni=Min(nelems-j,LOOPCNT);
10134
    if (realign) {
10135
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10136
      xp = tmp;
10137
    } else {
10138
      xp = (ushort *) *xpp;
10139
    }
10140
   /* copy the next block */
10141
#pragma cdir loopcnt=LOOPCNT
10142
#pragma cdir shortloop
10143
    for (i=0; i<ni; i++) {
10144
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
10145
     /* test for range errors (not always needed but do it anyway) */
10146
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10147
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10148
      nrange += xp[i] > LONG_MAX ;
10149
    }
10150
   /* update xpp and tp */
10151
    if (realign) xp = (ushort *) *xpp;
10152
    xp += ni;
10153
    tp += ni;
10154
    *xpp = (void*)xp;
10155
  }
10156
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10157
10158
#else   /* not SX */
10159
0
  const char *xp = (const char *) *xpp;
10160
0
  int status = NC_NOERR;
10161
10162
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10163
0
  {
10164
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
10165
0
    if (status == NC_NOERR) /* report the first encountered error */
10166
0
      status = lstatus;
10167
0
  }
10168
10169
0
  *xpp = (const void *)xp;
10170
0
  return status;
10171
0
#endif
10172
0
}
10173
10174
int
10175
ncx_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10176
0
{
10177
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10178
10179
 /* basic algorithm is:
10180
  *   - ensure sane alignment of input data
10181
  *   - copy (conversion happens automatically) input data
10182
  *     to output
10183
  *   - update xpp to point at next unconverted input, and tp to point
10184
  *     at next location for converted output
10185
  */
10186
  long i, j, ni;
10187
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10188
  ushort *xp;
10189
  int nrange = 0;         /* number of range errors */
10190
  int realign = 0;        /* "do we need to fix input data alignment?" */
10191
  long cxp = (long) *((char**)xpp);
10192
10193
  realign = (cxp & 7) % SIZEOF_USHORT;
10194
  /* sjl: manually stripmine so we can limit amount of
10195
   * vector work space reserved to LOOPCNT elements. Also
10196
   * makes vectorisation easy */
10197
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10198
    ni=Min(nelems-j,LOOPCNT);
10199
    if (realign) {
10200
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10201
      xp = tmp;
10202
    } else {
10203
      xp = (ushort *) *xpp;
10204
    }
10205
   /* copy the next block */
10206
#pragma cdir loopcnt=LOOPCNT
10207
#pragma cdir shortloop
10208
    for (i=0; i<ni; i++) {
10209
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
10210
     /* test for range errors (not always needed but do it anyway) */
10211
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10212
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10213
      nrange += xp[i] > FLOAT_MAX ;
10214
    }
10215
   /* update xpp and tp */
10216
    if (realign) xp = (ushort *) *xpp;
10217
    xp += ni;
10218
    tp += ni;
10219
    *xpp = (void*)xp;
10220
  }
10221
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10222
10223
#else   /* not SX */
10224
0
  const char *xp = (const char *) *xpp;
10225
0
  int status = NC_NOERR;
10226
10227
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10228
0
  {
10229
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10230
0
    if (status == NC_NOERR) /* report the first encountered error */
10231
0
      status = lstatus;
10232
0
  }
10233
10234
0
  *xpp = (const void *)xp;
10235
0
  return status;
10236
0
#endif
10237
0
}
10238
10239
int
10240
ncx_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10241
0
{
10242
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10243
10244
 /* basic algorithm is:
10245
  *   - ensure sane alignment of input data
10246
  *   - copy (conversion happens automatically) input data
10247
  *     to output
10248
  *   - update xpp to point at next unconverted input, and tp to point
10249
  *     at next location for converted output
10250
  */
10251
  long i, j, ni;
10252
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10253
  ushort *xp;
10254
  int nrange = 0;         /* number of range errors */
10255
  int realign = 0;        /* "do we need to fix input data alignment?" */
10256
  long cxp = (long) *((char**)xpp);
10257
10258
  realign = (cxp & 7) % SIZEOF_USHORT;
10259
  /* sjl: manually stripmine so we can limit amount of
10260
   * vector work space reserved to LOOPCNT elements. Also
10261
   * makes vectorisation easy */
10262
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10263
    ni=Min(nelems-j,LOOPCNT);
10264
    if (realign) {
10265
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10266
      xp = tmp;
10267
    } else {
10268
      xp = (ushort *) *xpp;
10269
    }
10270
   /* copy the next block */
10271
#pragma cdir loopcnt=LOOPCNT
10272
#pragma cdir shortloop
10273
    for (i=0; i<ni; i++) {
10274
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
10275
     /* test for range errors (not always needed but do it anyway) */
10276
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10277
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10278
      nrange += xp[i] > DOUBLE_MAX ;
10279
    }
10280
   /* update xpp and tp */
10281
    if (realign) xp = (ushort *) *xpp;
10282
    xp += ni;
10283
    tp += ni;
10284
    *xpp = (void*)xp;
10285
  }
10286
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10287
10288
#else   /* not SX */
10289
0
  const char *xp = (const char *) *xpp;
10290
0
  int status = NC_NOERR;
10291
10292
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10293
0
  {
10294
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10295
0
    if (status == NC_NOERR) /* report the first encountered error */
10296
0
      status = lstatus;
10297
0
  }
10298
10299
0
  *xpp = (const void *)xp;
10300
0
  return status;
10301
0
#endif
10302
0
}
10303
10304
int
10305
ncx_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10306
0
{
10307
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10308
10309
 /* basic algorithm is:
10310
  *   - ensure sane alignment of input data
10311
  *   - copy (conversion happens automatically) input data
10312
  *     to output
10313
  *   - update xpp to point at next unconverted input, and tp to point
10314
  *     at next location for converted output
10315
  */
10316
  long i, j, ni;
10317
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10318
  ushort *xp;
10319
  int nrange = 0;         /* number of range errors */
10320
  int realign = 0;        /* "do we need to fix input data alignment?" */
10321
  long cxp = (long) *((char**)xpp);
10322
10323
  realign = (cxp & 7) % SIZEOF_USHORT;
10324
  /* sjl: manually stripmine so we can limit amount of
10325
   * vector work space reserved to LOOPCNT elements. Also
10326
   * makes vectorisation easy */
10327
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10328
    ni=Min(nelems-j,LOOPCNT);
10329
    if (realign) {
10330
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10331
      xp = tmp;
10332
    } else {
10333
      xp = (ushort *) *xpp;
10334
    }
10335
   /* copy the next block */
10336
#pragma cdir loopcnt=LOOPCNT
10337
#pragma cdir shortloop
10338
    for (i=0; i<ni; i++) {
10339
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
10340
     /* test for range errors (not always needed but do it anyway) */
10341
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10342
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10343
      nrange += xp[i] > LONGLONG_MAX ;
10344
    }
10345
   /* update xpp and tp */
10346
    if (realign) xp = (ushort *) *xpp;
10347
    xp += ni;
10348
    tp += ni;
10349
    *xpp = (void*)xp;
10350
  }
10351
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10352
10353
#else   /* not SX */
10354
0
  const char *xp = (const char *) *xpp;
10355
0
  int status = NC_NOERR;
10356
10357
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10358
0
  {
10359
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10360
0
    if (status == NC_NOERR) /* report the first encountered error */
10361
0
      status = lstatus;
10362
0
  }
10363
10364
0
  *xpp = (const void *)xp;
10365
0
  return status;
10366
0
#endif
10367
0
}
10368
10369
int
10370
ncx_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10371
0
{
10372
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10373
10374
 /* basic algorithm is:
10375
  *   - ensure sane alignment of input data
10376
  *   - copy (conversion happens automatically) input data
10377
  *     to output
10378
  *   - update xpp to point at next unconverted input, and tp to point
10379
  *     at next location for converted output
10380
  */
10381
  long i, j, ni;
10382
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10383
  ushort *xp;
10384
  int nrange = 0;         /* number of range errors */
10385
  int realign = 0;        /* "do we need to fix input data alignment?" */
10386
  long cxp = (long) *((char**)xpp);
10387
10388
  realign = (cxp & 7) % SIZEOF_USHORT;
10389
  /* sjl: manually stripmine so we can limit amount of
10390
   * vector work space reserved to LOOPCNT elements. Also
10391
   * makes vectorisation easy */
10392
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10393
    ni=Min(nelems-j,LOOPCNT);
10394
    if (realign) {
10395
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10396
      xp = tmp;
10397
    } else {
10398
      xp = (ushort *) *xpp;
10399
    }
10400
   /* copy the next block */
10401
#pragma cdir loopcnt=LOOPCNT
10402
#pragma cdir shortloop
10403
    for (i=0; i<ni; i++) {
10404
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
10405
     /* test for range errors (not always needed but do it anyway) */
10406
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10407
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10408
      nrange += xp[i] > UCHAR_MAX ;
10409
    }
10410
   /* update xpp and tp */
10411
    if (realign) xp = (ushort *) *xpp;
10412
    xp += ni;
10413
    tp += ni;
10414
    *xpp = (void*)xp;
10415
  }
10416
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10417
10418
#else   /* not SX */
10419
0
  const char *xp = (const char *) *xpp;
10420
0
  int status = NC_NOERR;
10421
10422
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10423
0
  {
10424
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10425
0
    if (status == NC_NOERR) /* report the first encountered error */
10426
0
      status = lstatus;
10427
0
  }
10428
10429
0
  *xpp = (const void *)xp;
10430
0
  return status;
10431
0
#endif
10432
0
}
10433
10434
int
10435
ncx_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10436
0
{
10437
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10438
10439
 /* basic algorithm is:
10440
  *   - ensure sane alignment of input data
10441
  *   - copy (conversion happens automatically) input data
10442
  *     to output
10443
  *   - update xpp to point at next unconverted input, and tp to point
10444
  *     at next location for converted output
10445
  */
10446
  long i, j, ni;
10447
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10448
  ushort *xp;
10449
  int nrange = 0;         /* number of range errors */
10450
  int realign = 0;        /* "do we need to fix input data alignment?" */
10451
  long cxp = (long) *((char**)xpp);
10452
10453
  realign = (cxp & 7) % SIZEOF_USHORT;
10454
  /* sjl: manually stripmine so we can limit amount of
10455
   * vector work space reserved to LOOPCNT elements. Also
10456
   * makes vectorisation easy */
10457
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10458
    ni=Min(nelems-j,LOOPCNT);
10459
    if (realign) {
10460
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10461
      xp = tmp;
10462
    } else {
10463
      xp = (ushort *) *xpp;
10464
    }
10465
   /* copy the next block */
10466
#pragma cdir loopcnt=LOOPCNT
10467
#pragma cdir shortloop
10468
    for (i=0; i<ni; i++) {
10469
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
10470
     /* test for range errors (not always needed but do it anyway) */
10471
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10472
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10473
      nrange += xp[i] > UINT_MAX ;
10474
    }
10475
   /* update xpp and tp */
10476
    if (realign) xp = (ushort *) *xpp;
10477
    xp += ni;
10478
    tp += ni;
10479
    *xpp = (void*)xp;
10480
  }
10481
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10482
10483
#else   /* not SX */
10484
0
  const char *xp = (const char *) *xpp;
10485
0
  int status = NC_NOERR;
10486
10487
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10488
0
  {
10489
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10490
0
    if (status == NC_NOERR) /* report the first encountered error */
10491
0
      status = lstatus;
10492
0
  }
10493
10494
0
  *xpp = (const void *)xp;
10495
0
  return status;
10496
0
#endif
10497
0
}
10498
10499
int
10500
ncx_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10501
0
{
10502
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10503
10504
 /* basic algorithm is:
10505
  *   - ensure sane alignment of input data
10506
  *   - copy (conversion happens automatically) input data
10507
  *     to output
10508
  *   - update xpp to point at next unconverted input, and tp to point
10509
  *     at next location for converted output
10510
  */
10511
  long i, j, ni;
10512
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10513
  ushort *xp;
10514
  int nrange = 0;         /* number of range errors */
10515
  int realign = 0;        /* "do we need to fix input data alignment?" */
10516
  long cxp = (long) *((char**)xpp);
10517
10518
  realign = (cxp & 7) % SIZEOF_USHORT;
10519
  /* sjl: manually stripmine so we can limit amount of
10520
   * vector work space reserved to LOOPCNT elements. Also
10521
   * makes vectorisation easy */
10522
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10523
    ni=Min(nelems-j,LOOPCNT);
10524
    if (realign) {
10525
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10526
      xp = tmp;
10527
    } else {
10528
      xp = (ushort *) *xpp;
10529
    }
10530
   /* copy the next block */
10531
#pragma cdir loopcnt=LOOPCNT
10532
#pragma cdir shortloop
10533
    for (i=0; i<ni; i++) {
10534
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
10535
     /* test for range errors (not always needed but do it anyway) */
10536
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10537
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10538
      nrange += xp[i] > ULONGLONG_MAX ;
10539
    }
10540
   /* update xpp and tp */
10541
    if (realign) xp = (ushort *) *xpp;
10542
    xp += ni;
10543
    tp += ni;
10544
    *xpp = (void*)xp;
10545
  }
10546
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10547
10548
#else   /* not SX */
10549
0
  const char *xp = (const char *) *xpp;
10550
0
  int status = NC_NOERR;
10551
10552
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10553
0
  {
10554
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10555
0
    if (status == NC_NOERR) /* report the first encountered error */
10556
0
      status = lstatus;
10557
0
  }
10558
10559
0
  *xpp = (const void *)xp;
10560
0
  return status;
10561
0
#endif
10562
0
}
10563
10564
10565
int
10566
ncx_pad_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
10567
0
{
10568
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10569
10570
0
  const char *xp = (const char *) *xpp;
10571
0
  int status = NC_NOERR;
10572
10573
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10574
0
  {
10575
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
10576
0
    if (status == NC_NOERR) /* report the first encountered error */
10577
0
      status = lstatus;
10578
0
  }
10579
10580
0
  if (rndup != 0)
10581
0
    xp += X_SIZEOF_USHORT;
10582
10583
0
  *xpp = (void *)xp;
10584
0
  return status;
10585
0
}
10586
10587
int
10588
ncx_pad_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
10589
0
{
10590
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10591
10592
0
  const char *xp = (const char *) *xpp;
10593
0
  int status = NC_NOERR;
10594
10595
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10596
0
  {
10597
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
10598
0
    if (status == NC_NOERR) /* report the first encountered error */
10599
0
      status = lstatus;
10600
0
  }
10601
10602
0
  if (rndup != 0)
10603
0
    xp += X_SIZEOF_USHORT;
10604
10605
0
  *xpp = (void *)xp;
10606
0
  return status;
10607
0
}
10608
10609
int
10610
ncx_pad_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10611
0
{
10612
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10613
10614
0
  const char *xp = (const char *) *xpp;
10615
0
  int status = NC_NOERR;
10616
10617
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10618
0
  {
10619
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
10620
0
    if (status == NC_NOERR) /* report the first encountered error */
10621
0
      status = lstatus;
10622
0
  }
10623
10624
0
  if (rndup != 0)
10625
0
    xp += X_SIZEOF_USHORT;
10626
10627
0
  *xpp = (void *)xp;
10628
0
  return status;
10629
0
}
10630
10631
int
10632
ncx_pad_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10633
0
{
10634
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10635
10636
0
  const char *xp = (const char *) *xpp;
10637
0
  int status = NC_NOERR;
10638
10639
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10640
0
  {
10641
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
10642
0
    if (status == NC_NOERR) /* report the first encountered error */
10643
0
      status = lstatus;
10644
0
  }
10645
10646
0
  if (rndup != 0)
10647
0
    xp += X_SIZEOF_USHORT;
10648
10649
0
  *xpp = (void *)xp;
10650
0
  return status;
10651
0
}
10652
10653
int
10654
ncx_pad_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10655
0
{
10656
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10657
10658
0
  const char *xp = (const char *) *xpp;
10659
0
  int status = NC_NOERR;
10660
10661
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10662
0
  {
10663
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10664
0
    if (status == NC_NOERR) /* report the first encountered error */
10665
0
      status = lstatus;
10666
0
  }
10667
10668
0
  if (rndup != 0)
10669
0
    xp += X_SIZEOF_USHORT;
10670
10671
0
  *xpp = (void *)xp;
10672
0
  return status;
10673
0
}
10674
10675
int
10676
ncx_pad_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10677
0
{
10678
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10679
10680
0
  const char *xp = (const char *) *xpp;
10681
0
  int status = NC_NOERR;
10682
10683
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10684
0
  {
10685
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10686
0
    if (status == NC_NOERR) /* report the first encountered error */
10687
0
      status = lstatus;
10688
0
  }
10689
10690
0
  if (rndup != 0)
10691
0
    xp += X_SIZEOF_USHORT;
10692
10693
0
  *xpp = (void *)xp;
10694
0
  return status;
10695
0
}
10696
10697
int
10698
ncx_pad_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10699
0
{
10700
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10701
10702
0
  const char *xp = (const char *) *xpp;
10703
0
  int status = NC_NOERR;
10704
10705
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10706
0
  {
10707
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10708
0
    if (status == NC_NOERR) /* report the first encountered error */
10709
0
      status = lstatus;
10710
0
  }
10711
10712
0
  if (rndup != 0)
10713
0
    xp += X_SIZEOF_USHORT;
10714
10715
0
  *xpp = (void *)xp;
10716
0
  return status;
10717
0
}
10718
10719
int
10720
ncx_pad_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
10721
0
{
10722
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10723
10724
0
  const char *xp = (const char *) *xpp;
10725
0
  int status = NC_NOERR;
10726
10727
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10728
0
  {
10729
0
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
10730
0
    if (status == NC_NOERR) /* report the first encountered error */
10731
0
      status = lstatus;
10732
0
  }
10733
10734
0
  if (rndup != 0)
10735
0
    xp += X_SIZEOF_USHORT;
10736
10737
0
  *xpp = (void *)xp;
10738
0
  return status;
10739
0
}
10740
10741
int
10742
ncx_pad_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10743
0
{
10744
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10745
10746
0
  const char *xp = (const char *) *xpp;
10747
0
  int status = NC_NOERR;
10748
10749
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10750
0
  {
10751
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10752
0
    if (status == NC_NOERR) /* report the first encountered error */
10753
0
      status = lstatus;
10754
0
  }
10755
10756
0
  if (rndup != 0)
10757
0
    xp += X_SIZEOF_USHORT;
10758
10759
0
  *xpp = (void *)xp;
10760
0
  return status;
10761
0
}
10762
10763
int
10764
ncx_pad_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10765
0
{
10766
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10767
10768
0
  const char *xp = (const char *) *xpp;
10769
0
  int status = NC_NOERR;
10770
10771
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10772
0
  {
10773
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10774
0
    if (status == NC_NOERR) /* report the first encountered error */
10775
0
      status = lstatus;
10776
0
  }
10777
10778
0
  if (rndup != 0)
10779
0
    xp += X_SIZEOF_USHORT;
10780
10781
0
  *xpp = (void *)xp;
10782
0
  return status;
10783
0
}
10784
10785
int
10786
ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10787
0
{
10788
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10789
10790
0
  const char *xp = (const char *) *xpp;
10791
0
  int status = NC_NOERR;
10792
10793
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10794
0
  {
10795
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10796
0
    if (status == NC_NOERR) /* report the first encountered error */
10797
0
      status = lstatus;
10798
0
  }
10799
10800
0
  if (rndup != 0)
10801
0
    xp += X_SIZEOF_USHORT;
10802
10803
0
  *xpp = (void *)xp;
10804
0
  return status;
10805
0
}
10806
10807
10808
#if X_SIZEOF_USHORT == SIZEOF_USHORT
10809
/* optimized version */
10810
int
10811
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp, void *fillp)
10812
0
{
10813
#ifdef WORDS_BIGENDIAN
10814
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
10815
# else
10816
0
  swapn2b(*xpp, tp, nelems);
10817
0
# endif
10818
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
10819
0
  return NC_NOERR;
10820
0
}
10821
#else
10822
int
10823
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
10824
{
10825
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10826
10827
 /* basic algorithm is:
10828
  *   - ensure sane alignment of output data
10829
  *   - copy (conversion happens automatically) input data
10830
  *     to output
10831
  *   - update tp to point at next unconverted input, and xpp to point
10832
  *     at next location for converted output
10833
  */
10834
  long i, j, ni;
10835
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10836
  ushort *xp;
10837
  int nrange = 0;         /* number of range errors */
10838
  int realign = 0;        /* "do we need to fix input data alignment?" */
10839
  long cxp = (long) *((char**)xpp);
10840
10841
  realign = (cxp & 7) % SIZEOF_USHORT;
10842
  /* sjl: manually stripmine so we can limit amount of
10843
   * vector work space reserved to LOOPCNT elements. Also
10844
   * makes vectorisation easy */
10845
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10846
    ni=Min(nelems-j,LOOPCNT);
10847
    if (realign) {
10848
      xp = tmp;
10849
    } else {
10850
      xp = (ushort *) *xpp;
10851
    }
10852
   /* copy the next block */
10853
#pragma cdir loopcnt=LOOPCNT
10854
#pragma cdir shortloop
10855
    for (i=0; i<ni; i++) {
10856
      /* the normal case: */
10857
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10858
     /* test for range errors (not always needed but do it anyway) */
10859
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10860
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10861
      nrange += tp[i] > X_USHORT_MAX ;
10862
    }
10863
   /* copy workspace back if necessary */
10864
    if (realign) {
10865
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10866
      xp = (ushort *) *xpp;
10867
    }
10868
   /* update xpp and tp */
10869
    xp += ni;
10870
    tp += ni;
10871
    *xpp = (void*)xp;
10872
  }
10873
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10874
10875
#else   /* not SX */
10876
10877
  char *xp = (char *) *xpp;
10878
  int status = NC_NOERR;
10879
10880
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10881
  {
10882
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
10883
    if (status == NC_NOERR) /* report the first encountered error */
10884
      status = lstatus;
10885
  }
10886
10887
  *xpp = (void *)xp;
10888
  return status;
10889
#endif
10890
}
10891
10892
#endif
10893
int
10894
ncx_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
10895
0
{
10896
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10897
10898
 /* basic algorithm is:
10899
  *   - ensure sane alignment of output data
10900
  *   - copy (conversion happens automatically) input data
10901
  *     to output
10902
  *   - update tp to point at next unconverted input, and xpp to point
10903
  *     at next location for converted output
10904
  */
10905
  long i, j, ni;
10906
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10907
  ushort *xp;
10908
  int nrange = 0;         /* number of range errors */
10909
  int realign = 0;        /* "do we need to fix input data alignment?" */
10910
  long cxp = (long) *((char**)xpp);
10911
10912
  realign = (cxp & 7) % SIZEOF_USHORT;
10913
  /* sjl: manually stripmine so we can limit amount of
10914
   * vector work space reserved to LOOPCNT elements. Also
10915
   * makes vectorisation easy */
10916
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10917
    ni=Min(nelems-j,LOOPCNT);
10918
    if (realign) {
10919
      xp = tmp;
10920
    } else {
10921
      xp = (ushort *) *xpp;
10922
    }
10923
   /* copy the next block */
10924
#pragma cdir loopcnt=LOOPCNT
10925
#pragma cdir shortloop
10926
    for (i=0; i<ni; i++) {
10927
      /* the normal case: */
10928
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10929
     /* test for range errors (not always needed but do it anyway) */
10930
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10931
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10932
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10933
    }
10934
   /* copy workspace back if necessary */
10935
    if (realign) {
10936
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10937
      xp = (ushort *) *xpp;
10938
    }
10939
   /* update xpp and tp */
10940
    xp += ni;
10941
    tp += ni;
10942
    *xpp = (void*)xp;
10943
  }
10944
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10945
10946
#else   /* not SX */
10947
10948
0
  char *xp = (char *) *xpp;
10949
0
  int status = NC_NOERR;
10950
10951
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10952
0
  {
10953
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
10954
0
    if (status == NC_NOERR) /* report the first encountered error */
10955
0
      status = lstatus;
10956
0
  }
10957
10958
0
  *xpp = (void *)xp;
10959
0
  return status;
10960
0
#endif
10961
0
}
10962
10963
int
10964
ncx_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
10965
0
{
10966
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10967
10968
 /* basic algorithm is:
10969
  *   - ensure sane alignment of output data
10970
  *   - copy (conversion happens automatically) input data
10971
  *     to output
10972
  *   - update tp to point at next unconverted input, and xpp to point
10973
  *     at next location for converted output
10974
  */
10975
  long i, j, ni;
10976
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10977
  ushort *xp;
10978
  int nrange = 0;         /* number of range errors */
10979
  int realign = 0;        /* "do we need to fix input data alignment?" */
10980
  long cxp = (long) *((char**)xpp);
10981
10982
  realign = (cxp & 7) % SIZEOF_USHORT;
10983
  /* sjl: manually stripmine so we can limit amount of
10984
   * vector work space reserved to LOOPCNT elements. Also
10985
   * makes vectorisation easy */
10986
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10987
    ni=Min(nelems-j,LOOPCNT);
10988
    if (realign) {
10989
      xp = tmp;
10990
    } else {
10991
      xp = (ushort *) *xpp;
10992
    }
10993
   /* copy the next block */
10994
#pragma cdir loopcnt=LOOPCNT
10995
#pragma cdir shortloop
10996
    for (i=0; i<ni; i++) {
10997
      /* the normal case: */
10998
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10999
     /* test for range errors (not always needed but do it anyway) */
11000
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11001
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11002
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11003
    }
11004
   /* copy workspace back if necessary */
11005
    if (realign) {
11006
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11007
      xp = (ushort *) *xpp;
11008
    }
11009
   /* update xpp and tp */
11010
    xp += ni;
11011
    tp += ni;
11012
    *xpp = (void*)xp;
11013
  }
11014
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11015
11016
#else   /* not SX */
11017
11018
0
  char *xp = (char *) *xpp;
11019
0
  int status = NC_NOERR;
11020
11021
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11022
0
  {
11023
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11024
0
    if (status == NC_NOERR) /* report the first encountered error */
11025
0
      status = lstatus;
11026
0
  }
11027
11028
0
  *xpp = (void *)xp;
11029
0
  return status;
11030
0
#endif
11031
0
}
11032
11033
int
11034
ncx_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11035
0
{
11036
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11037
11038
 /* basic algorithm is:
11039
  *   - ensure sane alignment of output data
11040
  *   - copy (conversion happens automatically) input data
11041
  *     to output
11042
  *   - update tp to point at next unconverted input, and xpp to point
11043
  *     at next location for converted output
11044
  */
11045
  long i, j, ni;
11046
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11047
  ushort *xp;
11048
  int nrange = 0;         /* number of range errors */
11049
  int realign = 0;        /* "do we need to fix input data alignment?" */
11050
  long cxp = (long) *((char**)xpp);
11051
11052
  realign = (cxp & 7) % SIZEOF_USHORT;
11053
  /* sjl: manually stripmine so we can limit amount of
11054
   * vector work space reserved to LOOPCNT elements. Also
11055
   * makes vectorisation easy */
11056
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11057
    ni=Min(nelems-j,LOOPCNT);
11058
    if (realign) {
11059
      xp = tmp;
11060
    } else {
11061
      xp = (ushort *) *xpp;
11062
    }
11063
   /* copy the next block */
11064
#pragma cdir loopcnt=LOOPCNT
11065
#pragma cdir shortloop
11066
    for (i=0; i<ni; i++) {
11067
      /* the normal case: */
11068
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11069
     /* test for range errors (not always needed but do it anyway) */
11070
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11071
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11072
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11073
    }
11074
   /* copy workspace back if necessary */
11075
    if (realign) {
11076
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11077
      xp = (ushort *) *xpp;
11078
    }
11079
   /* update xpp and tp */
11080
    xp += ni;
11081
    tp += ni;
11082
    *xpp = (void*)xp;
11083
  }
11084
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11085
11086
#else   /* not SX */
11087
11088
0
  char *xp = (char *) *xpp;
11089
0
  int status = NC_NOERR;
11090
11091
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11092
0
  {
11093
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11094
0
    if (status == NC_NOERR) /* report the first encountered error */
11095
0
      status = lstatus;
11096
0
  }
11097
11098
0
  *xpp = (void *)xp;
11099
0
  return status;
11100
0
#endif
11101
0
}
11102
11103
int
11104
ncx_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11105
0
{
11106
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11107
11108
 /* basic algorithm is:
11109
  *   - ensure sane alignment of output data
11110
  *   - copy (conversion happens automatically) input data
11111
  *     to output
11112
  *   - update tp to point at next unconverted input, and xpp to point
11113
  *     at next location for converted output
11114
  */
11115
  long i, j, ni;
11116
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11117
  ushort *xp;
11118
  int nrange = 0;         /* number of range errors */
11119
  int realign = 0;        /* "do we need to fix input data alignment?" */
11120
  long cxp = (long) *((char**)xpp);
11121
11122
  realign = (cxp & 7) % SIZEOF_USHORT;
11123
  /* sjl: manually stripmine so we can limit amount of
11124
   * vector work space reserved to LOOPCNT elements. Also
11125
   * makes vectorisation easy */
11126
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11127
    ni=Min(nelems-j,LOOPCNT);
11128
    if (realign) {
11129
      xp = tmp;
11130
    } else {
11131
      xp = (ushort *) *xpp;
11132
    }
11133
   /* copy the next block */
11134
#pragma cdir loopcnt=LOOPCNT
11135
#pragma cdir shortloop
11136
    for (i=0; i<ni; i++) {
11137
      /* the normal case: */
11138
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11139
     /* test for range errors (not always needed but do it anyway) */
11140
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11141
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11142
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11143
    }
11144
   /* copy workspace back if necessary */
11145
    if (realign) {
11146
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11147
      xp = (ushort *) *xpp;
11148
    }
11149
   /* update xpp and tp */
11150
    xp += ni;
11151
    tp += ni;
11152
    *xpp = (void*)xp;
11153
  }
11154
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11155
11156
#else   /* not SX */
11157
11158
0
  char *xp = (char *) *xpp;
11159
0
  int status = NC_NOERR;
11160
11161
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11162
0
  {
11163
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11164
0
    if (status == NC_NOERR) /* report the first encountered error */
11165
0
      status = lstatus;
11166
0
  }
11167
11168
0
  *xpp = (void *)xp;
11169
0
  return status;
11170
0
#endif
11171
0
}
11172
11173
int
11174
ncx_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11175
0
{
11176
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11177
11178
 /* basic algorithm is:
11179
  *   - ensure sane alignment of output data
11180
  *   - copy (conversion happens automatically) input data
11181
  *     to output
11182
  *   - update tp to point at next unconverted input, and xpp to point
11183
  *     at next location for converted output
11184
  */
11185
  long i, j, ni;
11186
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11187
  ushort *xp;
11188
  int nrange = 0;         /* number of range errors */
11189
  int realign = 0;        /* "do we need to fix input data alignment?" */
11190
  long cxp = (long) *((char**)xpp);
11191
11192
  realign = (cxp & 7) % SIZEOF_USHORT;
11193
  /* sjl: manually stripmine so we can limit amount of
11194
   * vector work space reserved to LOOPCNT elements. Also
11195
   * makes vectorisation easy */
11196
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11197
    ni=Min(nelems-j,LOOPCNT);
11198
    if (realign) {
11199
      xp = tmp;
11200
    } else {
11201
      xp = (ushort *) *xpp;
11202
    }
11203
   /* copy the next block */
11204
#pragma cdir loopcnt=LOOPCNT
11205
#pragma cdir shortloop
11206
    for (i=0; i<ni; i++) {
11207
      /* the normal case: */
11208
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11209
     /* test for range errors (not always needed but do it anyway) */
11210
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11211
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11212
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11213
    }
11214
   /* copy workspace back if necessary */
11215
    if (realign) {
11216
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11217
      xp = (ushort *) *xpp;
11218
    }
11219
   /* update xpp and tp */
11220
    xp += ni;
11221
    tp += ni;
11222
    *xpp = (void*)xp;
11223
  }
11224
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11225
11226
#else   /* not SX */
11227
11228
0
  char *xp = (char *) *xpp;
11229
0
  int status = NC_NOERR;
11230
11231
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11232
0
  {
11233
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11234
0
    if (status == NC_NOERR) /* report the first encountered error */
11235
0
      status = lstatus;
11236
0
  }
11237
11238
0
  *xpp = (void *)xp;
11239
0
  return status;
11240
0
#endif
11241
0
}
11242
11243
int
11244
ncx_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11245
0
{
11246
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11247
11248
 /* basic algorithm is:
11249
  *   - ensure sane alignment of output data
11250
  *   - copy (conversion happens automatically) input data
11251
  *     to output
11252
  *   - update tp to point at next unconverted input, and xpp to point
11253
  *     at next location for converted output
11254
  */
11255
  long i, j, ni;
11256
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11257
  ushort *xp;
11258
  int nrange = 0;         /* number of range errors */
11259
  int realign = 0;        /* "do we need to fix input data alignment?" */
11260
  long cxp = (long) *((char**)xpp);
11261
11262
  realign = (cxp & 7) % SIZEOF_USHORT;
11263
  /* sjl: manually stripmine so we can limit amount of
11264
   * vector work space reserved to LOOPCNT elements. Also
11265
   * makes vectorisation easy */
11266
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11267
    ni=Min(nelems-j,LOOPCNT);
11268
    if (realign) {
11269
      xp = tmp;
11270
    } else {
11271
      xp = (ushort *) *xpp;
11272
    }
11273
   /* copy the next block */
11274
#pragma cdir loopcnt=LOOPCNT
11275
#pragma cdir shortloop
11276
    for (i=0; i<ni; i++) {
11277
      /* the normal case: */
11278
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11279
     /* test for range errors (not always needed but do it anyway) */
11280
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11281
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11282
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11283
    }
11284
   /* copy workspace back if necessary */
11285
    if (realign) {
11286
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11287
      xp = (ushort *) *xpp;
11288
    }
11289
   /* update xpp and tp */
11290
    xp += ni;
11291
    tp += ni;
11292
    *xpp = (void*)xp;
11293
  }
11294
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11295
11296
#else   /* not SX */
11297
11298
0
  char *xp = (char *) *xpp;
11299
0
  int status = NC_NOERR;
11300
11301
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11302
0
  {
11303
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11304
0
    if (status == NC_NOERR) /* report the first encountered error */
11305
0
      status = lstatus;
11306
0
  }
11307
11308
0
  *xpp = (void *)xp;
11309
0
  return status;
11310
0
#endif
11311
0
}
11312
11313
int
11314
ncx_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11315
0
{
11316
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11317
11318
 /* basic algorithm is:
11319
  *   - ensure sane alignment of output data
11320
  *   - copy (conversion happens automatically) input data
11321
  *     to output
11322
  *   - update tp to point at next unconverted input, and xpp to point
11323
  *     at next location for converted output
11324
  */
11325
  long i, j, ni;
11326
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11327
  ushort *xp;
11328
  int nrange = 0;         /* number of range errors */
11329
  int realign = 0;        /* "do we need to fix input data alignment?" */
11330
  long cxp = (long) *((char**)xpp);
11331
11332
  realign = (cxp & 7) % SIZEOF_USHORT;
11333
  /* sjl: manually stripmine so we can limit amount of
11334
   * vector work space reserved to LOOPCNT elements. Also
11335
   * makes vectorisation easy */
11336
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11337
    ni=Min(nelems-j,LOOPCNT);
11338
    if (realign) {
11339
      xp = tmp;
11340
    } else {
11341
      xp = (ushort *) *xpp;
11342
    }
11343
   /* copy the next block */
11344
#pragma cdir loopcnt=LOOPCNT
11345
#pragma cdir shortloop
11346
    for (i=0; i<ni; i++) {
11347
      /* the normal case: */
11348
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11349
     /* test for range errors (not always needed but do it anyway) */
11350
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11351
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11352
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11353
    }
11354
   /* copy workspace back if necessary */
11355
    if (realign) {
11356
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11357
      xp = (ushort *) *xpp;
11358
    }
11359
   /* update xpp and tp */
11360
    xp += ni;
11361
    tp += ni;
11362
    *xpp = (void*)xp;
11363
  }
11364
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11365
11366
#else   /* not SX */
11367
11368
0
  char *xp = (char *) *xpp;
11369
0
  int status = NC_NOERR;
11370
11371
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11372
0
  {
11373
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11374
0
    if (status == NC_NOERR) /* report the first encountered error */
11375
0
      status = lstatus;
11376
0
  }
11377
11378
0
  *xpp = (void *)xp;
11379
0
  return status;
11380
0
#endif
11381
0
}
11382
11383
int
11384
ncx_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11385
0
{
11386
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11387
11388
 /* basic algorithm is:
11389
  *   - ensure sane alignment of output data
11390
  *   - copy (conversion happens automatically) input data
11391
  *     to output
11392
  *   - update tp to point at next unconverted input, and xpp to point
11393
  *     at next location for converted output
11394
  */
11395
  long i, j, ni;
11396
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11397
  ushort *xp;
11398
  int nrange = 0;         /* number of range errors */
11399
  int realign = 0;        /* "do we need to fix input data alignment?" */
11400
  long cxp = (long) *((char**)xpp);
11401
11402
  realign = (cxp & 7) % SIZEOF_USHORT;
11403
  /* sjl: manually stripmine so we can limit amount of
11404
   * vector work space reserved to LOOPCNT elements. Also
11405
   * makes vectorisation easy */
11406
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11407
    ni=Min(nelems-j,LOOPCNT);
11408
    if (realign) {
11409
      xp = tmp;
11410
    } else {
11411
      xp = (ushort *) *xpp;
11412
    }
11413
   /* copy the next block */
11414
#pragma cdir loopcnt=LOOPCNT
11415
#pragma cdir shortloop
11416
    for (i=0; i<ni; i++) {
11417
      /* the normal case: */
11418
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11419
     /* test for range errors (not always needed but do it anyway) */
11420
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11421
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11422
      nrange += tp[i] > X_USHORT_MAX ;
11423
    }
11424
   /* copy workspace back if necessary */
11425
    if (realign) {
11426
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11427
      xp = (ushort *) *xpp;
11428
    }
11429
   /* update xpp and tp */
11430
    xp += ni;
11431
    tp += ni;
11432
    *xpp = (void*)xp;
11433
  }
11434
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11435
11436
#else   /* not SX */
11437
11438
0
  char *xp = (char *) *xpp;
11439
0
  int status = NC_NOERR;
11440
11441
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11442
0
  {
11443
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11444
0
    if (status == NC_NOERR) /* report the first encountered error */
11445
0
      status = lstatus;
11446
0
  }
11447
11448
0
  *xpp = (void *)xp;
11449
0
  return status;
11450
0
#endif
11451
0
}
11452
11453
int
11454
ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11455
0
{
11456
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11457
11458
 /* basic algorithm is:
11459
  *   - ensure sane alignment of output data
11460
  *   - copy (conversion happens automatically) input data
11461
  *     to output
11462
  *   - update tp to point at next unconverted input, and xpp to point
11463
  *     at next location for converted output
11464
  */
11465
  long i, j, ni;
11466
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11467
  ushort *xp;
11468
  int nrange = 0;         /* number of range errors */
11469
  int realign = 0;        /* "do we need to fix input data alignment?" */
11470
  long cxp = (long) *((char**)xpp);
11471
11472
  realign = (cxp & 7) % SIZEOF_USHORT;
11473
  /* sjl: manually stripmine so we can limit amount of
11474
   * vector work space reserved to LOOPCNT elements. Also
11475
   * makes vectorisation easy */
11476
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11477
    ni=Min(nelems-j,LOOPCNT);
11478
    if (realign) {
11479
      xp = tmp;
11480
    } else {
11481
      xp = (ushort *) *xpp;
11482
    }
11483
   /* copy the next block */
11484
#pragma cdir loopcnt=LOOPCNT
11485
#pragma cdir shortloop
11486
    for (i=0; i<ni; i++) {
11487
      /* the normal case: */
11488
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11489
     /* test for range errors (not always needed but do it anyway) */
11490
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11491
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11492
      nrange += tp[i] > X_USHORT_MAX ;
11493
    }
11494
   /* copy workspace back if necessary */
11495
    if (realign) {
11496
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11497
      xp = (ushort *) *xpp;
11498
    }
11499
   /* update xpp and tp */
11500
    xp += ni;
11501
    tp += ni;
11502
    *xpp = (void*)xp;
11503
  }
11504
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11505
11506
#else   /* not SX */
11507
11508
0
  char *xp = (char *) *xpp;
11509
0
  int status = NC_NOERR;
11510
11511
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11512
0
  {
11513
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11514
0
    if (status == NC_NOERR) /* report the first encountered error */
11515
0
      status = lstatus;
11516
0
  }
11517
11518
0
  *xpp = (void *)xp;
11519
0
  return status;
11520
0
#endif
11521
0
}
11522
11523
int
11524
ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11525
0
{
11526
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11527
11528
 /* basic algorithm is:
11529
  *   - ensure sane alignment of output data
11530
  *   - copy (conversion happens automatically) input data
11531
  *     to output
11532
  *   - update tp to point at next unconverted input, and xpp to point
11533
  *     at next location for converted output
11534
  */
11535
  long i, j, ni;
11536
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11537
  ushort *xp;
11538
  int nrange = 0;         /* number of range errors */
11539
  int realign = 0;        /* "do we need to fix input data alignment?" */
11540
  long cxp = (long) *((char**)xpp);
11541
11542
  realign = (cxp & 7) % SIZEOF_USHORT;
11543
  /* sjl: manually stripmine so we can limit amount of
11544
   * vector work space reserved to LOOPCNT elements. Also
11545
   * makes vectorisation easy */
11546
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11547
    ni=Min(nelems-j,LOOPCNT);
11548
    if (realign) {
11549
      xp = tmp;
11550
    } else {
11551
      xp = (ushort *) *xpp;
11552
    }
11553
   /* copy the next block */
11554
#pragma cdir loopcnt=LOOPCNT
11555
#pragma cdir shortloop
11556
    for (i=0; i<ni; i++) {
11557
      /* the normal case: */
11558
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11559
     /* test for range errors (not always needed but do it anyway) */
11560
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11561
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11562
      nrange += tp[i] > X_USHORT_MAX ;
11563
    }
11564
   /* copy workspace back if necessary */
11565
    if (realign) {
11566
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11567
      xp = (ushort *) *xpp;
11568
    }
11569
   /* update xpp and tp */
11570
    xp += ni;
11571
    tp += ni;
11572
    *xpp = (void*)xp;
11573
  }
11574
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11575
11576
#else   /* not SX */
11577
11578
0
  char *xp = (char *) *xpp;
11579
0
  int status = NC_NOERR;
11580
11581
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11582
0
  {
11583
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11584
0
    if (status == NC_NOERR) /* report the first encountered error */
11585
0
      status = lstatus;
11586
0
  }
11587
11588
0
  *xpp = (void *)xp;
11589
0
  return status;
11590
0
#endif
11591
0
}
11592
11593
11594
int
11595
ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
11596
0
{
11597
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11598
11599
0
  char *xp = (char *) *xpp;
11600
0
  int status = NC_NOERR;
11601
11602
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11603
0
  {
11604
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
11605
0
    if (status == NC_NOERR) /* report the first encountered error */
11606
0
      status = lstatus;
11607
0
  }
11608
11609
0
  if (rndup != 0)
11610
0
  {
11611
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11612
0
    xp += X_SIZEOF_USHORT;
11613
0
  }
11614
11615
0
  *xpp = (void *)xp;
11616
0
  return status;
11617
0
}
11618
11619
int
11620
ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11621
0
{
11622
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11623
11624
0
  char *xp = (char *) *xpp;
11625
0
  int status = NC_NOERR;
11626
11627
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11628
0
  {
11629
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11630
0
    if (status == NC_NOERR) /* report the first encountered error */
11631
0
      status = lstatus;
11632
0
  }
11633
11634
0
  if (rndup != 0)
11635
0
  {
11636
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11637
0
    xp += X_SIZEOF_USHORT;
11638
0
  }
11639
11640
0
  *xpp = (void *)xp;
11641
0
  return status;
11642
0
}
11643
11644
int
11645
ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
11646
0
{
11647
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11648
11649
0
  char *xp = (char *) *xpp;
11650
0
  int status = NC_NOERR;
11651
11652
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11653
0
  {
11654
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11655
0
    if (status == NC_NOERR) /* report the first encountered error */
11656
0
      status = lstatus;
11657
0
  }
11658
11659
0
  if (rndup != 0)
11660
0
  {
11661
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11662
0
    xp += X_SIZEOF_USHORT;
11663
0
  }
11664
11665
0
  *xpp = (void *)xp;
11666
0
  return status;
11667
0
}
11668
11669
int
11670
ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11671
0
{
11672
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11673
11674
0
  char *xp = (char *) *xpp;
11675
0
  int status = NC_NOERR;
11676
11677
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11678
0
  {
11679
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11680
0
    if (status == NC_NOERR) /* report the first encountered error */
11681
0
      status = lstatus;
11682
0
  }
11683
11684
0
  if (rndup != 0)
11685
0
  {
11686
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11687
0
    xp += X_SIZEOF_USHORT;
11688
0
  }
11689
11690
0
  *xpp = (void *)xp;
11691
0
  return status;
11692
0
}
11693
11694
int
11695
ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11696
0
{
11697
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11698
11699
0
  char *xp = (char *) *xpp;
11700
0
  int status = NC_NOERR;
11701
11702
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11703
0
  {
11704
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11705
0
    if (status == NC_NOERR) /* report the first encountered error */
11706
0
      status = lstatus;
11707
0
  }
11708
11709
0
  if (rndup != 0)
11710
0
  {
11711
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11712
0
    xp += X_SIZEOF_USHORT;
11713
0
  }
11714
11715
0
  *xpp = (void *)xp;
11716
0
  return status;
11717
0
}
11718
11719
int
11720
ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11721
0
{
11722
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11723
11724
0
  char *xp = (char *) *xpp;
11725
0
  int status = NC_NOERR;
11726
11727
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11728
0
  {
11729
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11730
0
    if (status == NC_NOERR) /* report the first encountered error */
11731
0
      status = lstatus;
11732
0
  }
11733
11734
0
  if (rndup != 0)
11735
0
  {
11736
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11737
0
    xp += X_SIZEOF_USHORT;
11738
0
  }
11739
11740
0
  *xpp = (void *)xp;
11741
0
  return status;
11742
0
}
11743
11744
int
11745
ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11746
0
{
11747
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11748
11749
0
  char *xp = (char *) *xpp;
11750
0
  int status = NC_NOERR;
11751
11752
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11753
0
  {
11754
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11755
0
    if (status == NC_NOERR) /* report the first encountered error */
11756
0
      status = lstatus;
11757
0
  }
11758
11759
0
  if (rndup != 0)
11760
0
  {
11761
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11762
0
    xp += X_SIZEOF_USHORT;
11763
0
  }
11764
11765
0
  *xpp = (void *)xp;
11766
0
  return status;
11767
0
}
11768
11769
int
11770
ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11771
0
{
11772
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11773
11774
0
  char *xp = (char *) *xpp;
11775
0
  int status = NC_NOERR;
11776
11777
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11778
0
  {
11779
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11780
0
    if (status == NC_NOERR) /* report the first encountered error */
11781
0
      status = lstatus;
11782
0
  }
11783
11784
0
  if (rndup != 0)
11785
0
  {
11786
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11787
0
    xp += X_SIZEOF_USHORT;
11788
0
  }
11789
11790
0
  *xpp = (void *)xp;
11791
0
  return status;
11792
0
}
11793
11794
int
11795
ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11796
0
{
11797
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11798
11799
0
  char *xp = (char *) *xpp;
11800
0
  int status = NC_NOERR;
11801
11802
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11803
0
  {
11804
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11805
0
    if (status == NC_NOERR) /* report the first encountered error */
11806
0
      status = lstatus;
11807
0
  }
11808
11809
0
  if (rndup != 0)
11810
0
  {
11811
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11812
0
    xp += X_SIZEOF_USHORT;
11813
0
  }
11814
11815
0
  *xpp = (void *)xp;
11816
0
  return status;
11817
0
}
11818
11819
int
11820
ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11821
0
{
11822
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11823
11824
0
  char *xp = (char *) *xpp;
11825
0
  int status = NC_NOERR;
11826
11827
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11828
0
  {
11829
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11830
0
    if (status == NC_NOERR) /* report the first encountered error */
11831
0
      status = lstatus;
11832
0
  }
11833
11834
0
  if (rndup != 0)
11835
0
  {
11836
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11837
0
    xp += X_SIZEOF_USHORT;
11838
0
  }
11839
11840
0
  *xpp = (void *)xp;
11841
0
  return status;
11842
0
}
11843
11844
int
11845
ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
11846
0
{
11847
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11848
11849
0
  char *xp = (char *) *xpp;
11850
0
  int status = NC_NOERR;
11851
11852
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11853
0
  {
11854
0
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
11855
0
    if (status == NC_NOERR) /* report the first encountered error */
11856
0
      status = lstatus;
11857
0
  }
11858
11859
0
  if (rndup != 0)
11860
0
  {
11861
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11862
0
    xp += X_SIZEOF_USHORT;
11863
0
  }
11864
11865
0
  *xpp = (void *)xp;
11866
0
  return status;
11867
0
}
11868
11869
11870
11871
/* int -----------------------------------------------------------------------*/
11872
11873
#if X_SIZEOF_INT == SIZEOF_INT
11874
/* optimized version */
11875
int
11876
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11877
131k
{
11878
#ifdef WORDS_BIGENDIAN
11879
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
11880
# else
11881
131k
  swapn4b(tp, *xpp, nelems);
11882
131k
# endif
11883
131k
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
11884
131k
  return NC_NOERR;
11885
131k
}
11886
#else
11887
int
11888
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11889
{
11890
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11891
11892
 /* basic algorithm is:
11893
  *   - ensure sane alignment of input data
11894
  *   - copy (conversion happens automatically) input data
11895
  *     to output
11896
  *   - update xpp to point at next unconverted input, and tp to point
11897
  *     at next location for converted output
11898
  */
11899
  long i, j, ni;
11900
  int tmp[LOOPCNT];        /* in case input is misaligned */
11901
  int *xp;
11902
  int nrange = 0;         /* number of range errors */
11903
  int realign = 0;        /* "do we need to fix input data alignment?" */
11904
  long cxp = (long) *((char**)xpp);
11905
11906
  realign = (cxp & 7) % SIZEOF_INT;
11907
  /* sjl: manually stripmine so we can limit amount of
11908
   * vector work space reserved to LOOPCNT elements. Also
11909
   * makes vectorisation easy */
11910
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11911
    ni=Min(nelems-j,LOOPCNT);
11912
    if (realign) {
11913
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11914
      xp = tmp;
11915
    } else {
11916
      xp = (int *) *xpp;
11917
    }
11918
   /* copy the next block */
11919
#pragma cdir loopcnt=LOOPCNT
11920
#pragma cdir shortloop
11921
    for (i=0; i<ni; i++) {
11922
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
11923
     /* test for range errors (not always needed but do it anyway) */
11924
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11925
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11926
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
11927
    }
11928
   /* update xpp and tp */
11929
    if (realign) xp = (int *) *xpp;
11930
    xp += ni;
11931
    tp += ni;
11932
    *xpp = (void*)xp;
11933
  }
11934
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11935
11936
#else   /* not SX */
11937
  const char *xp = (const char *) *xpp;
11938
  int status = NC_NOERR;
11939
11940
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11941
  {
11942
    const int lstatus = ncx_get_int_int(xp, tp);
11943
    if (status == NC_NOERR) /* report the first encountered error */
11944
      status = lstatus;
11945
  }
11946
11947
  *xpp = (const void *)xp;
11948
  return status;
11949
#endif
11950
}
11951
11952
#endif
11953
int
11954
ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
11955
0
{
11956
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11957
11958
 /* basic algorithm is:
11959
  *   - ensure sane alignment of input data
11960
  *   - copy (conversion happens automatically) input data
11961
  *     to output
11962
  *   - update xpp to point at next unconverted input, and tp to point
11963
  *     at next location for converted output
11964
  */
11965
  long i, j, ni;
11966
  int tmp[LOOPCNT];        /* in case input is misaligned */
11967
  int *xp;
11968
  int nrange = 0;         /* number of range errors */
11969
  int realign = 0;        /* "do we need to fix input data alignment?" */
11970
  long cxp = (long) *((char**)xpp);
11971
11972
  realign = (cxp & 7) % SIZEOF_INT;
11973
  /* sjl: manually stripmine so we can limit amount of
11974
   * vector work space reserved to LOOPCNT elements. Also
11975
   * makes vectorisation easy */
11976
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11977
    ni=Min(nelems-j,LOOPCNT);
11978
    if (realign) {
11979
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11980
      xp = tmp;
11981
    } else {
11982
      xp = (int *) *xpp;
11983
    }
11984
   /* copy the next block */
11985
#pragma cdir loopcnt=LOOPCNT
11986
#pragma cdir shortloop
11987
    for (i=0; i<ni; i++) {
11988
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
11989
     /* test for range errors (not always needed but do it anyway) */
11990
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11991
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11992
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
11993
    }
11994
   /* update xpp and tp */
11995
    if (realign) xp = (int *) *xpp;
11996
    xp += ni;
11997
    tp += ni;
11998
    *xpp = (void*)xp;
11999
  }
12000
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12001
12002
#else   /* not SX */
12003
0
  const char *xp = (const char *) *xpp;
12004
0
  int status = NC_NOERR;
12005
12006
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12007
0
  {
12008
0
    const int lstatus = ncx_get_int_schar(xp, tp);
12009
0
    if (status == NC_NOERR) /* report the first encountered error */
12010
0
      status = lstatus;
12011
0
  }
12012
12013
0
  *xpp = (const void *)xp;
12014
0
  return status;
12015
0
#endif
12016
0
}
12017
12018
int
12019
ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
12020
0
{
12021
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12022
12023
 /* basic algorithm is:
12024
  *   - ensure sane alignment of input data
12025
  *   - copy (conversion happens automatically) input data
12026
  *     to output
12027
  *   - update xpp to point at next unconverted input, and tp to point
12028
  *     at next location for converted output
12029
  */
12030
  long i, j, ni;
12031
  int tmp[LOOPCNT];        /* in case input is misaligned */
12032
  int *xp;
12033
  int nrange = 0;         /* number of range errors */
12034
  int realign = 0;        /* "do we need to fix input data alignment?" */
12035
  long cxp = (long) *((char**)xpp);
12036
12037
  realign = (cxp & 7) % SIZEOF_INT;
12038
  /* sjl: manually stripmine so we can limit amount of
12039
   * vector work space reserved to LOOPCNT elements. Also
12040
   * makes vectorisation easy */
12041
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12042
    ni=Min(nelems-j,LOOPCNT);
12043
    if (realign) {
12044
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12045
      xp = tmp;
12046
    } else {
12047
      xp = (int *) *xpp;
12048
    }
12049
   /* copy the next block */
12050
#pragma cdir loopcnt=LOOPCNT
12051
#pragma cdir shortloop
12052
    for (i=0; i<ni; i++) {
12053
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
12054
     /* test for range errors (not always needed but do it anyway) */
12055
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12056
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12057
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
12058
    }
12059
   /* update xpp and tp */
12060
    if (realign) xp = (int *) *xpp;
12061
    xp += ni;
12062
    tp += ni;
12063
    *xpp = (void*)xp;
12064
  }
12065
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12066
12067
#else   /* not SX */
12068
0
  const char *xp = (const char *) *xpp;
12069
0
  int status = NC_NOERR;
12070
12071
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12072
0
  {
12073
0
    const int lstatus = ncx_get_int_short(xp, tp);
12074
0
    if (status == NC_NOERR) /* report the first encountered error */
12075
0
      status = lstatus;
12076
0
  }
12077
12078
0
  *xpp = (const void *)xp;
12079
0
  return status;
12080
0
#endif
12081
0
}
12082
12083
int
12084
ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
12085
0
{
12086
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12087
12088
 /* basic algorithm is:
12089
  *   - ensure sane alignment of input data
12090
  *   - copy (conversion happens automatically) input data
12091
  *     to output
12092
  *   - update xpp to point at next unconverted input, and tp to point
12093
  *     at next location for converted output
12094
  */
12095
  long i, j, ni;
12096
  int tmp[LOOPCNT];        /* in case input is misaligned */
12097
  int *xp;
12098
  int nrange = 0;         /* number of range errors */
12099
  int realign = 0;        /* "do we need to fix input data alignment?" */
12100
  long cxp = (long) *((char**)xpp);
12101
12102
  realign = (cxp & 7) % SIZEOF_INT;
12103
  /* sjl: manually stripmine so we can limit amount of
12104
   * vector work space reserved to LOOPCNT elements. Also
12105
   * makes vectorisation easy */
12106
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12107
    ni=Min(nelems-j,LOOPCNT);
12108
    if (realign) {
12109
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12110
      xp = tmp;
12111
    } else {
12112
      xp = (int *) *xpp;
12113
    }
12114
   /* copy the next block */
12115
#pragma cdir loopcnt=LOOPCNT
12116
#pragma cdir shortloop
12117
    for (i=0; i<ni; i++) {
12118
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
12119
     /* test for range errors (not always needed but do it anyway) */
12120
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12121
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12122
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
12123
    }
12124
   /* update xpp and tp */
12125
    if (realign) xp = (int *) *xpp;
12126
    xp += ni;
12127
    tp += ni;
12128
    *xpp = (void*)xp;
12129
  }
12130
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12131
12132
#else   /* not SX */
12133
0
  const char *xp = (const char *) *xpp;
12134
0
  int status = NC_NOERR;
12135
12136
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12137
0
  {
12138
0
    const int lstatus = ncx_get_int_long(xp, tp);
12139
0
    if (status == NC_NOERR) /* report the first encountered error */
12140
0
      status = lstatus;
12141
0
  }
12142
12143
0
  *xpp = (const void *)xp;
12144
0
  return status;
12145
0
#endif
12146
0
}
12147
12148
int
12149
ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
12150
0
{
12151
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12152
12153
 /* basic algorithm is:
12154
  *   - ensure sane alignment of input data
12155
  *   - copy (conversion happens automatically) input data
12156
  *     to output
12157
  *   - update xpp to point at next unconverted input, and tp to point
12158
  *     at next location for converted output
12159
  */
12160
  long i, j, ni;
12161
  int tmp[LOOPCNT];        /* in case input is misaligned */
12162
  int *xp;
12163
  int nrange = 0;         /* number of range errors */
12164
  int realign = 0;        /* "do we need to fix input data alignment?" */
12165
  long cxp = (long) *((char**)xpp);
12166
12167
  realign = (cxp & 7) % SIZEOF_INT;
12168
  /* sjl: manually stripmine so we can limit amount of
12169
   * vector work space reserved to LOOPCNT elements. Also
12170
   * makes vectorisation easy */
12171
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12172
    ni=Min(nelems-j,LOOPCNT);
12173
    if (realign) {
12174
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12175
      xp = tmp;
12176
    } else {
12177
      xp = (int *) *xpp;
12178
    }
12179
   /* copy the next block */
12180
#pragma cdir loopcnt=LOOPCNT
12181
#pragma cdir shortloop
12182
    for (i=0; i<ni; i++) {
12183
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
12184
     /* test for range errors (not always needed but do it anyway) */
12185
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12186
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12187
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
12188
    }
12189
   /* update xpp and tp */
12190
    if (realign) xp = (int *) *xpp;
12191
    xp += ni;
12192
    tp += ni;
12193
    *xpp = (void*)xp;
12194
  }
12195
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12196
12197
#else   /* not SX */
12198
0
  const char *xp = (const char *) *xpp;
12199
0
  int status = NC_NOERR;
12200
12201
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12202
0
  {
12203
0
    const int lstatus = ncx_get_int_float(xp, tp);
12204
0
    if (status == NC_NOERR) /* report the first encountered error */
12205
0
      status = lstatus;
12206
0
  }
12207
12208
0
  *xpp = (const void *)xp;
12209
0
  return status;
12210
0
#endif
12211
0
}
12212
12213
int
12214
ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
12215
0
{
12216
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12217
12218
 /* basic algorithm is:
12219
  *   - ensure sane alignment of input data
12220
  *   - copy (conversion happens automatically) input data
12221
  *     to output
12222
  *   - update xpp to point at next unconverted input, and tp to point
12223
  *     at next location for converted output
12224
  */
12225
  long i, j, ni;
12226
  int tmp[LOOPCNT];        /* in case input is misaligned */
12227
  int *xp;
12228
  int nrange = 0;         /* number of range errors */
12229
  int realign = 0;        /* "do we need to fix input data alignment?" */
12230
  long cxp = (long) *((char**)xpp);
12231
12232
  realign = (cxp & 7) % SIZEOF_INT;
12233
  /* sjl: manually stripmine so we can limit amount of
12234
   * vector work space reserved to LOOPCNT elements. Also
12235
   * makes vectorisation easy */
12236
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12237
    ni=Min(nelems-j,LOOPCNT);
12238
    if (realign) {
12239
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12240
      xp = tmp;
12241
    } else {
12242
      xp = (int *) *xpp;
12243
    }
12244
   /* copy the next block */
12245
#pragma cdir loopcnt=LOOPCNT
12246
#pragma cdir shortloop
12247
    for (i=0; i<ni; i++) {
12248
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
12249
     /* test for range errors (not always needed but do it anyway) */
12250
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12251
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12252
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
12253
    }
12254
   /* update xpp and tp */
12255
    if (realign) xp = (int *) *xpp;
12256
    xp += ni;
12257
    tp += ni;
12258
    *xpp = (void*)xp;
12259
  }
12260
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12261
12262
#else   /* not SX */
12263
0
  const char *xp = (const char *) *xpp;
12264
0
  int status = NC_NOERR;
12265
12266
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12267
0
  {
12268
0
    const int lstatus = ncx_get_int_double(xp, tp);
12269
0
    if (status == NC_NOERR) /* report the first encountered error */
12270
0
      status = lstatus;
12271
0
  }
12272
12273
0
  *xpp = (const void *)xp;
12274
0
  return status;
12275
0
#endif
12276
0
}
12277
12278
int
12279
ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp)
12280
0
{
12281
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12282
12283
 /* basic algorithm is:
12284
  *   - ensure sane alignment of input data
12285
  *   - copy (conversion happens automatically) input data
12286
  *     to output
12287
  *   - update xpp to point at next unconverted input, and tp to point
12288
  *     at next location for converted output
12289
  */
12290
  long i, j, ni;
12291
  int tmp[LOOPCNT];        /* in case input is misaligned */
12292
  int *xp;
12293
  int nrange = 0;         /* number of range errors */
12294
  int realign = 0;        /* "do we need to fix input data alignment?" */
12295
  long cxp = (long) *((char**)xpp);
12296
12297
  realign = (cxp & 7) % SIZEOF_INT;
12298
  /* sjl: manually stripmine so we can limit amount of
12299
   * vector work space reserved to LOOPCNT elements. Also
12300
   * makes vectorisation easy */
12301
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12302
    ni=Min(nelems-j,LOOPCNT);
12303
    if (realign) {
12304
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12305
      xp = tmp;
12306
    } else {
12307
      xp = (int *) *xpp;
12308
    }
12309
   /* copy the next block */
12310
#pragma cdir loopcnt=LOOPCNT
12311
#pragma cdir shortloop
12312
    for (i=0; i<ni; i++) {
12313
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
12314
     /* test for range errors (not always needed but do it anyway) */
12315
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12316
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12317
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
12318
    }
12319
   /* update xpp and tp */
12320
    if (realign) xp = (int *) *xpp;
12321
    xp += ni;
12322
    tp += ni;
12323
    *xpp = (void*)xp;
12324
  }
12325
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12326
12327
#else   /* not SX */
12328
0
  const char *xp = (const char *) *xpp;
12329
0
  int status = NC_NOERR;
12330
12331
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12332
0
  {
12333
0
    const int lstatus = ncx_get_int_longlong(xp, tp);
12334
0
    if (status == NC_NOERR) /* report the first encountered error */
12335
0
      status = lstatus;
12336
0
  }
12337
12338
0
  *xpp = (const void *)xp;
12339
0
  return status;
12340
0
#endif
12341
0
}
12342
12343
int
12344
ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
12345
0
{
12346
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12347
12348
 /* basic algorithm is:
12349
  *   - ensure sane alignment of input data
12350
  *   - copy (conversion happens automatically) input data
12351
  *     to output
12352
  *   - update xpp to point at next unconverted input, and tp to point
12353
  *     at next location for converted output
12354
  */
12355
  long i, j, ni;
12356
  int tmp[LOOPCNT];        /* in case input is misaligned */
12357
  int *xp;
12358
  int nrange = 0;         /* number of range errors */
12359
  int realign = 0;        /* "do we need to fix input data alignment?" */
12360
  long cxp = (long) *((char**)xpp);
12361
12362
  realign = (cxp & 7) % SIZEOF_INT;
12363
  /* sjl: manually stripmine so we can limit amount of
12364
   * vector work space reserved to LOOPCNT elements. Also
12365
   * makes vectorisation easy */
12366
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12367
    ni=Min(nelems-j,LOOPCNT);
12368
    if (realign) {
12369
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12370
      xp = tmp;
12371
    } else {
12372
      xp = (int *) *xpp;
12373
    }
12374
   /* copy the next block */
12375
#pragma cdir loopcnt=LOOPCNT
12376
#pragma cdir shortloop
12377
    for (i=0; i<ni; i++) {
12378
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
12379
     /* test for range errors (not always needed but do it anyway) */
12380
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12381
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12382
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
12383
    }
12384
   /* update xpp and tp */
12385
    if (realign) xp = (int *) *xpp;
12386
    xp += ni;
12387
    tp += ni;
12388
    *xpp = (void*)xp;
12389
  }
12390
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12391
12392
#else   /* not SX */
12393
0
  const char *xp = (const char *) *xpp;
12394
0
  int status = NC_NOERR;
12395
12396
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12397
0
  {
12398
0
    const int lstatus = ncx_get_int_uchar(xp, tp);
12399
0
    if (status == NC_NOERR) /* report the first encountered error */
12400
0
      status = lstatus;
12401
0
  }
12402
12403
0
  *xpp = (const void *)xp;
12404
0
  return status;
12405
0
#endif
12406
0
}
12407
12408
int
12409
ncx_getn_int_ushort(const void **xpp, size_t nelems, ushort *tp)
12410
0
{
12411
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12412
12413
 /* basic algorithm is:
12414
  *   - ensure sane alignment of input data
12415
  *   - copy (conversion happens automatically) input data
12416
  *     to output
12417
  *   - update xpp to point at next unconverted input, and tp to point
12418
  *     at next location for converted output
12419
  */
12420
  long i, j, ni;
12421
  int tmp[LOOPCNT];        /* in case input is misaligned */
12422
  int *xp;
12423
  int nrange = 0;         /* number of range errors */
12424
  int realign = 0;        /* "do we need to fix input data alignment?" */
12425
  long cxp = (long) *((char**)xpp);
12426
12427
  realign = (cxp & 7) % SIZEOF_INT;
12428
  /* sjl: manually stripmine so we can limit amount of
12429
   * vector work space reserved to LOOPCNT elements. Also
12430
   * makes vectorisation easy */
12431
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12432
    ni=Min(nelems-j,LOOPCNT);
12433
    if (realign) {
12434
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12435
      xp = tmp;
12436
    } else {
12437
      xp = (int *) *xpp;
12438
    }
12439
   /* copy the next block */
12440
#pragma cdir loopcnt=LOOPCNT
12441
#pragma cdir shortloop
12442
    for (i=0; i<ni; i++) {
12443
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
12444
     /* test for range errors (not always needed but do it anyway) */
12445
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12446
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12447
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
12448
    }
12449
   /* update xpp and tp */
12450
    if (realign) xp = (int *) *xpp;
12451
    xp += ni;
12452
    tp += ni;
12453
    *xpp = (void*)xp;
12454
  }
12455
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12456
12457
#else   /* not SX */
12458
0
  const char *xp = (const char *) *xpp;
12459
0
  int status = NC_NOERR;
12460
12461
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12462
0
  {
12463
0
    const int lstatus = ncx_get_int_ushort(xp, tp);
12464
0
    if (status == NC_NOERR) /* report the first encountered error */
12465
0
      status = lstatus;
12466
0
  }
12467
12468
0
  *xpp = (const void *)xp;
12469
0
  return status;
12470
0
#endif
12471
0
}
12472
12473
int
12474
ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp)
12475
0
{
12476
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12477
12478
 /* basic algorithm is:
12479
  *   - ensure sane alignment of input data
12480
  *   - copy (conversion happens automatically) input data
12481
  *     to output
12482
  *   - update xpp to point at next unconverted input, and tp to point
12483
  *     at next location for converted output
12484
  */
12485
  long i, j, ni;
12486
  int tmp[LOOPCNT];        /* in case input is misaligned */
12487
  int *xp;
12488
  int nrange = 0;         /* number of range errors */
12489
  int realign = 0;        /* "do we need to fix input data alignment?" */
12490
  long cxp = (long) *((char**)xpp);
12491
12492
  realign = (cxp & 7) % SIZEOF_INT;
12493
  /* sjl: manually stripmine so we can limit amount of
12494
   * vector work space reserved to LOOPCNT elements. Also
12495
   * makes vectorisation easy */
12496
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12497
    ni=Min(nelems-j,LOOPCNT);
12498
    if (realign) {
12499
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12500
      xp = tmp;
12501
    } else {
12502
      xp = (int *) *xpp;
12503
    }
12504
   /* copy the next block */
12505
#pragma cdir loopcnt=LOOPCNT
12506
#pragma cdir shortloop
12507
    for (i=0; i<ni; i++) {
12508
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
12509
     /* test for range errors (not always needed but do it anyway) */
12510
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12511
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12512
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
12513
    }
12514
   /* update xpp and tp */
12515
    if (realign) xp = (int *) *xpp;
12516
    xp += ni;
12517
    tp += ni;
12518
    *xpp = (void*)xp;
12519
  }
12520
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12521
12522
#else   /* not SX */
12523
0
  const char *xp = (const char *) *xpp;
12524
0
  int status = NC_NOERR;
12525
12526
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12527
0
  {
12528
0
    const int lstatus = ncx_get_int_uint(xp, tp);
12529
0
    if (status == NC_NOERR) /* report the first encountered error */
12530
0
      status = lstatus;
12531
0
  }
12532
12533
0
  *xpp = (const void *)xp;
12534
0
  return status;
12535
0
#endif
12536
0
}
12537
12538
int
12539
ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
12540
0
{
12541
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12542
12543
 /* basic algorithm is:
12544
  *   - ensure sane alignment of input data
12545
  *   - copy (conversion happens automatically) input data
12546
  *     to output
12547
  *   - update xpp to point at next unconverted input, and tp to point
12548
  *     at next location for converted output
12549
  */
12550
  long i, j, ni;
12551
  int tmp[LOOPCNT];        /* in case input is misaligned */
12552
  int *xp;
12553
  int nrange = 0;         /* number of range errors */
12554
  int realign = 0;        /* "do we need to fix input data alignment?" */
12555
  long cxp = (long) *((char**)xpp);
12556
12557
  realign = (cxp & 7) % SIZEOF_INT;
12558
  /* sjl: manually stripmine so we can limit amount of
12559
   * vector work space reserved to LOOPCNT elements. Also
12560
   * makes vectorisation easy */
12561
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12562
    ni=Min(nelems-j,LOOPCNT);
12563
    if (realign) {
12564
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12565
      xp = tmp;
12566
    } else {
12567
      xp = (int *) *xpp;
12568
    }
12569
   /* copy the next block */
12570
#pragma cdir loopcnt=LOOPCNT
12571
#pragma cdir shortloop
12572
    for (i=0; i<ni; i++) {
12573
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
12574
     /* test for range errors (not always needed but do it anyway) */
12575
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12576
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12577
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
12578
    }
12579
   /* update xpp and tp */
12580
    if (realign) xp = (int *) *xpp;
12581
    xp += ni;
12582
    tp += ni;
12583
    *xpp = (void*)xp;
12584
  }
12585
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12586
12587
#else   /* not SX */
12588
0
  const char *xp = (const char *) *xpp;
12589
0
  int status = NC_NOERR;
12590
12591
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12592
0
  {
12593
0
    const int lstatus = ncx_get_int_ulonglong(xp, tp);
12594
0
    if (status == NC_NOERR) /* report the first encountered error */
12595
0
      status = lstatus;
12596
0
  }
12597
12598
0
  *xpp = (const void *)xp;
12599
0
  return status;
12600
0
#endif
12601
0
}
12602
12603
12604
#if X_SIZEOF_INT == SIZEOF_INT
12605
/* optimized version */
12606
int
12607
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12608
104k
{
12609
#ifdef WORDS_BIGENDIAN
12610
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
12611
# else
12612
104k
  swapn4b(*xpp, tp, nelems);
12613
104k
# endif
12614
104k
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
12615
104k
  return NC_NOERR;
12616
104k
}
12617
#else
12618
int
12619
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12620
{
12621
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12622
12623
 /* basic algorithm is:
12624
  *   - ensure sane alignment of output data
12625
  *   - copy (conversion happens automatically) input data
12626
  *     to output
12627
  *   - update tp to point at next unconverted input, and xpp to point
12628
  *     at next location for converted output
12629
  */
12630
  long i, j, ni;
12631
  int tmp[LOOPCNT];        /* in case input is misaligned */
12632
  int *xp;
12633
  int nrange = 0;         /* number of range errors */
12634
  int realign = 0;        /* "do we need to fix input data alignment?" */
12635
  long cxp = (long) *((char**)xpp);
12636
12637
  realign = (cxp & 7) % SIZEOF_INT;
12638
  /* sjl: manually stripmine so we can limit amount of
12639
   * vector work space reserved to LOOPCNT elements. Also
12640
   * makes vectorisation easy */
12641
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12642
    ni=Min(nelems-j,LOOPCNT);
12643
    if (realign) {
12644
      xp = tmp;
12645
    } else {
12646
      xp = (int *) *xpp;
12647
    }
12648
   /* copy the next block */
12649
#pragma cdir loopcnt=LOOPCNT
12650
#pragma cdir shortloop
12651
    for (i=0; i<ni; i++) {
12652
      /* the normal case: */
12653
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12654
     /* test for range errors (not always needed but do it anyway) */
12655
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12656
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12657
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12658
    }
12659
   /* copy workspace back if necessary */
12660
    if (realign) {
12661
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12662
      xp = (int *) *xpp;
12663
    }
12664
   /* update xpp and tp */
12665
    xp += ni;
12666
    tp += ni;
12667
    *xpp = (void*)xp;
12668
  }
12669
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12670
12671
#else   /* not SX */
12672
12673
  char *xp = (char *) *xpp;
12674
  int status = NC_NOERR;
12675
12676
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12677
  {
12678
    int lstatus = ncx_put_int_int(xp, tp, fillp);
12679
    if (status == NC_NOERR) /* report the first encountered error */
12680
      status = lstatus;
12681
  }
12682
12683
  *xpp = (void *)xp;
12684
  return status;
12685
#endif
12686
}
12687
12688
#endif
12689
int
12690
ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
12691
0
{
12692
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12693
12694
 /* basic algorithm is:
12695
  *   - ensure sane alignment of output data
12696
  *   - copy (conversion happens automatically) input data
12697
  *     to output
12698
  *   - update tp to point at next unconverted input, and xpp to point
12699
  *     at next location for converted output
12700
  */
12701
  long i, j, ni;
12702
  int tmp[LOOPCNT];        /* in case input is misaligned */
12703
  int *xp;
12704
  int nrange = 0;         /* number of range errors */
12705
  int realign = 0;        /* "do we need to fix input data alignment?" */
12706
  long cxp = (long) *((char**)xpp);
12707
12708
  realign = (cxp & 7) % SIZEOF_INT;
12709
  /* sjl: manually stripmine so we can limit amount of
12710
   * vector work space reserved to LOOPCNT elements. Also
12711
   * makes vectorisation easy */
12712
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12713
    ni=Min(nelems-j,LOOPCNT);
12714
    if (realign) {
12715
      xp = tmp;
12716
    } else {
12717
      xp = (int *) *xpp;
12718
    }
12719
   /* copy the next block */
12720
#pragma cdir loopcnt=LOOPCNT
12721
#pragma cdir shortloop
12722
    for (i=0; i<ni; i++) {
12723
      /* the normal case: */
12724
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12725
     /* test for range errors (not always needed but do it anyway) */
12726
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12727
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12728
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12729
    }
12730
   /* copy workspace back if necessary */
12731
    if (realign) {
12732
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12733
      xp = (int *) *xpp;
12734
    }
12735
   /* update xpp and tp */
12736
    xp += ni;
12737
    tp += ni;
12738
    *xpp = (void*)xp;
12739
  }
12740
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12741
12742
#else   /* not SX */
12743
12744
0
  char *xp = (char *) *xpp;
12745
0
  int status = NC_NOERR;
12746
12747
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12748
0
  {
12749
0
    int lstatus = ncx_put_int_schar(xp, tp, fillp);
12750
0
    if (status == NC_NOERR) /* report the first encountered error */
12751
0
      status = lstatus;
12752
0
  }
12753
12754
0
  *xpp = (void *)xp;
12755
0
  return status;
12756
0
#endif
12757
0
}
12758
12759
int
12760
ncx_putn_int_short(void **xpp, size_t nelems, const short *tp, void *fillp)
12761
0
{
12762
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12763
12764
 /* basic algorithm is:
12765
  *   - ensure sane alignment of output data
12766
  *   - copy (conversion happens automatically) input data
12767
  *     to output
12768
  *   - update tp to point at next unconverted input, and xpp to point
12769
  *     at next location for converted output
12770
  */
12771
  long i, j, ni;
12772
  int tmp[LOOPCNT];        /* in case input is misaligned */
12773
  int *xp;
12774
  int nrange = 0;         /* number of range errors */
12775
  int realign = 0;        /* "do we need to fix input data alignment?" */
12776
  long cxp = (long) *((char**)xpp);
12777
12778
  realign = (cxp & 7) % SIZEOF_INT;
12779
  /* sjl: manually stripmine so we can limit amount of
12780
   * vector work space reserved to LOOPCNT elements. Also
12781
   * makes vectorisation easy */
12782
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12783
    ni=Min(nelems-j,LOOPCNT);
12784
    if (realign) {
12785
      xp = tmp;
12786
    } else {
12787
      xp = (int *) *xpp;
12788
    }
12789
   /* copy the next block */
12790
#pragma cdir loopcnt=LOOPCNT
12791
#pragma cdir shortloop
12792
    for (i=0; i<ni; i++) {
12793
      /* the normal case: */
12794
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12795
     /* test for range errors (not always needed but do it anyway) */
12796
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12797
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12798
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12799
    }
12800
   /* copy workspace back if necessary */
12801
    if (realign) {
12802
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12803
      xp = (int *) *xpp;
12804
    }
12805
   /* update xpp and tp */
12806
    xp += ni;
12807
    tp += ni;
12808
    *xpp = (void*)xp;
12809
  }
12810
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12811
12812
#else   /* not SX */
12813
12814
0
  char *xp = (char *) *xpp;
12815
0
  int status = NC_NOERR;
12816
12817
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12818
0
  {
12819
0
    int lstatus = ncx_put_int_short(xp, tp, fillp);
12820
0
    if (status == NC_NOERR) /* report the first encountered error */
12821
0
      status = lstatus;
12822
0
  }
12823
12824
0
  *xpp = (void *)xp;
12825
0
  return status;
12826
0
#endif
12827
0
}
12828
12829
int
12830
ncx_putn_int_long(void **xpp, size_t nelems, const long *tp, void *fillp)
12831
0
{
12832
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12833
12834
 /* basic algorithm is:
12835
  *   - ensure sane alignment of output data
12836
  *   - copy (conversion happens automatically) input data
12837
  *     to output
12838
  *   - update tp to point at next unconverted input, and xpp to point
12839
  *     at next location for converted output
12840
  */
12841
  long i, j, ni;
12842
  int tmp[LOOPCNT];        /* in case input is misaligned */
12843
  int *xp;
12844
  int nrange = 0;         /* number of range errors */
12845
  int realign = 0;        /* "do we need to fix input data alignment?" */
12846
  long cxp = (long) *((char**)xpp);
12847
12848
  realign = (cxp & 7) % SIZEOF_INT;
12849
  /* sjl: manually stripmine so we can limit amount of
12850
   * vector work space reserved to LOOPCNT elements. Also
12851
   * makes vectorisation easy */
12852
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12853
    ni=Min(nelems-j,LOOPCNT);
12854
    if (realign) {
12855
      xp = tmp;
12856
    } else {
12857
      xp = (int *) *xpp;
12858
    }
12859
   /* copy the next block */
12860
#pragma cdir loopcnt=LOOPCNT
12861
#pragma cdir shortloop
12862
    for (i=0; i<ni; i++) {
12863
      /* the normal case: */
12864
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12865
     /* test for range errors (not always needed but do it anyway) */
12866
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12867
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12868
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12869
    }
12870
   /* copy workspace back if necessary */
12871
    if (realign) {
12872
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12873
      xp = (int *) *xpp;
12874
    }
12875
   /* update xpp and tp */
12876
    xp += ni;
12877
    tp += ni;
12878
    *xpp = (void*)xp;
12879
  }
12880
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12881
12882
#else   /* not SX */
12883
12884
0
  char *xp = (char *) *xpp;
12885
0
  int status = NC_NOERR;
12886
12887
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12888
0
  {
12889
0
    int lstatus = ncx_put_int_long(xp, tp, fillp);
12890
0
    if (status == NC_NOERR) /* report the first encountered error */
12891
0
      status = lstatus;
12892
0
  }
12893
12894
0
  *xpp = (void *)xp;
12895
0
  return status;
12896
0
#endif
12897
0
}
12898
12899
int
12900
ncx_putn_int_float(void **xpp, size_t nelems, const float *tp, void *fillp)
12901
0
{
12902
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12903
12904
 /* basic algorithm is:
12905
  *   - ensure sane alignment of output data
12906
  *   - copy (conversion happens automatically) input data
12907
  *     to output
12908
  *   - update tp to point at next unconverted input, and xpp to point
12909
  *     at next location for converted output
12910
  */
12911
  long i, j, ni;
12912
  int tmp[LOOPCNT];        /* in case input is misaligned */
12913
  int *xp;
12914
  double d;               /* special case for ncx_putn_int_float */
12915
  int nrange = 0;         /* number of range errors */
12916
  int realign = 0;        /* "do we need to fix input data alignment?" */
12917
  long cxp = (long) *((char**)xpp);
12918
12919
  realign = (cxp & 7) % SIZEOF_INT;
12920
  /* sjl: manually stripmine so we can limit amount of
12921
   * vector work space reserved to LOOPCNT elements. Also
12922
   * makes vectorisation easy */
12923
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12924
    ni=Min(nelems-j,LOOPCNT);
12925
    if (realign) {
12926
      xp = tmp;
12927
    } else {
12928
      xp = (int *) *xpp;
12929
    }
12930
   /* copy the next block */
12931
#pragma cdir loopcnt=LOOPCNT
12932
#pragma cdir shortloop
12933
    for (i=0; i<ni; i++) {
12934
      /* for some reason int to float, for putn, requires a special case */
12935
      d = tp[i];
12936
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
12937
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12938
    }
12939
   /* copy workspace back if necessary */
12940
    if (realign) {
12941
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12942
      xp = (int *) *xpp;
12943
    }
12944
   /* update xpp and tp */
12945
    xp += ni;
12946
    tp += ni;
12947
    *xpp = (void*)xp;
12948
  }
12949
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12950
12951
#else   /* not SX */
12952
12953
0
  char *xp = (char *) *xpp;
12954
0
  int status = NC_NOERR;
12955
12956
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12957
0
  {
12958
0
    int lstatus = ncx_put_int_float(xp, tp, fillp);
12959
0
    if (status == NC_NOERR) /* report the first encountered error */
12960
0
      status = lstatus;
12961
0
  }
12962
12963
0
  *xpp = (void *)xp;
12964
0
  return status;
12965
0
#endif
12966
0
}
12967
12968
int
12969
ncx_putn_int_double(void **xpp, size_t nelems, const double *tp, void *fillp)
12970
0
{
12971
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12972
12973
 /* basic algorithm is:
12974
  *   - ensure sane alignment of output data
12975
  *   - copy (conversion happens automatically) input data
12976
  *     to output
12977
  *   - update tp to point at next unconverted input, and xpp to point
12978
  *     at next location for converted output
12979
  */
12980
  long i, j, ni;
12981
  int tmp[LOOPCNT];        /* in case input is misaligned */
12982
  int *xp;
12983
  int nrange = 0;         /* number of range errors */
12984
  int realign = 0;        /* "do we need to fix input data alignment?" */
12985
  long cxp = (long) *((char**)xpp);
12986
12987
  realign = (cxp & 7) % SIZEOF_INT;
12988
  /* sjl: manually stripmine so we can limit amount of
12989
   * vector work space reserved to LOOPCNT elements. Also
12990
   * makes vectorisation easy */
12991
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12992
    ni=Min(nelems-j,LOOPCNT);
12993
    if (realign) {
12994
      xp = tmp;
12995
    } else {
12996
      xp = (int *) *xpp;
12997
    }
12998
   /* copy the next block */
12999
#pragma cdir loopcnt=LOOPCNT
13000
#pragma cdir shortloop
13001
    for (i=0; i<ni; i++) {
13002
      /* the normal case: */
13003
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13004
     /* test for range errors (not always needed but do it anyway) */
13005
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13006
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13007
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
13008
    }
13009
   /* copy workspace back if necessary */
13010
    if (realign) {
13011
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13012
      xp = (int *) *xpp;
13013
    }
13014
   /* update xpp and tp */
13015
    xp += ni;
13016
    tp += ni;
13017
    *xpp = (void*)xp;
13018
  }
13019
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13020
13021
#else   /* not SX */
13022
13023
0
  char *xp = (char *) *xpp;
13024
0
  int status = NC_NOERR;
13025
13026
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13027
0
  {
13028
0
    int lstatus = ncx_put_int_double(xp, tp, fillp);
13029
0
    if (status == NC_NOERR) /* report the first encountered error */
13030
0
      status = lstatus;
13031
0
  }
13032
13033
0
  *xpp = (void *)xp;
13034
0
  return status;
13035
0
#endif
13036
0
}
13037
13038
int
13039
ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
13040
0
{
13041
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13042
13043
 /* basic algorithm is:
13044
  *   - ensure sane alignment of output data
13045
  *   - copy (conversion happens automatically) input data
13046
  *     to output
13047
  *   - update tp to point at next unconverted input, and xpp to point
13048
  *     at next location for converted output
13049
  */
13050
  long i, j, ni;
13051
  int tmp[LOOPCNT];        /* in case input is misaligned */
13052
  int *xp;
13053
  int nrange = 0;         /* number of range errors */
13054
  int realign = 0;        /* "do we need to fix input data alignment?" */
13055
  long cxp = (long) *((char**)xpp);
13056
13057
  realign = (cxp & 7) % SIZEOF_INT;
13058
  /* sjl: manually stripmine so we can limit amount of
13059
   * vector work space reserved to LOOPCNT elements. Also
13060
   * makes vectorisation easy */
13061
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13062
    ni=Min(nelems-j,LOOPCNT);
13063
    if (realign) {
13064
      xp = tmp;
13065
    } else {
13066
      xp = (int *) *xpp;
13067
    }
13068
   /* copy the next block */
13069
#pragma cdir loopcnt=LOOPCNT
13070
#pragma cdir shortloop
13071
    for (i=0; i<ni; i++) {
13072
      /* the normal case: */
13073
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13074
     /* test for range errors (not always needed but do it anyway) */
13075
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13076
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13077
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
13078
    }
13079
   /* copy workspace back if necessary */
13080
    if (realign) {
13081
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13082
      xp = (int *) *xpp;
13083
    }
13084
   /* update xpp and tp */
13085
    xp += ni;
13086
    tp += ni;
13087
    *xpp = (void*)xp;
13088
  }
13089
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13090
13091
#else   /* not SX */
13092
13093
0
  char *xp = (char *) *xpp;
13094
0
  int status = NC_NOERR;
13095
13096
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13097
0
  {
13098
0
    int lstatus = ncx_put_int_longlong(xp, tp, fillp);
13099
0
    if (status == NC_NOERR) /* report the first encountered error */
13100
0
      status = lstatus;
13101
0
  }
13102
13103
0
  *xpp = (void *)xp;
13104
0
  return status;
13105
0
#endif
13106
0
}
13107
13108
int
13109
ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
13110
0
{
13111
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13112
13113
 /* basic algorithm is:
13114
  *   - ensure sane alignment of output data
13115
  *   - copy (conversion happens automatically) input data
13116
  *     to output
13117
  *   - update tp to point at next unconverted input, and xpp to point
13118
  *     at next location for converted output
13119
  */
13120
  long i, j, ni;
13121
  int tmp[LOOPCNT];        /* in case input is misaligned */
13122
  int *xp;
13123
  int nrange = 0;         /* number of range errors */
13124
  int realign = 0;        /* "do we need to fix input data alignment?" */
13125
  long cxp = (long) *((char**)xpp);
13126
13127
  realign = (cxp & 7) % SIZEOF_INT;
13128
  /* sjl: manually stripmine so we can limit amount of
13129
   * vector work space reserved to LOOPCNT elements. Also
13130
   * makes vectorisation easy */
13131
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13132
    ni=Min(nelems-j,LOOPCNT);
13133
    if (realign) {
13134
      xp = tmp;
13135
    } else {
13136
      xp = (int *) *xpp;
13137
    }
13138
   /* copy the next block */
13139
#pragma cdir loopcnt=LOOPCNT
13140
#pragma cdir shortloop
13141
    for (i=0; i<ni; i++) {
13142
      /* the normal case: */
13143
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13144
     /* test for range errors (not always needed but do it anyway) */
13145
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13146
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13147
      nrange += tp[i] > X_INT_MAX ;
13148
    }
13149
   /* copy workspace back if necessary */
13150
    if (realign) {
13151
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13152
      xp = (int *) *xpp;
13153
    }
13154
   /* update xpp and tp */
13155
    xp += ni;
13156
    tp += ni;
13157
    *xpp = (void*)xp;
13158
  }
13159
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13160
13161
#else   /* not SX */
13162
13163
0
  char *xp = (char *) *xpp;
13164
0
  int status = NC_NOERR;
13165
13166
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13167
0
  {
13168
0
    int lstatus = ncx_put_int_uchar(xp, tp, fillp);
13169
0
    if (status == NC_NOERR) /* report the first encountered error */
13170
0
      status = lstatus;
13171
0
  }
13172
13173
0
  *xpp = (void *)xp;
13174
0
  return status;
13175
0
#endif
13176
0
}
13177
13178
int
13179
ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
13180
0
{
13181
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13182
13183
 /* basic algorithm is:
13184
  *   - ensure sane alignment of output data
13185
  *   - copy (conversion happens automatically) input data
13186
  *     to output
13187
  *   - update tp to point at next unconverted input, and xpp to point
13188
  *     at next location for converted output
13189
  */
13190
  long i, j, ni;
13191
  int tmp[LOOPCNT];        /* in case input is misaligned */
13192
  int *xp;
13193
  int nrange = 0;         /* number of range errors */
13194
  int realign = 0;        /* "do we need to fix input data alignment?" */
13195
  long cxp = (long) *((char**)xpp);
13196
13197
  realign = (cxp & 7) % SIZEOF_INT;
13198
  /* sjl: manually stripmine so we can limit amount of
13199
   * vector work space reserved to LOOPCNT elements. Also
13200
   * makes vectorisation easy */
13201
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13202
    ni=Min(nelems-j,LOOPCNT);
13203
    if (realign) {
13204
      xp = tmp;
13205
    } else {
13206
      xp = (int *) *xpp;
13207
    }
13208
   /* copy the next block */
13209
#pragma cdir loopcnt=LOOPCNT
13210
#pragma cdir shortloop
13211
    for (i=0; i<ni; i++) {
13212
      /* the normal case: */
13213
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13214
     /* test for range errors (not always needed but do it anyway) */
13215
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13216
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13217
      nrange += tp[i] > X_INT_MAX ;
13218
    }
13219
   /* copy workspace back if necessary */
13220
    if (realign) {
13221
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13222
      xp = (int *) *xpp;
13223
    }
13224
   /* update xpp and tp */
13225
    xp += ni;
13226
    tp += ni;
13227
    *xpp = (void*)xp;
13228
  }
13229
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13230
13231
#else   /* not SX */
13232
13233
0
  char *xp = (char *) *xpp;
13234
0
  int status = NC_NOERR;
13235
13236
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13237
0
  {
13238
0
    int lstatus = ncx_put_int_ushort(xp, tp, fillp);
13239
0
    if (status == NC_NOERR) /* report the first encountered error */
13240
0
      status = lstatus;
13241
0
  }
13242
13243
0
  *xpp = (void *)xp;
13244
0
  return status;
13245
0
#endif
13246
0
}
13247
13248
int
13249
ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13250
0
{
13251
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13252
13253
 /* basic algorithm is:
13254
  *   - ensure sane alignment of output data
13255
  *   - copy (conversion happens automatically) input data
13256
  *     to output
13257
  *   - update tp to point at next unconverted input, and xpp to point
13258
  *     at next location for converted output
13259
  */
13260
  long i, j, ni;
13261
  int tmp[LOOPCNT];        /* in case input is misaligned */
13262
  int *xp;
13263
  int nrange = 0;         /* number of range errors */
13264
  int realign = 0;        /* "do we need to fix input data alignment?" */
13265
  long cxp = (long) *((char**)xpp);
13266
13267
  realign = (cxp & 7) % SIZEOF_INT;
13268
  /* sjl: manually stripmine so we can limit amount of
13269
   * vector work space reserved to LOOPCNT elements. Also
13270
   * makes vectorisation easy */
13271
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13272
    ni=Min(nelems-j,LOOPCNT);
13273
    if (realign) {
13274
      xp = tmp;
13275
    } else {
13276
      xp = (int *) *xpp;
13277
    }
13278
   /* copy the next block */
13279
#pragma cdir loopcnt=LOOPCNT
13280
#pragma cdir shortloop
13281
    for (i=0; i<ni; i++) {
13282
      /* the normal case: */
13283
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13284
     /* test for range errors (not always needed but do it anyway) */
13285
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13286
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13287
      nrange += tp[i] > X_INT_MAX ;
13288
    }
13289
   /* copy workspace back if necessary */
13290
    if (realign) {
13291
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13292
      xp = (int *) *xpp;
13293
    }
13294
   /* update xpp and tp */
13295
    xp += ni;
13296
    tp += ni;
13297
    *xpp = (void*)xp;
13298
  }
13299
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13300
13301
#else   /* not SX */
13302
13303
0
  char *xp = (char *) *xpp;
13304
0
  int status = NC_NOERR;
13305
13306
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13307
0
  {
13308
0
    int lstatus = ncx_put_int_uint(xp, tp, fillp);
13309
0
    if (status == NC_NOERR) /* report the first encountered error */
13310
0
      status = lstatus;
13311
0
  }
13312
13313
0
  *xpp = (void *)xp;
13314
0
  return status;
13315
0
#endif
13316
0
}
13317
13318
int
13319
ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
13320
0
{
13321
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13322
13323
 /* basic algorithm is:
13324
  *   - ensure sane alignment of output data
13325
  *   - copy (conversion happens automatically) input data
13326
  *     to output
13327
  *   - update tp to point at next unconverted input, and xpp to point
13328
  *     at next location for converted output
13329
  */
13330
  long i, j, ni;
13331
  int tmp[LOOPCNT];        /* in case input is misaligned */
13332
  int *xp;
13333
  int nrange = 0;         /* number of range errors */
13334
  int realign = 0;        /* "do we need to fix input data alignment?" */
13335
  long cxp = (long) *((char**)xpp);
13336
13337
  realign = (cxp & 7) % SIZEOF_INT;
13338
  /* sjl: manually stripmine so we can limit amount of
13339
   * vector work space reserved to LOOPCNT elements. Also
13340
   * makes vectorisation easy */
13341
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13342
    ni=Min(nelems-j,LOOPCNT);
13343
    if (realign) {
13344
      xp = tmp;
13345
    } else {
13346
      xp = (int *) *xpp;
13347
    }
13348
   /* copy the next block */
13349
#pragma cdir loopcnt=LOOPCNT
13350
#pragma cdir shortloop
13351
    for (i=0; i<ni; i++) {
13352
      /* the normal case: */
13353
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13354
     /* test for range errors (not always needed but do it anyway) */
13355
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13356
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13357
      nrange += tp[i] > X_INT_MAX ;
13358
    }
13359
   /* copy workspace back if necessary */
13360
    if (realign) {
13361
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13362
      xp = (int *) *xpp;
13363
    }
13364
   /* update xpp and tp */
13365
    xp += ni;
13366
    tp += ni;
13367
    *xpp = (void*)xp;
13368
  }
13369
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13370
13371
#else   /* not SX */
13372
13373
0
  char *xp = (char *) *xpp;
13374
0
  int status = NC_NOERR;
13375
13376
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13377
0
  {
13378
0
    int lstatus = ncx_put_int_ulonglong(xp, tp, fillp);
13379
0
    if (status == NC_NOERR) /* report the first encountered error */
13380
0
      status = lstatus;
13381
0
  }
13382
13383
0
  *xpp = (void *)xp;
13384
0
  return status;
13385
0
#endif
13386
0
}
13387
13388
13389
/* uint ----------------------------------------------------------------------*/
13390
13391
#if X_SIZEOF_UINT == SIZEOF_UINT
13392
/* optimized version */
13393
int
13394
ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
13395
0
{
13396
#ifdef WORDS_BIGENDIAN
13397
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
13398
# else
13399
0
  swapn4b(tp, *xpp, nelems);
13400
0
# endif
13401
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
13402
0
  return NC_NOERR;
13403
0
}
13404
#else
13405
int
13406
ncx_getn_uint_uint(const void **xpp, size_t nelems, uint *tp)
13407
{
13408
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13409
13410
 /* basic algorithm is:
13411
  *   - ensure sane alignment of input data
13412
  *   - copy (conversion happens automatically) input data
13413
  *     to output
13414
  *   - update xpp to point at next unconverted input, and tp to point
13415
  *     at next location for converted output
13416
  */
13417
  long i, j, ni;
13418
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13419
  uint *xp;
13420
  int nrange = 0;         /* number of range errors */
13421
  int realign = 0;        /* "do we need to fix input data alignment?" */
13422
  long cxp = (long) *((char**)xpp);
13423
13424
  realign = (cxp & 7) % SIZEOF_UINT;
13425
  /* sjl: manually stripmine so we can limit amount of
13426
   * vector work space reserved to LOOPCNT elements. Also
13427
   * makes vectorisation easy */
13428
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13429
    ni=Min(nelems-j,LOOPCNT);
13430
    if (realign) {
13431
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13432
      xp = tmp;
13433
    } else {
13434
      xp = (uint *) *xpp;
13435
    }
13436
   /* copy the next block */
13437
#pragma cdir loopcnt=LOOPCNT
13438
#pragma cdir shortloop
13439
    for (i=0; i<ni; i++) {
13440
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
13441
     /* test for range errors (not always needed but do it anyway) */
13442
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13443
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13444
      nrange += xp[i] > UINT_MAX ;
13445
    }
13446
   /* update xpp and tp */
13447
    if (realign) xp = (uint *) *xpp;
13448
    xp += ni;
13449
    tp += ni;
13450
    *xpp = (void*)xp;
13451
  }
13452
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13453
13454
#else   /* not SX */
13455
  const char *xp = (const char *) *xpp;
13456
  int status = NC_NOERR;
13457
13458
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13459
  {
13460
    const int lstatus = ncx_get_uint_uint(xp, tp);
13461
    if (status == NC_NOERR) /* report the first encountered error */
13462
      status = lstatus;
13463
  }
13464
13465
  *xpp = (const void *)xp;
13466
  return status;
13467
#endif
13468
}
13469
13470
#endif
13471
int
13472
ncx_getn_uint_schar(const void **xpp, size_t nelems, schar *tp)
13473
0
{
13474
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13475
13476
 /* basic algorithm is:
13477
  *   - ensure sane alignment of input data
13478
  *   - copy (conversion happens automatically) input data
13479
  *     to output
13480
  *   - update xpp to point at next unconverted input, and tp to point
13481
  *     at next location for converted output
13482
  */
13483
  long i, j, ni;
13484
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13485
  uint *xp;
13486
  int nrange = 0;         /* number of range errors */
13487
  int realign = 0;        /* "do we need to fix input data alignment?" */
13488
  long cxp = (long) *((char**)xpp);
13489
13490
  realign = (cxp & 7) % SIZEOF_UINT;
13491
  /* sjl: manually stripmine so we can limit amount of
13492
   * vector work space reserved to LOOPCNT elements. Also
13493
   * makes vectorisation easy */
13494
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13495
    ni=Min(nelems-j,LOOPCNT);
13496
    if (realign) {
13497
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13498
      xp = tmp;
13499
    } else {
13500
      xp = (uint *) *xpp;
13501
    }
13502
   /* copy the next block */
13503
#pragma cdir loopcnt=LOOPCNT
13504
#pragma cdir shortloop
13505
    for (i=0; i<ni; i++) {
13506
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
13507
     /* test for range errors (not always needed but do it anyway) */
13508
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13509
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13510
      nrange += xp[i] > SCHAR_MAX ;
13511
    }
13512
   /* update xpp and tp */
13513
    if (realign) xp = (uint *) *xpp;
13514
    xp += ni;
13515
    tp += ni;
13516
    *xpp = (void*)xp;
13517
  }
13518
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13519
13520
#else   /* not SX */
13521
0
  const char *xp = (const char *) *xpp;
13522
0
  int status = NC_NOERR;
13523
13524
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13525
0
  {
13526
0
    const int lstatus = ncx_get_uint_schar(xp, tp);
13527
0
    if (status == NC_NOERR) /* report the first encountered error */
13528
0
      status = lstatus;
13529
0
  }
13530
13531
0
  *xpp = (const void *)xp;
13532
0
  return status;
13533
0
#endif
13534
0
}
13535
13536
int
13537
ncx_getn_uint_short(const void **xpp, size_t nelems, short *tp)
13538
0
{
13539
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13540
13541
 /* basic algorithm is:
13542
  *   - ensure sane alignment of input data
13543
  *   - copy (conversion happens automatically) input data
13544
  *     to output
13545
  *   - update xpp to point at next unconverted input, and tp to point
13546
  *     at next location for converted output
13547
  */
13548
  long i, j, ni;
13549
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13550
  uint *xp;
13551
  int nrange = 0;         /* number of range errors */
13552
  int realign = 0;        /* "do we need to fix input data alignment?" */
13553
  long cxp = (long) *((char**)xpp);
13554
13555
  realign = (cxp & 7) % SIZEOF_UINT;
13556
  /* sjl: manually stripmine so we can limit amount of
13557
   * vector work space reserved to LOOPCNT elements. Also
13558
   * makes vectorisation easy */
13559
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13560
    ni=Min(nelems-j,LOOPCNT);
13561
    if (realign) {
13562
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13563
      xp = tmp;
13564
    } else {
13565
      xp = (uint *) *xpp;
13566
    }
13567
   /* copy the next block */
13568
#pragma cdir loopcnt=LOOPCNT
13569
#pragma cdir shortloop
13570
    for (i=0; i<ni; i++) {
13571
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
13572
     /* test for range errors (not always needed but do it anyway) */
13573
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13574
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13575
      nrange += xp[i] > SHORT_MAX ;
13576
    }
13577
   /* update xpp and tp */
13578
    if (realign) xp = (uint *) *xpp;
13579
    xp += ni;
13580
    tp += ni;
13581
    *xpp = (void*)xp;
13582
  }
13583
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13584
13585
#else   /* not SX */
13586
0
  const char *xp = (const char *) *xpp;
13587
0
  int status = NC_NOERR;
13588
13589
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13590
0
  {
13591
0
    const int lstatus = ncx_get_uint_short(xp, tp);
13592
0
    if (status == NC_NOERR) /* report the first encountered error */
13593
0
      status = lstatus;
13594
0
  }
13595
13596
0
  *xpp = (const void *)xp;
13597
0
  return status;
13598
0
#endif
13599
0
}
13600
13601
int
13602
ncx_getn_uint_int(const void **xpp, size_t nelems, int *tp)
13603
0
{
13604
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13605
13606
 /* basic algorithm is:
13607
  *   - ensure sane alignment of input data
13608
  *   - copy (conversion happens automatically) input data
13609
  *     to output
13610
  *   - update xpp to point at next unconverted input, and tp to point
13611
  *     at next location for converted output
13612
  */
13613
  long i, j, ni;
13614
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13615
  uint *xp;
13616
  int nrange = 0;         /* number of range errors */
13617
  int realign = 0;        /* "do we need to fix input data alignment?" */
13618
  long cxp = (long) *((char**)xpp);
13619
13620
  realign = (cxp & 7) % SIZEOF_UINT;
13621
  /* sjl: manually stripmine so we can limit amount of
13622
   * vector work space reserved to LOOPCNT elements. Also
13623
   * makes vectorisation easy */
13624
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13625
    ni=Min(nelems-j,LOOPCNT);
13626
    if (realign) {
13627
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13628
      xp = tmp;
13629
    } else {
13630
      xp = (uint *) *xpp;
13631
    }
13632
   /* copy the next block */
13633
#pragma cdir loopcnt=LOOPCNT
13634
#pragma cdir shortloop
13635
    for (i=0; i<ni; i++) {
13636
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
13637
     /* test for range errors (not always needed but do it anyway) */
13638
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13639
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13640
      nrange += xp[i] > INT_MAX ;
13641
    }
13642
   /* update xpp and tp */
13643
    if (realign) xp = (uint *) *xpp;
13644
    xp += ni;
13645
    tp += ni;
13646
    *xpp = (void*)xp;
13647
  }
13648
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13649
13650
#else   /* not SX */
13651
0
  const char *xp = (const char *) *xpp;
13652
0
  int status = NC_NOERR;
13653
13654
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13655
0
  {
13656
0
    const int lstatus = ncx_get_uint_int(xp, tp);
13657
0
    if (status == NC_NOERR) /* report the first encountered error */
13658
0
      status = lstatus;
13659
0
  }
13660
13661
0
  *xpp = (const void *)xp;
13662
0
  return status;
13663
0
#endif
13664
0
}
13665
13666
int
13667
ncx_getn_uint_long(const void **xpp, size_t nelems, long *tp)
13668
0
{
13669
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13670
13671
 /* basic algorithm is:
13672
  *   - ensure sane alignment of input data
13673
  *   - copy (conversion happens automatically) input data
13674
  *     to output
13675
  *   - update xpp to point at next unconverted input, and tp to point
13676
  *     at next location for converted output
13677
  */
13678
  long i, j, ni;
13679
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13680
  uint *xp;
13681
  int nrange = 0;         /* number of range errors */
13682
  int realign = 0;        /* "do we need to fix input data alignment?" */
13683
  long cxp = (long) *((char**)xpp);
13684
13685
  realign = (cxp & 7) % SIZEOF_UINT;
13686
  /* sjl: manually stripmine so we can limit amount of
13687
   * vector work space reserved to LOOPCNT elements. Also
13688
   * makes vectorisation easy */
13689
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13690
    ni=Min(nelems-j,LOOPCNT);
13691
    if (realign) {
13692
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13693
      xp = tmp;
13694
    } else {
13695
      xp = (uint *) *xpp;
13696
    }
13697
   /* copy the next block */
13698
#pragma cdir loopcnt=LOOPCNT
13699
#pragma cdir shortloop
13700
    for (i=0; i<ni; i++) {
13701
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
13702
     /* test for range errors (not always needed but do it anyway) */
13703
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13704
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13705
      nrange += xp[i] > LONG_MAX ;
13706
    }
13707
   /* update xpp and tp */
13708
    if (realign) xp = (uint *) *xpp;
13709
    xp += ni;
13710
    tp += ni;
13711
    *xpp = (void*)xp;
13712
  }
13713
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13714
13715
#else   /* not SX */
13716
0
  const char *xp = (const char *) *xpp;
13717
0
  int status = NC_NOERR;
13718
13719
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13720
0
  {
13721
0
    const int lstatus = ncx_get_uint_long(xp, tp);
13722
0
    if (status == NC_NOERR) /* report the first encountered error */
13723
0
      status = lstatus;
13724
0
  }
13725
13726
0
  *xpp = (const void *)xp;
13727
0
  return status;
13728
0
#endif
13729
0
}
13730
13731
int
13732
ncx_getn_uint_float(const void **xpp, size_t nelems, float *tp)
13733
0
{
13734
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13735
13736
 /* basic algorithm is:
13737
  *   - ensure sane alignment of input data
13738
  *   - copy (conversion happens automatically) input data
13739
  *     to output
13740
  *   - update xpp to point at next unconverted input, and tp to point
13741
  *     at next location for converted output
13742
  */
13743
  long i, j, ni;
13744
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13745
  uint *xp;
13746
  int nrange = 0;         /* number of range errors */
13747
  int realign = 0;        /* "do we need to fix input data alignment?" */
13748
  long cxp = (long) *((char**)xpp);
13749
13750
  realign = (cxp & 7) % SIZEOF_UINT;
13751
  /* sjl: manually stripmine so we can limit amount of
13752
   * vector work space reserved to LOOPCNT elements. Also
13753
   * makes vectorisation easy */
13754
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13755
    ni=Min(nelems-j,LOOPCNT);
13756
    if (realign) {
13757
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13758
      xp = tmp;
13759
    } else {
13760
      xp = (uint *) *xpp;
13761
    }
13762
   /* copy the next block */
13763
#pragma cdir loopcnt=LOOPCNT
13764
#pragma cdir shortloop
13765
    for (i=0; i<ni; i++) {
13766
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
13767
     /* test for range errors (not always needed but do it anyway) */
13768
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13769
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13770
      nrange += xp[i] > FLOAT_MAX ;
13771
    }
13772
   /* update xpp and tp */
13773
    if (realign) xp = (uint *) *xpp;
13774
    xp += ni;
13775
    tp += ni;
13776
    *xpp = (void*)xp;
13777
  }
13778
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13779
13780
#else   /* not SX */
13781
0
  const char *xp = (const char *) *xpp;
13782
0
  int status = NC_NOERR;
13783
13784
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13785
0
  {
13786
0
    const int lstatus = ncx_get_uint_float(xp, tp);
13787
0
    if (status == NC_NOERR) /* report the first encountered error */
13788
0
      status = lstatus;
13789
0
  }
13790
13791
0
  *xpp = (const void *)xp;
13792
0
  return status;
13793
0
#endif
13794
0
}
13795
13796
int
13797
ncx_getn_uint_double(const void **xpp, size_t nelems, double *tp)
13798
0
{
13799
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13800
13801
 /* basic algorithm is:
13802
  *   - ensure sane alignment of input data
13803
  *   - copy (conversion happens automatically) input data
13804
  *     to output
13805
  *   - update xpp to point at next unconverted input, and tp to point
13806
  *     at next location for converted output
13807
  */
13808
  long i, j, ni;
13809
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13810
  uint *xp;
13811
  int nrange = 0;         /* number of range errors */
13812
  int realign = 0;        /* "do we need to fix input data alignment?" */
13813
  long cxp = (long) *((char**)xpp);
13814
13815
  realign = (cxp & 7) % SIZEOF_UINT;
13816
  /* sjl: manually stripmine so we can limit amount of
13817
   * vector work space reserved to LOOPCNT elements. Also
13818
   * makes vectorisation easy */
13819
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13820
    ni=Min(nelems-j,LOOPCNT);
13821
    if (realign) {
13822
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13823
      xp = tmp;
13824
    } else {
13825
      xp = (uint *) *xpp;
13826
    }
13827
   /* copy the next block */
13828
#pragma cdir loopcnt=LOOPCNT
13829
#pragma cdir shortloop
13830
    for (i=0; i<ni; i++) {
13831
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
13832
     /* test for range errors (not always needed but do it anyway) */
13833
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13834
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13835
      nrange += xp[i] > DOUBLE_MAX ;
13836
    }
13837
   /* update xpp and tp */
13838
    if (realign) xp = (uint *) *xpp;
13839
    xp += ni;
13840
    tp += ni;
13841
    *xpp = (void*)xp;
13842
  }
13843
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13844
13845
#else   /* not SX */
13846
0
  const char *xp = (const char *) *xpp;
13847
0
  int status = NC_NOERR;
13848
13849
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13850
0
  {
13851
0
    const int lstatus = ncx_get_uint_double(xp, tp);
13852
0
    if (status == NC_NOERR) /* report the first encountered error */
13853
0
      status = lstatus;
13854
0
  }
13855
13856
0
  *xpp = (const void *)xp;
13857
0
  return status;
13858
0
#endif
13859
0
}
13860
13861
int
13862
ncx_getn_uint_longlong(const void **xpp, size_t nelems, longlong *tp)
13863
0
{
13864
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13865
13866
 /* basic algorithm is:
13867
  *   - ensure sane alignment of input data
13868
  *   - copy (conversion happens automatically) input data
13869
  *     to output
13870
  *   - update xpp to point at next unconverted input, and tp to point
13871
  *     at next location for converted output
13872
  */
13873
  long i, j, ni;
13874
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13875
  uint *xp;
13876
  int nrange = 0;         /* number of range errors */
13877
  int realign = 0;        /* "do we need to fix input data alignment?" */
13878
  long cxp = (long) *((char**)xpp);
13879
13880
  realign = (cxp & 7) % SIZEOF_UINT;
13881
  /* sjl: manually stripmine so we can limit amount of
13882
   * vector work space reserved to LOOPCNT elements. Also
13883
   * makes vectorisation easy */
13884
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13885
    ni=Min(nelems-j,LOOPCNT);
13886
    if (realign) {
13887
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13888
      xp = tmp;
13889
    } else {
13890
      xp = (uint *) *xpp;
13891
    }
13892
   /* copy the next block */
13893
#pragma cdir loopcnt=LOOPCNT
13894
#pragma cdir shortloop
13895
    for (i=0; i<ni; i++) {
13896
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
13897
     /* test for range errors (not always needed but do it anyway) */
13898
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13899
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13900
      nrange += xp[i] > LONGLONG_MAX ;
13901
    }
13902
   /* update xpp and tp */
13903
    if (realign) xp = (uint *) *xpp;
13904
    xp += ni;
13905
    tp += ni;
13906
    *xpp = (void*)xp;
13907
  }
13908
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13909
13910
#else   /* not SX */
13911
0
  const char *xp = (const char *) *xpp;
13912
0
  int status = NC_NOERR;
13913
13914
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13915
0
  {
13916
0
    const int lstatus = ncx_get_uint_longlong(xp, tp);
13917
0
    if (status == NC_NOERR) /* report the first encountered error */
13918
0
      status = lstatus;
13919
0
  }
13920
13921
0
  *xpp = (const void *)xp;
13922
0
  return status;
13923
0
#endif
13924
0
}
13925
13926
int
13927
ncx_getn_uint_uchar(const void **xpp, size_t nelems, uchar *tp)
13928
0
{
13929
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13930
13931
 /* basic algorithm is:
13932
  *   - ensure sane alignment of input data
13933
  *   - copy (conversion happens automatically) input data
13934
  *     to output
13935
  *   - update xpp to point at next unconverted input, and tp to point
13936
  *     at next location for converted output
13937
  */
13938
  long i, j, ni;
13939
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13940
  uint *xp;
13941
  int nrange = 0;         /* number of range errors */
13942
  int realign = 0;        /* "do we need to fix input data alignment?" */
13943
  long cxp = (long) *((char**)xpp);
13944
13945
  realign = (cxp & 7) % SIZEOF_UINT;
13946
  /* sjl: manually stripmine so we can limit amount of
13947
   * vector work space reserved to LOOPCNT elements. Also
13948
   * makes vectorisation easy */
13949
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13950
    ni=Min(nelems-j,LOOPCNT);
13951
    if (realign) {
13952
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13953
      xp = tmp;
13954
    } else {
13955
      xp = (uint *) *xpp;
13956
    }
13957
   /* copy the next block */
13958
#pragma cdir loopcnt=LOOPCNT
13959
#pragma cdir shortloop
13960
    for (i=0; i<ni; i++) {
13961
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
13962
     /* test for range errors (not always needed but do it anyway) */
13963
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13964
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13965
      nrange += xp[i] > UCHAR_MAX ;
13966
    }
13967
   /* update xpp and tp */
13968
    if (realign) xp = (uint *) *xpp;
13969
    xp += ni;
13970
    tp += ni;
13971
    *xpp = (void*)xp;
13972
  }
13973
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13974
13975
#else   /* not SX */
13976
0
  const char *xp = (const char *) *xpp;
13977
0
  int status = NC_NOERR;
13978
13979
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13980
0
  {
13981
0
    const int lstatus = ncx_get_uint_uchar(xp, tp);
13982
0
    if (status == NC_NOERR) /* report the first encountered error */
13983
0
      status = lstatus;
13984
0
  }
13985
13986
0
  *xpp = (const void *)xp;
13987
0
  return status;
13988
0
#endif
13989
0
}
13990
13991
int
13992
ncx_getn_uint_ushort(const void **xpp, size_t nelems, ushort *tp)
13993
0
{
13994
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13995
13996
 /* basic algorithm is:
13997
  *   - ensure sane alignment of input data
13998
  *   - copy (conversion happens automatically) input data
13999
  *     to output
14000
  *   - update xpp to point at next unconverted input, and tp to point
14001
  *     at next location for converted output
14002
  */
14003
  long i, j, ni;
14004
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14005
  uint *xp;
14006
  int nrange = 0;         /* number of range errors */
14007
  int realign = 0;        /* "do we need to fix input data alignment?" */
14008
  long cxp = (long) *((char**)xpp);
14009
14010
  realign = (cxp & 7) % SIZEOF_UINT;
14011
  /* sjl: manually stripmine so we can limit amount of
14012
   * vector work space reserved to LOOPCNT elements. Also
14013
   * makes vectorisation easy */
14014
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14015
    ni=Min(nelems-j,LOOPCNT);
14016
    if (realign) {
14017
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
14018
      xp = tmp;
14019
    } else {
14020
      xp = (uint *) *xpp;
14021
    }
14022
   /* copy the next block */
14023
#pragma cdir loopcnt=LOOPCNT
14024
#pragma cdir shortloop
14025
    for (i=0; i<ni; i++) {
14026
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
14027
     /* test for range errors (not always needed but do it anyway) */
14028
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14029
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14030
      nrange += xp[i] > USHORT_MAX ;
14031
    }
14032
   /* update xpp and tp */
14033
    if (realign) xp = (uint *) *xpp;
14034
    xp += ni;
14035
    tp += ni;
14036
    *xpp = (void*)xp;
14037
  }
14038
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14039
14040
#else   /* not SX */
14041
0
  const char *xp = (const char *) *xpp;
14042
0
  int status = NC_NOERR;
14043
14044
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14045
0
  {
14046
0
    const int lstatus = ncx_get_uint_ushort(xp, tp);
14047
0
    if (status == NC_NOERR) /* report the first encountered error */
14048
0
      status = lstatus;
14049
0
  }
14050
14051
0
  *xpp = (const void *)xp;
14052
0
  return status;
14053
0
#endif
14054
0
}
14055
14056
int
14057
ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
14058
0
{
14059
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14060
14061
 /* basic algorithm is:
14062
  *   - ensure sane alignment of input data
14063
  *   - copy (conversion happens automatically) input data
14064
  *     to output
14065
  *   - update xpp to point at next unconverted input, and tp to point
14066
  *     at next location for converted output
14067
  */
14068
  long i, j, ni;
14069
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14070
  uint *xp;
14071
  int nrange = 0;         /* number of range errors */
14072
  int realign = 0;        /* "do we need to fix input data alignment?" */
14073
  long cxp = (long) *((char**)xpp);
14074
14075
  realign = (cxp & 7) % SIZEOF_UINT;
14076
  /* sjl: manually stripmine so we can limit amount of
14077
   * vector work space reserved to LOOPCNT elements. Also
14078
   * makes vectorisation easy */
14079
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14080
    ni=Min(nelems-j,LOOPCNT);
14081
    if (realign) {
14082
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
14083
      xp = tmp;
14084
    } else {
14085
      xp = (uint *) *xpp;
14086
    }
14087
   /* copy the next block */
14088
#pragma cdir loopcnt=LOOPCNT
14089
#pragma cdir shortloop
14090
    for (i=0; i<ni; i++) {
14091
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
14092
     /* test for range errors (not always needed but do it anyway) */
14093
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14094
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14095
      nrange += xp[i] > ULONGLONG_MAX ;
14096
    }
14097
   /* update xpp and tp */
14098
    if (realign) xp = (uint *) *xpp;
14099
    xp += ni;
14100
    tp += ni;
14101
    *xpp = (void*)xp;
14102
  }
14103
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14104
14105
#else   /* not SX */
14106
0
  const char *xp = (const char *) *xpp;
14107
0
  int status = NC_NOERR;
14108
14109
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14110
0
  {
14111
0
    const int lstatus = ncx_get_uint_ulonglong(xp, tp);
14112
0
    if (status == NC_NOERR) /* report the first encountered error */
14113
0
      status = lstatus;
14114
0
  }
14115
14116
0
  *xpp = (const void *)xp;
14117
0
  return status;
14118
0
#endif
14119
0
}
14120
14121
14122
#if X_SIZEOF_UINT == SIZEOF_UINT
14123
/* optimized version */
14124
int
14125
ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp, void *fillp)
14126
0
{
14127
#ifdef WORDS_BIGENDIAN
14128
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
14129
# else
14130
0
  swapn4b(*xpp, tp, nelems);
14131
0
# endif
14132
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
14133
0
  return NC_NOERR;
14134
0
}
14135
#else
14136
int
14137
ncx_putn_uint_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
14138
{
14139
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14140
14141
 /* basic algorithm is:
14142
  *   - ensure sane alignment of output data
14143
  *   - copy (conversion happens automatically) input data
14144
  *     to output
14145
  *   - update tp to point at next unconverted input, and xpp to point
14146
  *     at next location for converted output
14147
  */
14148
  long i, j, ni;
14149
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14150
  uint *xp;
14151
  int nrange = 0;         /* number of range errors */
14152
  int realign = 0;        /* "do we need to fix input data alignment?" */
14153
  long cxp = (long) *((char**)xpp);
14154
14155
  realign = (cxp & 7) % SIZEOF_UINT;
14156
  /* sjl: manually stripmine so we can limit amount of
14157
   * vector work space reserved to LOOPCNT elements. Also
14158
   * makes vectorisation easy */
14159
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14160
    ni=Min(nelems-j,LOOPCNT);
14161
    if (realign) {
14162
      xp = tmp;
14163
    } else {
14164
      xp = (uint *) *xpp;
14165
    }
14166
   /* copy the next block */
14167
#pragma cdir loopcnt=LOOPCNT
14168
#pragma cdir shortloop
14169
    for (i=0; i<ni; i++) {
14170
      /* the normal case: */
14171
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14172
     /* test for range errors (not always needed but do it anyway) */
14173
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14174
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14175
      nrange += tp[i] > X_UINT_MAX ;
14176
    }
14177
   /* copy workspace back if necessary */
14178
    if (realign) {
14179
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14180
      xp = (uint *) *xpp;
14181
    }
14182
   /* update xpp and tp */
14183
    xp += ni;
14184
    tp += ni;
14185
    *xpp = (void*)xp;
14186
  }
14187
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14188
14189
#else   /* not SX */
14190
14191
  char *xp = (char *) *xpp;
14192
  int status = NC_NOERR;
14193
14194
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14195
  {
14196
    int lstatus = ncx_put_uint_uint(xp, tp, fillp);
14197
    if (status == NC_NOERR) /* report the first encountered error */
14198
      status = lstatus;
14199
  }
14200
14201
  *xpp = (void *)xp;
14202
  return status;
14203
#endif
14204
}
14205
14206
#endif
14207
int
14208
ncx_putn_uint_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
14209
0
{
14210
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14211
14212
 /* basic algorithm is:
14213
  *   - ensure sane alignment of output data
14214
  *   - copy (conversion happens automatically) input data
14215
  *     to output
14216
  *   - update tp to point at next unconverted input, and xpp to point
14217
  *     at next location for converted output
14218
  */
14219
  long i, j, ni;
14220
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14221
  uint *xp;
14222
  int nrange = 0;         /* number of range errors */
14223
  int realign = 0;        /* "do we need to fix input data alignment?" */
14224
  long cxp = (long) *((char**)xpp);
14225
14226
  realign = (cxp & 7) % SIZEOF_UINT;
14227
  /* sjl: manually stripmine so we can limit amount of
14228
   * vector work space reserved to LOOPCNT elements. Also
14229
   * makes vectorisation easy */
14230
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14231
    ni=Min(nelems-j,LOOPCNT);
14232
    if (realign) {
14233
      xp = tmp;
14234
    } else {
14235
      xp = (uint *) *xpp;
14236
    }
14237
   /* copy the next block */
14238
#pragma cdir loopcnt=LOOPCNT
14239
#pragma cdir shortloop
14240
    for (i=0; i<ni; i++) {
14241
      /* the normal case: */
14242
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14243
     /* test for range errors (not always needed but do it anyway) */
14244
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14245
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14246
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14247
    }
14248
   /* copy workspace back if necessary */
14249
    if (realign) {
14250
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14251
      xp = (uint *) *xpp;
14252
    }
14253
   /* update xpp and tp */
14254
    xp += ni;
14255
    tp += ni;
14256
    *xpp = (void*)xp;
14257
  }
14258
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14259
14260
#else   /* not SX */
14261
14262
0
  char *xp = (char *) *xpp;
14263
0
  int status = NC_NOERR;
14264
14265
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14266
0
  {
14267
0
    int lstatus = ncx_put_uint_schar(xp, tp, fillp);
14268
0
    if (status == NC_NOERR) /* report the first encountered error */
14269
0
      status = lstatus;
14270
0
  }
14271
14272
0
  *xpp = (void *)xp;
14273
0
  return status;
14274
0
#endif
14275
0
}
14276
14277
int
14278
ncx_putn_uint_short(void **xpp, size_t nelems, const short *tp, void *fillp)
14279
0
{
14280
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14281
14282
 /* basic algorithm is:
14283
  *   - ensure sane alignment of output data
14284
  *   - copy (conversion happens automatically) input data
14285
  *     to output
14286
  *   - update tp to point at next unconverted input, and xpp to point
14287
  *     at next location for converted output
14288
  */
14289
  long i, j, ni;
14290
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14291
  uint *xp;
14292
  int nrange = 0;         /* number of range errors */
14293
  int realign = 0;        /* "do we need to fix input data alignment?" */
14294
  long cxp = (long) *((char**)xpp);
14295
14296
  realign = (cxp & 7) % SIZEOF_UINT;
14297
  /* sjl: manually stripmine so we can limit amount of
14298
   * vector work space reserved to LOOPCNT elements. Also
14299
   * makes vectorisation easy */
14300
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14301
    ni=Min(nelems-j,LOOPCNT);
14302
    if (realign) {
14303
      xp = tmp;
14304
    } else {
14305
      xp = (uint *) *xpp;
14306
    }
14307
   /* copy the next block */
14308
#pragma cdir loopcnt=LOOPCNT
14309
#pragma cdir shortloop
14310
    for (i=0; i<ni; i++) {
14311
      /* the normal case: */
14312
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14313
     /* test for range errors (not always needed but do it anyway) */
14314
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14315
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14316
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14317
    }
14318
   /* copy workspace back if necessary */
14319
    if (realign) {
14320
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14321
      xp = (uint *) *xpp;
14322
    }
14323
   /* update xpp and tp */
14324
    xp += ni;
14325
    tp += ni;
14326
    *xpp = (void*)xp;
14327
  }
14328
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14329
14330
#else   /* not SX */
14331
14332
0
  char *xp = (char *) *xpp;
14333
0
  int status = NC_NOERR;
14334
14335
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14336
0
  {
14337
0
    int lstatus = ncx_put_uint_short(xp, tp, fillp);
14338
0
    if (status == NC_NOERR) /* report the first encountered error */
14339
0
      status = lstatus;
14340
0
  }
14341
14342
0
  *xpp = (void *)xp;
14343
0
  return status;
14344
0
#endif
14345
0
}
14346
14347
int
14348
ncx_putn_uint_int(void **xpp, size_t nelems, const int *tp, void *fillp)
14349
0
{
14350
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14351
14352
 /* basic algorithm is:
14353
  *   - ensure sane alignment of output data
14354
  *   - copy (conversion happens automatically) input data
14355
  *     to output
14356
  *   - update tp to point at next unconverted input, and xpp to point
14357
  *     at next location for converted output
14358
  */
14359
  long i, j, ni;
14360
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14361
  uint *xp;
14362
  int nrange = 0;         /* number of range errors */
14363
  int realign = 0;        /* "do we need to fix input data alignment?" */
14364
  long cxp = (long) *((char**)xpp);
14365
14366
  realign = (cxp & 7) % SIZEOF_UINT;
14367
  /* sjl: manually stripmine so we can limit amount of
14368
   * vector work space reserved to LOOPCNT elements. Also
14369
   * makes vectorisation easy */
14370
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14371
    ni=Min(nelems-j,LOOPCNT);
14372
    if (realign) {
14373
      xp = tmp;
14374
    } else {
14375
      xp = (uint *) *xpp;
14376
    }
14377
   /* copy the next block */
14378
#pragma cdir loopcnt=LOOPCNT
14379
#pragma cdir shortloop
14380
    for (i=0; i<ni; i++) {
14381
      /* the normal case: */
14382
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14383
     /* test for range errors (not always needed but do it anyway) */
14384
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14385
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14386
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14387
    }
14388
   /* copy workspace back if necessary */
14389
    if (realign) {
14390
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14391
      xp = (uint *) *xpp;
14392
    }
14393
   /* update xpp and tp */
14394
    xp += ni;
14395
    tp += ni;
14396
    *xpp = (void*)xp;
14397
  }
14398
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14399
14400
#else   /* not SX */
14401
14402
0
  char *xp = (char *) *xpp;
14403
0
  int status = NC_NOERR;
14404
14405
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14406
0
  {
14407
0
    int lstatus = ncx_put_uint_int(xp, tp, fillp);
14408
0
    if (status == NC_NOERR) /* report the first encountered error */
14409
0
      status = lstatus;
14410
0
  }
14411
14412
0
  *xpp = (void *)xp;
14413
0
  return status;
14414
0
#endif
14415
0
}
14416
14417
int
14418
ncx_putn_uint_long(void **xpp, size_t nelems, const long *tp, void *fillp)
14419
0
{
14420
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14421
14422
 /* basic algorithm is:
14423
  *   - ensure sane alignment of output data
14424
  *   - copy (conversion happens automatically) input data
14425
  *     to output
14426
  *   - update tp to point at next unconverted input, and xpp to point
14427
  *     at next location for converted output
14428
  */
14429
  long i, j, ni;
14430
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14431
  uint *xp;
14432
  int nrange = 0;         /* number of range errors */
14433
  int realign = 0;        /* "do we need to fix input data alignment?" */
14434
  long cxp = (long) *((char**)xpp);
14435
14436
  realign = (cxp & 7) % SIZEOF_UINT;
14437
  /* sjl: manually stripmine so we can limit amount of
14438
   * vector work space reserved to LOOPCNT elements. Also
14439
   * makes vectorisation easy */
14440
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14441
    ni=Min(nelems-j,LOOPCNT);
14442
    if (realign) {
14443
      xp = tmp;
14444
    } else {
14445
      xp = (uint *) *xpp;
14446
    }
14447
   /* copy the next block */
14448
#pragma cdir loopcnt=LOOPCNT
14449
#pragma cdir shortloop
14450
    for (i=0; i<ni; i++) {
14451
      /* the normal case: */
14452
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14453
     /* test for range errors (not always needed but do it anyway) */
14454
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14455
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14456
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14457
    }
14458
   /* copy workspace back if necessary */
14459
    if (realign) {
14460
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14461
      xp = (uint *) *xpp;
14462
    }
14463
   /* update xpp and tp */
14464
    xp += ni;
14465
    tp += ni;
14466
    *xpp = (void*)xp;
14467
  }
14468
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14469
14470
#else   /* not SX */
14471
14472
0
  char *xp = (char *) *xpp;
14473
0
  int status = NC_NOERR;
14474
14475
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14476
0
  {
14477
0
    int lstatus = ncx_put_uint_long(xp, tp, fillp);
14478
0
    if (status == NC_NOERR) /* report the first encountered error */
14479
0
      status = lstatus;
14480
0
  }
14481
14482
0
  *xpp = (void *)xp;
14483
0
  return status;
14484
0
#endif
14485
0
}
14486
14487
int
14488
ncx_putn_uint_float(void **xpp, size_t nelems, const float *tp, void *fillp)
14489
0
{
14490
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14491
14492
 /* basic algorithm is:
14493
  *   - ensure sane alignment of output data
14494
  *   - copy (conversion happens automatically) input data
14495
  *     to output
14496
  *   - update tp to point at next unconverted input, and xpp to point
14497
  *     at next location for converted output
14498
  */
14499
  long i, j, ni;
14500
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14501
  uint *xp;
14502
  int nrange = 0;         /* number of range errors */
14503
  int realign = 0;        /* "do we need to fix input data alignment?" */
14504
  long cxp = (long) *((char**)xpp);
14505
14506
  realign = (cxp & 7) % SIZEOF_UINT;
14507
  /* sjl: manually stripmine so we can limit amount of
14508
   * vector work space reserved to LOOPCNT elements. Also
14509
   * makes vectorisation easy */
14510
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14511
    ni=Min(nelems-j,LOOPCNT);
14512
    if (realign) {
14513
      xp = tmp;
14514
    } else {
14515
      xp = (uint *) *xpp;
14516
    }
14517
   /* copy the next block */
14518
#pragma cdir loopcnt=LOOPCNT
14519
#pragma cdir shortloop
14520
    for (i=0; i<ni; i++) {
14521
      /* the normal case: */
14522
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14523
     /* test for range errors (not always needed but do it anyway) */
14524
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14525
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14526
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14527
    }
14528
   /* copy workspace back if necessary */
14529
    if (realign) {
14530
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14531
      xp = (uint *) *xpp;
14532
    }
14533
   /* update xpp and tp */
14534
    xp += ni;
14535
    tp += ni;
14536
    *xpp = (void*)xp;
14537
  }
14538
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14539
14540
#else   /* not SX */
14541
14542
0
  char *xp = (char *) *xpp;
14543
0
  int status = NC_NOERR;
14544
14545
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14546
0
  {
14547
0
    int lstatus = ncx_put_uint_float(xp, tp, fillp);
14548
0
    if (status == NC_NOERR) /* report the first encountered error */
14549
0
      status = lstatus;
14550
0
  }
14551
14552
0
  *xpp = (void *)xp;
14553
0
  return status;
14554
0
#endif
14555
0
}
14556
14557
int
14558
ncx_putn_uint_double(void **xpp, size_t nelems, const double *tp, void *fillp)
14559
0
{
14560
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14561
14562
 /* basic algorithm is:
14563
  *   - ensure sane alignment of output data
14564
  *   - copy (conversion happens automatically) input data
14565
  *     to output
14566
  *   - update tp to point at next unconverted input, and xpp to point
14567
  *     at next location for converted output
14568
  */
14569
  long i, j, ni;
14570
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14571
  uint *xp;
14572
  int nrange = 0;         /* number of range errors */
14573
  int realign = 0;        /* "do we need to fix input data alignment?" */
14574
  long cxp = (long) *((char**)xpp);
14575
14576
  realign = (cxp & 7) % SIZEOF_UINT;
14577
  /* sjl: manually stripmine so we can limit amount of
14578
   * vector work space reserved to LOOPCNT elements. Also
14579
   * makes vectorisation easy */
14580
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14581
    ni=Min(nelems-j,LOOPCNT);
14582
    if (realign) {
14583
      xp = tmp;
14584
    } else {
14585
      xp = (uint *) *xpp;
14586
    }
14587
   /* copy the next block */
14588
#pragma cdir loopcnt=LOOPCNT
14589
#pragma cdir shortloop
14590
    for (i=0; i<ni; i++) {
14591
      /* the normal case: */
14592
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14593
     /* test for range errors (not always needed but do it anyway) */
14594
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14595
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14596
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14597
    }
14598
   /* copy workspace back if necessary */
14599
    if (realign) {
14600
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14601
      xp = (uint *) *xpp;
14602
    }
14603
   /* update xpp and tp */
14604
    xp += ni;
14605
    tp += ni;
14606
    *xpp = (void*)xp;
14607
  }
14608
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14609
14610
#else   /* not SX */
14611
14612
0
  char *xp = (char *) *xpp;
14613
0
  int status = NC_NOERR;
14614
14615
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14616
0
  {
14617
0
    int lstatus = ncx_put_uint_double(xp, tp, fillp);
14618
0
    if (status == NC_NOERR) /* report the first encountered error */
14619
0
      status = lstatus;
14620
0
  }
14621
14622
0
  *xpp = (void *)xp;
14623
0
  return status;
14624
0
#endif
14625
0
}
14626
14627
int
14628
ncx_putn_uint_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
14629
0
{
14630
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14631
14632
 /* basic algorithm is:
14633
  *   - ensure sane alignment of output data
14634
  *   - copy (conversion happens automatically) input data
14635
  *     to output
14636
  *   - update tp to point at next unconverted input, and xpp to point
14637
  *     at next location for converted output
14638
  */
14639
  long i, j, ni;
14640
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14641
  uint *xp;
14642
  int nrange = 0;         /* number of range errors */
14643
  int realign = 0;        /* "do we need to fix input data alignment?" */
14644
  long cxp = (long) *((char**)xpp);
14645
14646
  realign = (cxp & 7) % SIZEOF_UINT;
14647
  /* sjl: manually stripmine so we can limit amount of
14648
   * vector work space reserved to LOOPCNT elements. Also
14649
   * makes vectorisation easy */
14650
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14651
    ni=Min(nelems-j,LOOPCNT);
14652
    if (realign) {
14653
      xp = tmp;
14654
    } else {
14655
      xp = (uint *) *xpp;
14656
    }
14657
   /* copy the next block */
14658
#pragma cdir loopcnt=LOOPCNT
14659
#pragma cdir shortloop
14660
    for (i=0; i<ni; i++) {
14661
      /* the normal case: */
14662
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14663
     /* test for range errors (not always needed but do it anyway) */
14664
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14665
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14666
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14667
    }
14668
   /* copy workspace back if necessary */
14669
    if (realign) {
14670
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14671
      xp = (uint *) *xpp;
14672
    }
14673
   /* update xpp and tp */
14674
    xp += ni;
14675
    tp += ni;
14676
    *xpp = (void*)xp;
14677
  }
14678
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14679
14680
#else   /* not SX */
14681
14682
0
  char *xp = (char *) *xpp;
14683
0
  int status = NC_NOERR;
14684
14685
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14686
0
  {
14687
0
    int lstatus = ncx_put_uint_longlong(xp, tp, fillp);
14688
0
    if (status == NC_NOERR) /* report the first encountered error */
14689
0
      status = lstatus;
14690
0
  }
14691
14692
0
  *xpp = (void *)xp;
14693
0
  return status;
14694
0
#endif
14695
0
}
14696
14697
int
14698
ncx_putn_uint_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
14699
0
{
14700
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14701
14702
 /* basic algorithm is:
14703
  *   - ensure sane alignment of output data
14704
  *   - copy (conversion happens automatically) input data
14705
  *     to output
14706
  *   - update tp to point at next unconverted input, and xpp to point
14707
  *     at next location for converted output
14708
  */
14709
  long i, j, ni;
14710
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14711
  uint *xp;
14712
  int nrange = 0;         /* number of range errors */
14713
  int realign = 0;        /* "do we need to fix input data alignment?" */
14714
  long cxp = (long) *((char**)xpp);
14715
14716
  realign = (cxp & 7) % SIZEOF_UINT;
14717
  /* sjl: manually stripmine so we can limit amount of
14718
   * vector work space reserved to LOOPCNT elements. Also
14719
   * makes vectorisation easy */
14720
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14721
    ni=Min(nelems-j,LOOPCNT);
14722
    if (realign) {
14723
      xp = tmp;
14724
    } else {
14725
      xp = (uint *) *xpp;
14726
    }
14727
   /* copy the next block */
14728
#pragma cdir loopcnt=LOOPCNT
14729
#pragma cdir shortloop
14730
    for (i=0; i<ni; i++) {
14731
      /* the normal case: */
14732
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14733
     /* test for range errors (not always needed but do it anyway) */
14734
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14735
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14736
      nrange += tp[i] > X_UINT_MAX ;
14737
    }
14738
   /* copy workspace back if necessary */
14739
    if (realign) {
14740
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14741
      xp = (uint *) *xpp;
14742
    }
14743
   /* update xpp and tp */
14744
    xp += ni;
14745
    tp += ni;
14746
    *xpp = (void*)xp;
14747
  }
14748
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14749
14750
#else   /* not SX */
14751
14752
0
  char *xp = (char *) *xpp;
14753
0
  int status = NC_NOERR;
14754
14755
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14756
0
  {
14757
0
    int lstatus = ncx_put_uint_uchar(xp, tp, fillp);
14758
0
    if (status == NC_NOERR) /* report the first encountered error */
14759
0
      status = lstatus;
14760
0
  }
14761
14762
0
  *xpp = (void *)xp;
14763
0
  return status;
14764
0
#endif
14765
0
}
14766
14767
int
14768
ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
14769
0
{
14770
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14771
14772
 /* basic algorithm is:
14773
  *   - ensure sane alignment of output data
14774
  *   - copy (conversion happens automatically) input data
14775
  *     to output
14776
  *   - update tp to point at next unconverted input, and xpp to point
14777
  *     at next location for converted output
14778
  */
14779
  long i, j, ni;
14780
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14781
  uint *xp;
14782
  int nrange = 0;         /* number of range errors */
14783
  int realign = 0;        /* "do we need to fix input data alignment?" */
14784
  long cxp = (long) *((char**)xpp);
14785
14786
  realign = (cxp & 7) % SIZEOF_UINT;
14787
  /* sjl: manually stripmine so we can limit amount of
14788
   * vector work space reserved to LOOPCNT elements. Also
14789
   * makes vectorisation easy */
14790
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14791
    ni=Min(nelems-j,LOOPCNT);
14792
    if (realign) {
14793
      xp = tmp;
14794
    } else {
14795
      xp = (uint *) *xpp;
14796
    }
14797
   /* copy the next block */
14798
#pragma cdir loopcnt=LOOPCNT
14799
#pragma cdir shortloop
14800
    for (i=0; i<ni; i++) {
14801
      /* the normal case: */
14802
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14803
     /* test for range errors (not always needed but do it anyway) */
14804
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14805
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14806
      nrange += tp[i] > X_UINT_MAX ;
14807
    }
14808
   /* copy workspace back if necessary */
14809
    if (realign) {
14810
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14811
      xp = (uint *) *xpp;
14812
    }
14813
   /* update xpp and tp */
14814
    xp += ni;
14815
    tp += ni;
14816
    *xpp = (void*)xp;
14817
  }
14818
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14819
14820
#else   /* not SX */
14821
14822
0
  char *xp = (char *) *xpp;
14823
0
  int status = NC_NOERR;
14824
14825
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14826
0
  {
14827
0
    int lstatus = ncx_put_uint_ushort(xp, tp, fillp);
14828
0
    if (status == NC_NOERR) /* report the first encountered error */
14829
0
      status = lstatus;
14830
0
  }
14831
14832
0
  *xpp = (void *)xp;
14833
0
  return status;
14834
0
#endif
14835
0
}
14836
14837
int
14838
ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
14839
0
{
14840
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14841
14842
 /* basic algorithm is:
14843
  *   - ensure sane alignment of output data
14844
  *   - copy (conversion happens automatically) input data
14845
  *     to output
14846
  *   - update tp to point at next unconverted input, and xpp to point
14847
  *     at next location for converted output
14848
  */
14849
  long i, j, ni;
14850
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14851
  uint *xp;
14852
  int nrange = 0;         /* number of range errors */
14853
  int realign = 0;        /* "do we need to fix input data alignment?" */
14854
  long cxp = (long) *((char**)xpp);
14855
14856
  realign = (cxp & 7) % SIZEOF_UINT;
14857
  /* sjl: manually stripmine so we can limit amount of
14858
   * vector work space reserved to LOOPCNT elements. Also
14859
   * makes vectorisation easy */
14860
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14861
    ni=Min(nelems-j,LOOPCNT);
14862
    if (realign) {
14863
      xp = tmp;
14864
    } else {
14865
      xp = (uint *) *xpp;
14866
    }
14867
   /* copy the next block */
14868
#pragma cdir loopcnt=LOOPCNT
14869
#pragma cdir shortloop
14870
    for (i=0; i<ni; i++) {
14871
      /* the normal case: */
14872
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14873
     /* test for range errors (not always needed but do it anyway) */
14874
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14875
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14876
      nrange += tp[i] > X_UINT_MAX ;
14877
    }
14878
   /* copy workspace back if necessary */
14879
    if (realign) {
14880
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14881
      xp = (uint *) *xpp;
14882
    }
14883
   /* update xpp and tp */
14884
    xp += ni;
14885
    tp += ni;
14886
    *xpp = (void*)xp;
14887
  }
14888
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14889
14890
#else   /* not SX */
14891
14892
0
  char *xp = (char *) *xpp;
14893
0
  int status = NC_NOERR;
14894
14895
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14896
0
  {
14897
0
    int lstatus = ncx_put_uint_ulonglong(xp, tp, fillp);
14898
0
    if (status == NC_NOERR) /* report the first encountered error */
14899
0
      status = lstatus;
14900
0
  }
14901
14902
0
  *xpp = (void *)xp;
14903
0
  return status;
14904
0
#endif
14905
0
}
14906
14907
14908
14909
/* float ---------------------------------------------------------------------*/
14910
14911
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
14912
/* optimized version */
14913
int
14914
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14915
18.4k
{
14916
#ifdef WORDS_BIGENDIAN
14917
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
14918
# else
14919
18.4k
  swapn4b(tp, *xpp, nelems);
14920
18.4k
# endif
14921
18.4k
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
14922
18.4k
  return NC_NOERR;
14923
18.4k
}
14924
#elif defined(vax) && vax != 0
14925
int
14926
ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
14927
{
14928
  float *const end = ip + nfloats;
14929
14930
  while (ip < end)
14931
  {
14932
    struct vax_single *const vsp = (struct vax_single *) ip;
14933
    const struct ieee_single *const isp =
14934
       (const struct ieee_single *) (*xpp);
14935
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
14936
14937
    switch(exp) {
14938
    case 0 :
14939
      /* ieee subnormal */
14940
      if (isp->mant_hi == min.ieee.mant_hi
14941
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
14942
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
14943
      {
14944
        *vsp = min.s;
14945
      }
14946
      else
14947
      {
14948
        unsigned mantissa = (isp->mant_hi << 16)
14949
           | isp->mant_lo_hi << 8
14950
           | isp->mant_lo_lo;
14951
        unsigned tmp = mantissa >> 20;
14952
        if (tmp >= 4) {
14953
          vsp->exp = 2;
14954
        } else if (tmp >= 2) {
14955
          vsp->exp = 1;
14956
        } else {
14957
          *vsp = min.s;
14958
          break;
14959
        } /* else */
14960
        tmp = mantissa - (1 << (20 + vsp->exp ));
14961
        tmp <<= 3 - vsp->exp;
14962
        vsp->mantissa2 = tmp;
14963
        vsp->mantissa1 = (tmp >> 16);
14964
      }
14965
      break;
14966
    case 0xfe :
14967
    case 0xff :
14968
      *vsp = max.s;
14969
      break;
14970
    default :
14971
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
14972
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
14973
      vsp->mantissa1 = isp->mant_hi;
14974
    }
14975
14976
    vsp->sign = isp->sign;
14977
14978
14979
    ip++;
14980
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
14981
  }
14982
  return NC_NOERR;
14983
}
14984
#else
14985
int
14986
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14987
{
14988
  const char *xp = *xpp;
14989
  int status = NC_NOERR;
14990
14991
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14992
  {
14993
    const int lstatus = ncx_get_float_float(xp, tp, fillp);
14994
    if (status == NC_NOERR) /* report the first encountered error */
14995
      status = lstatus;
14996
  }
14997
14998
  *xpp = (const void *)xp;
14999
  return status;
15000
}
15001
15002
#endif
15003
int
15004
ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
15005
0
{
15006
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15007
15008
 /* basic algorithm is:
15009
  *   - ensure sane alignment of input data
15010
  *   - copy (conversion happens automatically) input data
15011
  *     to output
15012
  *   - update xpp to point at next unconverted input, and tp to point
15013
  *     at next location for converted output
15014
  */
15015
  long i, j, ni;
15016
  float tmp[LOOPCNT];        /* in case input is misaligned */
15017
  float *xp;
15018
  int nrange = 0;         /* number of range errors */
15019
  int realign = 0;        /* "do we need to fix input data alignment?" */
15020
  long cxp = (long) *((char**)xpp);
15021
15022
  realign = (cxp & 7) % SIZEOF_FLOAT;
15023
  /* sjl: manually stripmine so we can limit amount of
15024
   * vector work space reserved to LOOPCNT elements. Also
15025
   * makes vectorisation easy */
15026
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15027
    ni=Min(nelems-j,LOOPCNT);
15028
    if (realign) {
15029
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15030
      xp = tmp;
15031
    } else {
15032
      xp = (float *) *xpp;
15033
    }
15034
   /* copy the next block */
15035
#pragma cdir loopcnt=LOOPCNT
15036
#pragma cdir shortloop
15037
    for (i=0; i<ni; i++) {
15038
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
15039
     /* test for range errors (not always needed but do it anyway) */
15040
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15041
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15042
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
15043
    }
15044
   /* update xpp and tp */
15045
    if (realign) xp = (float *) *xpp;
15046
    xp += ni;
15047
    tp += ni;
15048
    *xpp = (void*)xp;
15049
  }
15050
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15051
15052
#else   /* not SX */
15053
0
  const char *xp = (const char *) *xpp;
15054
0
  int status = NC_NOERR;
15055
15056
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15057
0
  {
15058
0
    const int lstatus = ncx_get_float_schar(xp, tp);
15059
0
    if (status == NC_NOERR) /* report the first encountered error */
15060
0
      status = lstatus;
15061
0
  }
15062
15063
0
  *xpp = (const void *)xp;
15064
0
  return status;
15065
0
#endif
15066
0
}
15067
15068
int
15069
ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
15070
0
{
15071
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15072
15073
 /* basic algorithm is:
15074
  *   - ensure sane alignment of input data
15075
  *   - copy (conversion happens automatically) input data
15076
  *     to output
15077
  *   - update xpp to point at next unconverted input, and tp to point
15078
  *     at next location for converted output
15079
  */
15080
  long i, j, ni;
15081
  float tmp[LOOPCNT];        /* in case input is misaligned */
15082
  float *xp;
15083
  int nrange = 0;         /* number of range errors */
15084
  int realign = 0;        /* "do we need to fix input data alignment?" */
15085
  long cxp = (long) *((char**)xpp);
15086
15087
  realign = (cxp & 7) % SIZEOF_FLOAT;
15088
  /* sjl: manually stripmine so we can limit amount of
15089
   * vector work space reserved to LOOPCNT elements. Also
15090
   * makes vectorisation easy */
15091
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15092
    ni=Min(nelems-j,LOOPCNT);
15093
    if (realign) {
15094
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15095
      xp = tmp;
15096
    } else {
15097
      xp = (float *) *xpp;
15098
    }
15099
   /* copy the next block */
15100
#pragma cdir loopcnt=LOOPCNT
15101
#pragma cdir shortloop
15102
    for (i=0; i<ni; i++) {
15103
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
15104
     /* test for range errors (not always needed but do it anyway) */
15105
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15106
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15107
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
15108
    }
15109
   /* update xpp and tp */
15110
    if (realign) xp = (float *) *xpp;
15111
    xp += ni;
15112
    tp += ni;
15113
    *xpp = (void*)xp;
15114
  }
15115
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15116
15117
#else   /* not SX */
15118
0
  const char *xp = (const char *) *xpp;
15119
0
  int status = NC_NOERR;
15120
15121
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15122
0
  {
15123
0
    const int lstatus = ncx_get_float_short(xp, tp);
15124
0
    if (status == NC_NOERR) /* report the first encountered error */
15125
0
      status = lstatus;
15126
0
  }
15127
15128
0
  *xpp = (const void *)xp;
15129
0
  return status;
15130
0
#endif
15131
0
}
15132
15133
int
15134
ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
15135
0
{
15136
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15137
15138
 /* basic algorithm is:
15139
  *   - ensure sane alignment of input data
15140
  *   - copy (conversion happens automatically) input data
15141
  *     to output
15142
  *   - update xpp to point at next unconverted input, and tp to point
15143
  *     at next location for converted output
15144
  */
15145
  long i, j, ni;
15146
  float tmp[LOOPCNT];        /* in case input is misaligned */
15147
  float *xp;
15148
  int nrange = 0;         /* number of range errors */
15149
  int realign = 0;        /* "do we need to fix input data alignment?" */
15150
  long cxp = (long) *((char**)xpp);
15151
15152
  realign = (cxp & 7) % SIZEOF_FLOAT;
15153
  /* sjl: manually stripmine so we can limit amount of
15154
   * vector work space reserved to LOOPCNT elements. Also
15155
   * makes vectorisation easy */
15156
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15157
    ni=Min(nelems-j,LOOPCNT);
15158
    if (realign) {
15159
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15160
      xp = tmp;
15161
    } else {
15162
      xp = (float *) *xpp;
15163
    }
15164
   /* copy the next block */
15165
#pragma cdir loopcnt=LOOPCNT
15166
#pragma cdir shortloop
15167
    for (i=0; i<ni; i++) {
15168
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
15169
     /* test for range errors (not always needed but do it anyway) */
15170
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15171
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15172
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
15173
    }
15174
   /* update xpp and tp */
15175
    if (realign) xp = (float *) *xpp;
15176
    xp += ni;
15177
    tp += ni;
15178
    *xpp = (void*)xp;
15179
  }
15180
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15181
15182
#else   /* not SX */
15183
0
  const char *xp = (const char *) *xpp;
15184
0
  int status = NC_NOERR;
15185
15186
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15187
0
  {
15188
0
    const int lstatus = ncx_get_float_int(xp, tp);
15189
0
    if (status == NC_NOERR) /* report the first encountered error */
15190
0
      status = lstatus;
15191
0
  }
15192
15193
0
  *xpp = (const void *)xp;
15194
0
  return status;
15195
0
#endif
15196
0
}
15197
15198
int
15199
ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
15200
0
{
15201
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15202
15203
 /* basic algorithm is:
15204
  *   - ensure sane alignment of input data
15205
  *   - copy (conversion happens automatically) input data
15206
  *     to output
15207
  *   - update xpp to point at next unconverted input, and tp to point
15208
  *     at next location for converted output
15209
  */
15210
  long i, j, ni;
15211
  float tmp[LOOPCNT];        /* in case input is misaligned */
15212
  float *xp;
15213
  int nrange = 0;         /* number of range errors */
15214
  int realign = 0;        /* "do we need to fix input data alignment?" */
15215
  long cxp = (long) *((char**)xpp);
15216
15217
  realign = (cxp & 7) % SIZEOF_FLOAT;
15218
  /* sjl: manually stripmine so we can limit amount of
15219
   * vector work space reserved to LOOPCNT elements. Also
15220
   * makes vectorisation easy */
15221
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15222
    ni=Min(nelems-j,LOOPCNT);
15223
    if (realign) {
15224
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15225
      xp = tmp;
15226
    } else {
15227
      xp = (float *) *xpp;
15228
    }
15229
   /* copy the next block */
15230
#pragma cdir loopcnt=LOOPCNT
15231
#pragma cdir shortloop
15232
    for (i=0; i<ni; i++) {
15233
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
15234
     /* test for range errors (not always needed but do it anyway) */
15235
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15236
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15237
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
15238
    }
15239
   /* update xpp and tp */
15240
    if (realign) xp = (float *) *xpp;
15241
    xp += ni;
15242
    tp += ni;
15243
    *xpp = (void*)xp;
15244
  }
15245
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15246
15247
#else   /* not SX */
15248
0
  const char *xp = (const char *) *xpp;
15249
0
  int status = NC_NOERR;
15250
15251
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15252
0
  {
15253
0
    const int lstatus = ncx_get_float_long(xp, tp);
15254
0
    if (status == NC_NOERR) /* report the first encountered error */
15255
0
      status = lstatus;
15256
0
  }
15257
15258
0
  *xpp = (const void *)xp;
15259
0
  return status;
15260
0
#endif
15261
0
}
15262
15263
int
15264
ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
15265
0
{
15266
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15267
15268
 /* basic algorithm is:
15269
  *   - ensure sane alignment of input data
15270
  *   - copy (conversion happens automatically) input data
15271
  *     to output
15272
  *   - update xpp to point at next unconverted input, and tp to point
15273
  *     at next location for converted output
15274
  */
15275
  long i, j, ni;
15276
  float tmp[LOOPCNT];        /* in case input is misaligned */
15277
  float *xp;
15278
  int nrange = 0;         /* number of range errors */
15279
  int realign = 0;        /* "do we need to fix input data alignment?" */
15280
  long cxp = (long) *((char**)xpp);
15281
15282
  realign = (cxp & 7) % SIZEOF_FLOAT;
15283
  /* sjl: manually stripmine so we can limit amount of
15284
   * vector work space reserved to LOOPCNT elements. Also
15285
   * makes vectorisation easy */
15286
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15287
    ni=Min(nelems-j,LOOPCNT);
15288
    if (realign) {
15289
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15290
      xp = tmp;
15291
    } else {
15292
      xp = (float *) *xpp;
15293
    }
15294
   /* copy the next block */
15295
#pragma cdir loopcnt=LOOPCNT
15296
#pragma cdir shortloop
15297
    for (i=0; i<ni; i++) {
15298
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
15299
     /* test for range errors (not always needed but do it anyway) */
15300
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15301
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15302
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
15303
    }
15304
   /* update xpp and tp */
15305
    if (realign) xp = (float *) *xpp;
15306
    xp += ni;
15307
    tp += ni;
15308
    *xpp = (void*)xp;
15309
  }
15310
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15311
15312
#else   /* not SX */
15313
0
  const char *xp = (const char *) *xpp;
15314
0
  int status = NC_NOERR;
15315
15316
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15317
0
  {
15318
0
    const int lstatus = ncx_get_float_double(xp, tp);
15319
0
    if (status == NC_NOERR) /* report the first encountered error */
15320
0
      status = lstatus;
15321
0
  }
15322
15323
0
  *xpp = (const void *)xp;
15324
0
  return status;
15325
0
#endif
15326
0
}
15327
15328
int
15329
ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp)
15330
0
{
15331
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15332
15333
 /* basic algorithm is:
15334
  *   - ensure sane alignment of input data
15335
  *   - copy (conversion happens automatically) input data
15336
  *     to output
15337
  *   - update xpp to point at next unconverted input, and tp to point
15338
  *     at next location for converted output
15339
  */
15340
  long i, j, ni;
15341
  float tmp[LOOPCNT];        /* in case input is misaligned */
15342
  float *xp;
15343
  int nrange = 0;         /* number of range errors */
15344
  int realign = 0;        /* "do we need to fix input data alignment?" */
15345
  long cxp = (long) *((char**)xpp);
15346
15347
  realign = (cxp & 7) % SIZEOF_FLOAT;
15348
  /* sjl: manually stripmine so we can limit amount of
15349
   * vector work space reserved to LOOPCNT elements. Also
15350
   * makes vectorisation easy */
15351
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15352
    ni=Min(nelems-j,LOOPCNT);
15353
    if (realign) {
15354
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15355
      xp = tmp;
15356
    } else {
15357
      xp = (float *) *xpp;
15358
    }
15359
   /* copy the next block */
15360
#pragma cdir loopcnt=LOOPCNT
15361
#pragma cdir shortloop
15362
    for (i=0; i<ni; i++) {
15363
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
15364
     /* test for range errors (not always needed but do it anyway) */
15365
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15366
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15367
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
15368
    }
15369
   /* update xpp and tp */
15370
    if (realign) xp = (float *) *xpp;
15371
    xp += ni;
15372
    tp += ni;
15373
    *xpp = (void*)xp;
15374
  }
15375
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15376
15377
#else   /* not SX */
15378
0
  const char *xp = (const char *) *xpp;
15379
0
  int status = NC_NOERR;
15380
15381
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15382
0
  {
15383
0
    const int lstatus = ncx_get_float_longlong(xp, tp);
15384
0
    if (status == NC_NOERR) /* report the first encountered error */
15385
0
      status = lstatus;
15386
0
  }
15387
15388
0
  *xpp = (const void *)xp;
15389
0
  return status;
15390
0
#endif
15391
0
}
15392
15393
int
15394
ncx_getn_float_ushort(const void **xpp, size_t nelems, ushort *tp)
15395
0
{
15396
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15397
15398
 /* basic algorithm is:
15399
  *   - ensure sane alignment of input data
15400
  *   - copy (conversion happens automatically) input data
15401
  *     to output
15402
  *   - update xpp to point at next unconverted input, and tp to point
15403
  *     at next location for converted output
15404
  */
15405
  long i, j, ni;
15406
  float tmp[LOOPCNT];        /* in case input is misaligned */
15407
  float *xp;
15408
  int nrange = 0;         /* number of range errors */
15409
  int realign = 0;        /* "do we need to fix input data alignment?" */
15410
  long cxp = (long) *((char**)xpp);
15411
15412
  realign = (cxp & 7) % SIZEOF_FLOAT;
15413
  /* sjl: manually stripmine so we can limit amount of
15414
   * vector work space reserved to LOOPCNT elements. Also
15415
   * makes vectorisation easy */
15416
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15417
    ni=Min(nelems-j,LOOPCNT);
15418
    if (realign) {
15419
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15420
      xp = tmp;
15421
    } else {
15422
      xp = (float *) *xpp;
15423
    }
15424
   /* copy the next block */
15425
#pragma cdir loopcnt=LOOPCNT
15426
#pragma cdir shortloop
15427
    for (i=0; i<ni; i++) {
15428
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
15429
     /* test for range errors (not always needed but do it anyway) */
15430
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15431
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15432
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
15433
    }
15434
   /* update xpp and tp */
15435
    if (realign) xp = (float *) *xpp;
15436
    xp += ni;
15437
    tp += ni;
15438
    *xpp = (void*)xp;
15439
  }
15440
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15441
15442
#else   /* not SX */
15443
0
  const char *xp = (const char *) *xpp;
15444
0
  int status = NC_NOERR;
15445
15446
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15447
0
  {
15448
0
    const int lstatus = ncx_get_float_ushort(xp, tp);
15449
0
    if (status == NC_NOERR) /* report the first encountered error */
15450
0
      status = lstatus;
15451
0
  }
15452
15453
0
  *xpp = (const void *)xp;
15454
0
  return status;
15455
0
#endif
15456
0
}
15457
15458
int
15459
ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
15460
0
{
15461
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15462
15463
 /* basic algorithm is:
15464
  *   - ensure sane alignment of input data
15465
  *   - copy (conversion happens automatically) input data
15466
  *     to output
15467
  *   - update xpp to point at next unconverted input, and tp to point
15468
  *     at next location for converted output
15469
  */
15470
  long i, j, ni;
15471
  float tmp[LOOPCNT];        /* in case input is misaligned */
15472
  float *xp;
15473
  int nrange = 0;         /* number of range errors */
15474
  int realign = 0;        /* "do we need to fix input data alignment?" */
15475
  long cxp = (long) *((char**)xpp);
15476
15477
  realign = (cxp & 7) % SIZEOF_FLOAT;
15478
  /* sjl: manually stripmine so we can limit amount of
15479
   * vector work space reserved to LOOPCNT elements. Also
15480
   * makes vectorisation easy */
15481
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15482
    ni=Min(nelems-j,LOOPCNT);
15483
    if (realign) {
15484
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15485
      xp = tmp;
15486
    } else {
15487
      xp = (float *) *xpp;
15488
    }
15489
   /* copy the next block */
15490
#pragma cdir loopcnt=LOOPCNT
15491
#pragma cdir shortloop
15492
    for (i=0; i<ni; i++) {
15493
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
15494
     /* test for range errors (not always needed but do it anyway) */
15495
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15496
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15497
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
15498
    }
15499
   /* update xpp and tp */
15500
    if (realign) xp = (float *) *xpp;
15501
    xp += ni;
15502
    tp += ni;
15503
    *xpp = (void*)xp;
15504
  }
15505
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15506
15507
#else   /* not SX */
15508
0
  const char *xp = (const char *) *xpp;
15509
0
  int status = NC_NOERR;
15510
15511
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15512
0
  {
15513
0
    const int lstatus = ncx_get_float_uchar(xp, tp);
15514
0
    if (status == NC_NOERR) /* report the first encountered error */
15515
0
      status = lstatus;
15516
0
  }
15517
15518
0
  *xpp = (const void *)xp;
15519
0
  return status;
15520
0
#endif
15521
0
}
15522
15523
int
15524
ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp)
15525
0
{
15526
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15527
15528
 /* basic algorithm is:
15529
  *   - ensure sane alignment of input data
15530
  *   - copy (conversion happens automatically) input data
15531
  *     to output
15532
  *   - update xpp to point at next unconverted input, and tp to point
15533
  *     at next location for converted output
15534
  */
15535
  long i, j, ni;
15536
  float tmp[LOOPCNT];        /* in case input is misaligned */
15537
  float *xp;
15538
  int nrange = 0;         /* number of range errors */
15539
  int realign = 0;        /* "do we need to fix input data alignment?" */
15540
  long cxp = (long) *((char**)xpp);
15541
15542
  realign = (cxp & 7) % SIZEOF_FLOAT;
15543
  /* sjl: manually stripmine so we can limit amount of
15544
   * vector work space reserved to LOOPCNT elements. Also
15545
   * makes vectorisation easy */
15546
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15547
    ni=Min(nelems-j,LOOPCNT);
15548
    if (realign) {
15549
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15550
      xp = tmp;
15551
    } else {
15552
      xp = (float *) *xpp;
15553
    }
15554
   /* copy the next block */
15555
#pragma cdir loopcnt=LOOPCNT
15556
#pragma cdir shortloop
15557
    for (i=0; i<ni; i++) {
15558
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
15559
     /* test for range errors (not always needed but do it anyway) */
15560
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15561
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15562
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
15563
    }
15564
   /* update xpp and tp */
15565
    if (realign) xp = (float *) *xpp;
15566
    xp += ni;
15567
    tp += ni;
15568
    *xpp = (void*)xp;
15569
  }
15570
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15571
15572
#else   /* not SX */
15573
0
  const char *xp = (const char *) *xpp;
15574
0
  int status = NC_NOERR;
15575
15576
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15577
0
  {
15578
0
    const int lstatus = ncx_get_float_uint(xp, tp);
15579
0
    if (status == NC_NOERR) /* report the first encountered error */
15580
0
      status = lstatus;
15581
0
  }
15582
15583
0
  *xpp = (const void *)xp;
15584
0
  return status;
15585
0
#endif
15586
0
}
15587
15588
int
15589
ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
15590
0
{
15591
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15592
15593
 /* basic algorithm is:
15594
  *   - ensure sane alignment of input data
15595
  *   - copy (conversion happens automatically) input data
15596
  *     to output
15597
  *   - update xpp to point at next unconverted input, and tp to point
15598
  *     at next location for converted output
15599
  */
15600
  long i, j, ni;
15601
  float tmp[LOOPCNT];        /* in case input is misaligned */
15602
  float *xp;
15603
  int nrange = 0;         /* number of range errors */
15604
  int realign = 0;        /* "do we need to fix input data alignment?" */
15605
  long cxp = (long) *((char**)xpp);
15606
15607
  realign = (cxp & 7) % SIZEOF_FLOAT;
15608
  /* sjl: manually stripmine so we can limit amount of
15609
   * vector work space reserved to LOOPCNT elements. Also
15610
   * makes vectorisation easy */
15611
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15612
    ni=Min(nelems-j,LOOPCNT);
15613
    if (realign) {
15614
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15615
      xp = tmp;
15616
    } else {
15617
      xp = (float *) *xpp;
15618
    }
15619
   /* copy the next block */
15620
#pragma cdir loopcnt=LOOPCNT
15621
#pragma cdir shortloop
15622
    for (i=0; i<ni; i++) {
15623
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
15624
     /* test for range errors (not always needed but do it anyway) */
15625
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15626
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15627
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
15628
    }
15629
   /* update xpp and tp */
15630
    if (realign) xp = (float *) *xpp;
15631
    xp += ni;
15632
    tp += ni;
15633
    *xpp = (void*)xp;
15634
  }
15635
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15636
15637
#else   /* not SX */
15638
0
  const char *xp = (const char *) *xpp;
15639
0
  int status = NC_NOERR;
15640
15641
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15642
0
  {
15643
0
    const int lstatus = ncx_get_float_ulonglong(xp, tp);
15644
0
    if (status == NC_NOERR) /* report the first encountered error */
15645
0
      status = lstatus;
15646
0
  }
15647
15648
0
  *xpp = (const void *)xp;
15649
0
  return status;
15650
0
#endif
15651
0
}
15652
15653
15654
int
15655
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
15656
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
15657
/* optimized version */
15658
552
{
15659
#ifdef WORDS_BIGENDIAN
15660
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
15661
# else
15662
552
  swapn4b(*xpp, tp, nelems);
15663
552
# endif
15664
552
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
15665
552
  return NC_NOERR;
15666
552
}
15667
#elif defined(vax) && vax != 0
15668
{
15669
  const float *const end = tp + nelems;
15670
15671
  while (tp < end) {
15672
        const struct vax_single *const vsp =
15673
       (const struct vax_single *)ip;
15674
    struct ieee_single *const isp = (struct ieee_single *) (*xpp);
15675
15676
    switch(vsp->exp){
15677
    case 0 :
15678
      /* all vax float with zero exponent map to zero */
15679
      *isp = min.ieee;
15680
      break;
15681
    case 2 :
15682
    case 1 :
15683
    {
15684
      /* These will map to subnormals */
15685
      unsigned mantissa = (vsp->mantissa1 << 16)
15686
           | vsp->mantissa2;
15687
      mantissa >>= 3 - vsp->exp;
15688
      mantissa += (1 << (20 + vsp->exp));
15689
      isp->mant_lo_lo = mantissa;
15690
      isp->mant_lo_hi = mantissa >> 8;
15691
      isp->mant_hi = mantissa >> 16;
15692
      isp->exp_lo = 0;
15693
      isp->exp_hi = 0;
15694
    }
15695
      break;
15696
    case 0xff : /* max.s.exp */
15697
      if (vsp->mantissa2 == max.s.mantissa2 &&
15698
          vsp->mantissa1 == max.s.mantissa1)
15699
      {
15700
        /* map largest vax float to ieee infinity */
15701
        *isp = max.ieee;
15702
        break;
15703
      } /* else, fall thru */
15704
    default :
15705
    {
15706
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
15707
      isp->exp_hi = exp >> 1;
15708
      isp->exp_lo = exp;
15709
      isp->mant_lo_lo = vsp->mantissa2;
15710
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
15711
      isp->mant_hi = vsp->mantissa1;
15712
    }
15713
    }
15714
15715
    isp->sign = vsp->sign;
15716
15717
    tp++;
15718
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
15719
  }
15720
  return NC_NOERR;
15721
}
15722
#else
15723
{
15724
  char *xp = *xpp;
15725
  int status = NC_NOERR;
15726
15727
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
15728
    int lstatus = ncx_put_float_float(xp, tp, fillp);
15729
    if (status == NC_NOERR) /* report the first encountered error */
15730
      status = lstatus;
15731
  }
15732
15733
  *xpp = (void *)xp;
15734
  return status;
15735
}
15736
#endif
15737
int
15738
ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
15739
0
{
15740
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15741
15742
 /* basic algorithm is:
15743
  *   - ensure sane alignment of output data
15744
  *   - copy (conversion happens automatically) input data
15745
  *     to output
15746
  *   - update tp to point at next unconverted input, and xpp to point
15747
  *     at next location for converted output
15748
  */
15749
  long i, j, ni;
15750
  float tmp[LOOPCNT];        /* in case input is misaligned */
15751
  float *xp;
15752
  int nrange = 0;         /* number of range errors */
15753
  int realign = 0;        /* "do we need to fix input data alignment?" */
15754
  long cxp = (long) *((char**)xpp);
15755
15756
  realign = (cxp & 7) % SIZEOF_FLOAT;
15757
  /* sjl: manually stripmine so we can limit amount of
15758
   * vector work space reserved to LOOPCNT elements. Also
15759
   * makes vectorisation easy */
15760
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15761
    ni=Min(nelems-j,LOOPCNT);
15762
    if (realign) {
15763
      xp = tmp;
15764
    } else {
15765
      xp = (float *) *xpp;
15766
    }
15767
   /* copy the next block */
15768
#pragma cdir loopcnt=LOOPCNT
15769
#pragma cdir shortloop
15770
    for (i=0; i<ni; i++) {
15771
      /* the normal case: */
15772
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15773
     /* test for range errors (not always needed but do it anyway) */
15774
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15775
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15776
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15777
    }
15778
   /* copy workspace back if necessary */
15779
    if (realign) {
15780
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15781
      xp = (float *) *xpp;
15782
    }
15783
   /* update xpp and tp */
15784
    xp += ni;
15785
    tp += ni;
15786
    *xpp = (void*)xp;
15787
  }
15788
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15789
15790
#else   /* not SX */
15791
15792
0
  char *xp = (char *) *xpp;
15793
0
  int status = NC_NOERR;
15794
15795
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15796
0
  {
15797
0
    int lstatus = ncx_put_float_schar(xp, tp, fillp);
15798
0
    if (status == NC_NOERR) /* report the first encountered error */
15799
0
      status = lstatus;
15800
0
  }
15801
15802
0
  *xpp = (void *)xp;
15803
0
  return status;
15804
0
#endif
15805
0
}
15806
15807
int
15808
ncx_putn_float_short(void **xpp, size_t nelems, const short *tp, void *fillp)
15809
0
{
15810
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15811
15812
 /* basic algorithm is:
15813
  *   - ensure sane alignment of output data
15814
  *   - copy (conversion happens automatically) input data
15815
  *     to output
15816
  *   - update tp to point at next unconverted input, and xpp to point
15817
  *     at next location for converted output
15818
  */
15819
  long i, j, ni;
15820
  float tmp[LOOPCNT];        /* in case input is misaligned */
15821
  float *xp;
15822
  int nrange = 0;         /* number of range errors */
15823
  int realign = 0;        /* "do we need to fix input data alignment?" */
15824
  long cxp = (long) *((char**)xpp);
15825
15826
  realign = (cxp & 7) % SIZEOF_FLOAT;
15827
  /* sjl: manually stripmine so we can limit amount of
15828
   * vector work space reserved to LOOPCNT elements. Also
15829
   * makes vectorisation easy */
15830
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15831
    ni=Min(nelems-j,LOOPCNT);
15832
    if (realign) {
15833
      xp = tmp;
15834
    } else {
15835
      xp = (float *) *xpp;
15836
    }
15837
   /* copy the next block */
15838
#pragma cdir loopcnt=LOOPCNT
15839
#pragma cdir shortloop
15840
    for (i=0; i<ni; i++) {
15841
      /* the normal case: */
15842
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15843
     /* test for range errors (not always needed but do it anyway) */
15844
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15845
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15846
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15847
    }
15848
   /* copy workspace back if necessary */
15849
    if (realign) {
15850
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15851
      xp = (float *) *xpp;
15852
    }
15853
   /* update xpp and tp */
15854
    xp += ni;
15855
    tp += ni;
15856
    *xpp = (void*)xp;
15857
  }
15858
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15859
15860
#else   /* not SX */
15861
15862
0
  char *xp = (char *) *xpp;
15863
0
  int status = NC_NOERR;
15864
15865
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15866
0
  {
15867
0
    int lstatus = ncx_put_float_short(xp, tp, fillp);
15868
0
    if (status == NC_NOERR) /* report the first encountered error */
15869
0
      status = lstatus;
15870
0
  }
15871
15872
0
  *xpp = (void *)xp;
15873
0
  return status;
15874
0
#endif
15875
0
}
15876
15877
int
15878
ncx_putn_float_int(void **xpp, size_t nelems, const int *tp, void *fillp)
15879
0
{
15880
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15881
15882
 /* basic algorithm is:
15883
  *   - ensure sane alignment of output data
15884
  *   - copy (conversion happens automatically) input data
15885
  *     to output
15886
  *   - update tp to point at next unconverted input, and xpp to point
15887
  *     at next location for converted output
15888
  */
15889
  long i, j, ni;
15890
  float tmp[LOOPCNT];        /* in case input is misaligned */
15891
  float *xp;
15892
  int nrange = 0;         /* number of range errors */
15893
  int realign = 0;        /* "do we need to fix input data alignment?" */
15894
  long cxp = (long) *((char**)xpp);
15895
15896
  realign = (cxp & 7) % SIZEOF_FLOAT;
15897
  /* sjl: manually stripmine so we can limit amount of
15898
   * vector work space reserved to LOOPCNT elements. Also
15899
   * makes vectorisation easy */
15900
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15901
    ni=Min(nelems-j,LOOPCNT);
15902
    if (realign) {
15903
      xp = tmp;
15904
    } else {
15905
      xp = (float *) *xpp;
15906
    }
15907
   /* copy the next block */
15908
#pragma cdir loopcnt=LOOPCNT
15909
#pragma cdir shortloop
15910
    for (i=0; i<ni; i++) {
15911
      /* the normal case: */
15912
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15913
     /* test for range errors (not always needed but do it anyway) */
15914
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15915
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15916
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15917
    }
15918
   /* copy workspace back if necessary */
15919
    if (realign) {
15920
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15921
      xp = (float *) *xpp;
15922
    }
15923
   /* update xpp and tp */
15924
    xp += ni;
15925
    tp += ni;
15926
    *xpp = (void*)xp;
15927
  }
15928
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15929
15930
#else   /* not SX */
15931
15932
0
  char *xp = (char *) *xpp;
15933
0
  int status = NC_NOERR;
15934
15935
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15936
0
  {
15937
0
    int lstatus = ncx_put_float_int(xp, tp, fillp);
15938
0
    if (status == NC_NOERR) /* report the first encountered error */
15939
0
      status = lstatus;
15940
0
  }
15941
15942
0
  *xpp = (void *)xp;
15943
0
  return status;
15944
0
#endif
15945
0
}
15946
15947
int
15948
ncx_putn_float_long(void **xpp, size_t nelems, const long *tp, void *fillp)
15949
0
{
15950
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15951
15952
 /* basic algorithm is:
15953
  *   - ensure sane alignment of output data
15954
  *   - copy (conversion happens automatically) input data
15955
  *     to output
15956
  *   - update tp to point at next unconverted input, and xpp to point
15957
  *     at next location for converted output
15958
  */
15959
  long i, j, ni;
15960
  float tmp[LOOPCNT];        /* in case input is misaligned */
15961
  float *xp;
15962
  int nrange = 0;         /* number of range errors */
15963
  int realign = 0;        /* "do we need to fix input data alignment?" */
15964
  long cxp = (long) *((char**)xpp);
15965
15966
  realign = (cxp & 7) % SIZEOF_FLOAT;
15967
  /* sjl: manually stripmine so we can limit amount of
15968
   * vector work space reserved to LOOPCNT elements. Also
15969
   * makes vectorisation easy */
15970
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15971
    ni=Min(nelems-j,LOOPCNT);
15972
    if (realign) {
15973
      xp = tmp;
15974
    } else {
15975
      xp = (float *) *xpp;
15976
    }
15977
   /* copy the next block */
15978
#pragma cdir loopcnt=LOOPCNT
15979
#pragma cdir shortloop
15980
    for (i=0; i<ni; i++) {
15981
      /* the normal case: */
15982
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15983
     /* test for range errors (not always needed but do it anyway) */
15984
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15985
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15986
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15987
    }
15988
   /* copy workspace back if necessary */
15989
    if (realign) {
15990
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15991
      xp = (float *) *xpp;
15992
    }
15993
   /* update xpp and tp */
15994
    xp += ni;
15995
    tp += ni;
15996
    *xpp = (void*)xp;
15997
  }
15998
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15999
16000
#else   /* not SX */
16001
16002
0
  char *xp = (char *) *xpp;
16003
0
  int status = NC_NOERR;
16004
16005
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16006
0
  {
16007
0
    int lstatus = ncx_put_float_long(xp, tp, fillp);
16008
0
    if (status == NC_NOERR) /* report the first encountered error */
16009
0
      status = lstatus;
16010
0
  }
16011
16012
0
  *xpp = (void *)xp;
16013
0
  return status;
16014
0
#endif
16015
0
}
16016
16017
int
16018
ncx_putn_float_double(void **xpp, size_t nelems, const double *tp, void *fillp)
16019
0
{
16020
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16021
16022
 /* basic algorithm is:
16023
  *   - ensure sane alignment of output data
16024
  *   - copy (conversion happens automatically) input data
16025
  *     to output
16026
  *   - update tp to point at next unconverted input, and xpp to point
16027
  *     at next location for converted output
16028
  */
16029
  long i, j, ni;
16030
  float tmp[LOOPCNT];        /* in case input is misaligned */
16031
  float *xp;
16032
  int nrange = 0;         /* number of range errors */
16033
  int realign = 0;        /* "do we need to fix input data alignment?" */
16034
  long cxp = (long) *((char**)xpp);
16035
16036
  realign = (cxp & 7) % SIZEOF_FLOAT;
16037
  /* sjl: manually stripmine so we can limit amount of
16038
   * vector work space reserved to LOOPCNT elements. Also
16039
   * makes vectorisation easy */
16040
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16041
    ni=Min(nelems-j,LOOPCNT);
16042
    if (realign) {
16043
      xp = tmp;
16044
    } else {
16045
      xp = (float *) *xpp;
16046
    }
16047
   /* copy the next block */
16048
#pragma cdir loopcnt=LOOPCNT
16049
#pragma cdir shortloop
16050
    for (i=0; i<ni; i++) {
16051
      /* the normal case: */
16052
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16053
     /* test for range errors (not always needed but do it anyway) */
16054
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16055
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16056
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
16057
    }
16058
   /* copy workspace back if necessary */
16059
    if (realign) {
16060
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16061
      xp = (float *) *xpp;
16062
    }
16063
   /* update xpp and tp */
16064
    xp += ni;
16065
    tp += ni;
16066
    *xpp = (void*)xp;
16067
  }
16068
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16069
16070
#else   /* not SX */
16071
16072
0
  char *xp = (char *) *xpp;
16073
0
  int status = NC_NOERR;
16074
16075
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16076
0
  {
16077
0
    int lstatus = ncx_put_float_double(xp, tp, fillp);
16078
0
    if (status == NC_NOERR) /* report the first encountered error */
16079
0
      status = lstatus;
16080
0
  }
16081
16082
0
  *xpp = (void *)xp;
16083
0
  return status;
16084
0
#endif
16085
0
}
16086
16087
int
16088
ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
16089
0
{
16090
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16091
16092
 /* basic algorithm is:
16093
  *   - ensure sane alignment of output data
16094
  *   - copy (conversion happens automatically) input data
16095
  *     to output
16096
  *   - update tp to point at next unconverted input, and xpp to point
16097
  *     at next location for converted output
16098
  */
16099
  long i, j, ni;
16100
  float tmp[LOOPCNT];        /* in case input is misaligned */
16101
  float *xp;
16102
  int nrange = 0;         /* number of range errors */
16103
  int realign = 0;        /* "do we need to fix input data alignment?" */
16104
  long cxp = (long) *((char**)xpp);
16105
16106
  realign = (cxp & 7) % SIZEOF_FLOAT;
16107
  /* sjl: manually stripmine so we can limit amount of
16108
   * vector work space reserved to LOOPCNT elements. Also
16109
   * makes vectorisation easy */
16110
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16111
    ni=Min(nelems-j,LOOPCNT);
16112
    if (realign) {
16113
      xp = tmp;
16114
    } else {
16115
      xp = (float *) *xpp;
16116
    }
16117
   /* copy the next block */
16118
#pragma cdir loopcnt=LOOPCNT
16119
#pragma cdir shortloop
16120
    for (i=0; i<ni; i++) {
16121
      /* the normal case: */
16122
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16123
     /* test for range errors (not always needed but do it anyway) */
16124
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16125
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16126
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
16127
    }
16128
   /* copy workspace back if necessary */
16129
    if (realign) {
16130
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16131
      xp = (float *) *xpp;
16132
    }
16133
   /* update xpp and tp */
16134
    xp += ni;
16135
    tp += ni;
16136
    *xpp = (void*)xp;
16137
  }
16138
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16139
16140
#else   /* not SX */
16141
16142
0
  char *xp = (char *) *xpp;
16143
0
  int status = NC_NOERR;
16144
16145
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16146
0
  {
16147
0
    int lstatus = ncx_put_float_longlong(xp, tp, fillp);
16148
0
    if (status == NC_NOERR) /* report the first encountered error */
16149
0
      status = lstatus;
16150
0
  }
16151
16152
0
  *xpp = (void *)xp;
16153
0
  return status;
16154
0
#endif
16155
0
}
16156
16157
int
16158
ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
16159
0
{
16160
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16161
16162
 /* basic algorithm is:
16163
  *   - ensure sane alignment of output data
16164
  *   - copy (conversion happens automatically) input data
16165
  *     to output
16166
  *   - update tp to point at next unconverted input, and xpp to point
16167
  *     at next location for converted output
16168
  */
16169
  long i, j, ni;
16170
  float tmp[LOOPCNT];        /* in case input is misaligned */
16171
  float *xp;
16172
  int nrange = 0;         /* number of range errors */
16173
  int realign = 0;        /* "do we need to fix input data alignment?" */
16174
  long cxp = (long) *((char**)xpp);
16175
16176
  realign = (cxp & 7) % SIZEOF_FLOAT;
16177
  /* sjl: manually stripmine so we can limit amount of
16178
   * vector work space reserved to LOOPCNT elements. Also
16179
   * makes vectorisation easy */
16180
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16181
    ni=Min(nelems-j,LOOPCNT);
16182
    if (realign) {
16183
      xp = tmp;
16184
    } else {
16185
      xp = (float *) *xpp;
16186
    }
16187
   /* copy the next block */
16188
#pragma cdir loopcnt=LOOPCNT
16189
#pragma cdir shortloop
16190
    for (i=0; i<ni; i++) {
16191
      /* the normal case: */
16192
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16193
     /* test for range errors (not always needed but do it anyway) */
16194
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16195
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16196
      nrange += tp[i] > X_FLOAT_MAX ;
16197
    }
16198
   /* copy workspace back if necessary */
16199
    if (realign) {
16200
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16201
      xp = (float *) *xpp;
16202
    }
16203
   /* update xpp and tp */
16204
    xp += ni;
16205
    tp += ni;
16206
    *xpp = (void*)xp;
16207
  }
16208
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16209
16210
#else   /* not SX */
16211
16212
0
  char *xp = (char *) *xpp;
16213
0
  int status = NC_NOERR;
16214
16215
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16216
0
  {
16217
0
    int lstatus = ncx_put_float_uchar(xp, tp, fillp);
16218
0
    if (status == NC_NOERR) /* report the first encountered error */
16219
0
      status = lstatus;
16220
0
  }
16221
16222
0
  *xpp = (void *)xp;
16223
0
  return status;
16224
0
#endif
16225
0
}
16226
16227
int
16228
ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
16229
0
{
16230
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16231
16232
 /* basic algorithm is:
16233
  *   - ensure sane alignment of output data
16234
  *   - copy (conversion happens automatically) input data
16235
  *     to output
16236
  *   - update tp to point at next unconverted input, and xpp to point
16237
  *     at next location for converted output
16238
  */
16239
  long i, j, ni;
16240
  float tmp[LOOPCNT];        /* in case input is misaligned */
16241
  float *xp;
16242
  int nrange = 0;         /* number of range errors */
16243
  int realign = 0;        /* "do we need to fix input data alignment?" */
16244
  long cxp = (long) *((char**)xpp);
16245
16246
  realign = (cxp & 7) % SIZEOF_FLOAT;
16247
  /* sjl: manually stripmine so we can limit amount of
16248
   * vector work space reserved to LOOPCNT elements. Also
16249
   * makes vectorisation easy */
16250
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16251
    ni=Min(nelems-j,LOOPCNT);
16252
    if (realign) {
16253
      xp = tmp;
16254
    } else {
16255
      xp = (float *) *xpp;
16256
    }
16257
   /* copy the next block */
16258
#pragma cdir loopcnt=LOOPCNT
16259
#pragma cdir shortloop
16260
    for (i=0; i<ni; i++) {
16261
      /* the normal case: */
16262
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16263
     /* test for range errors (not always needed but do it anyway) */
16264
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16265
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16266
      nrange += tp[i] > X_FLOAT_MAX ;
16267
    }
16268
   /* copy workspace back if necessary */
16269
    if (realign) {
16270
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16271
      xp = (float *) *xpp;
16272
    }
16273
   /* update xpp and tp */
16274
    xp += ni;
16275
    tp += ni;
16276
    *xpp = (void*)xp;
16277
  }
16278
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16279
16280
#else   /* not SX */
16281
16282
0
  char *xp = (char *) *xpp;
16283
0
  int status = NC_NOERR;
16284
16285
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16286
0
  {
16287
0
    int lstatus = ncx_put_float_ushort(xp, tp, fillp);
16288
0
    if (status == NC_NOERR) /* report the first encountered error */
16289
0
      status = lstatus;
16290
0
  }
16291
16292
0
  *xpp = (void *)xp;
16293
0
  return status;
16294
0
#endif
16295
0
}
16296
16297
int
16298
ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
16299
0
{
16300
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16301
16302
 /* basic algorithm is:
16303
  *   - ensure sane alignment of output data
16304
  *   - copy (conversion happens automatically) input data
16305
  *     to output
16306
  *   - update tp to point at next unconverted input, and xpp to point
16307
  *     at next location for converted output
16308
  */
16309
  long i, j, ni;
16310
  float tmp[LOOPCNT];        /* in case input is misaligned */
16311
  float *xp;
16312
  int nrange = 0;         /* number of range errors */
16313
  int realign = 0;        /* "do we need to fix input data alignment?" */
16314
  long cxp = (long) *((char**)xpp);
16315
16316
  realign = (cxp & 7) % SIZEOF_FLOAT;
16317
  /* sjl: manually stripmine so we can limit amount of
16318
   * vector work space reserved to LOOPCNT elements. Also
16319
   * makes vectorisation easy */
16320
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16321
    ni=Min(nelems-j,LOOPCNT);
16322
    if (realign) {
16323
      xp = tmp;
16324
    } else {
16325
      xp = (float *) *xpp;
16326
    }
16327
   /* copy the next block */
16328
#pragma cdir loopcnt=LOOPCNT
16329
#pragma cdir shortloop
16330
    for (i=0; i<ni; i++) {
16331
      /* the normal case: */
16332
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16333
     /* test for range errors (not always needed but do it anyway) */
16334
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16335
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16336
      nrange += tp[i] > X_FLOAT_MAX ;
16337
    }
16338
   /* copy workspace back if necessary */
16339
    if (realign) {
16340
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16341
      xp = (float *) *xpp;
16342
    }
16343
   /* update xpp and tp */
16344
    xp += ni;
16345
    tp += ni;
16346
    *xpp = (void*)xp;
16347
  }
16348
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16349
16350
#else   /* not SX */
16351
16352
0
  char *xp = (char *) *xpp;
16353
0
  int status = NC_NOERR;
16354
16355
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16356
0
  {
16357
0
    int lstatus = ncx_put_float_uint(xp, tp, fillp);
16358
0
    if (status == NC_NOERR) /* report the first encountered error */
16359
0
      status = lstatus;
16360
0
  }
16361
16362
0
  *xpp = (void *)xp;
16363
0
  return status;
16364
0
#endif
16365
0
}
16366
16367
int
16368
ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
16369
0
{
16370
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16371
16372
 /* basic algorithm is:
16373
  *   - ensure sane alignment of output data
16374
  *   - copy (conversion happens automatically) input data
16375
  *     to output
16376
  *   - update tp to point at next unconverted input, and xpp to point
16377
  *     at next location for converted output
16378
  */
16379
  long i, j, ni;
16380
  float tmp[LOOPCNT];        /* in case input is misaligned */
16381
  float *xp;
16382
  int nrange = 0;         /* number of range errors */
16383
  int realign = 0;        /* "do we need to fix input data alignment?" */
16384
  long cxp = (long) *((char**)xpp);
16385
16386
  realign = (cxp & 7) % SIZEOF_FLOAT;
16387
  /* sjl: manually stripmine so we can limit amount of
16388
   * vector work space reserved to LOOPCNT elements. Also
16389
   * makes vectorisation easy */
16390
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16391
    ni=Min(nelems-j,LOOPCNT);
16392
    if (realign) {
16393
      xp = tmp;
16394
    } else {
16395
      xp = (float *) *xpp;
16396
    }
16397
   /* copy the next block */
16398
#pragma cdir loopcnt=LOOPCNT
16399
#pragma cdir shortloop
16400
    for (i=0; i<ni; i++) {
16401
      /* the normal case: */
16402
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16403
     /* test for range errors (not always needed but do it anyway) */
16404
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16405
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16406
      nrange += tp[i] > X_FLOAT_MAX ;
16407
    }
16408
   /* copy workspace back if necessary */
16409
    if (realign) {
16410
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16411
      xp = (float *) *xpp;
16412
    }
16413
   /* update xpp and tp */
16414
    xp += ni;
16415
    tp += ni;
16416
    *xpp = (void*)xp;
16417
  }
16418
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16419
16420
#else   /* not SX */
16421
16422
0
  char *xp = (char *) *xpp;
16423
0
  int status = NC_NOERR;
16424
16425
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16426
0
  {
16427
0
    int lstatus = ncx_put_float_ulonglong(xp, tp, fillp);
16428
0
    if (status == NC_NOERR) /* report the first encountered error */
16429
0
      status = lstatus;
16430
0
  }
16431
16432
0
  *xpp = (void *)xp;
16433
0
  return status;
16434
0
#endif
16435
0
}
16436
16437
16438
/* double --------------------------------------------------------------------*/
16439
16440
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16441
/* optimized version */
16442
int
16443
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16444
9.58k
{
16445
#ifdef WORDS_BIGENDIAN
16446
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
16447
# else
16448
9.58k
  swapn8b(tp, *xpp, nelems);
16449
9.58k
# endif
16450
9.58k
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16451
9.58k
  return NC_NOERR;
16452
9.58k
}
16453
#elif defined(vax) && vax != 0
16454
int
16455
ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
16456
{
16457
  double *const end = ip + ndoubles;
16458
16459
  while (ip < end)
16460
  {
16461
  struct vax_double *const vdp =
16462
       (struct vax_double *)ip;
16463
  const struct ieee_double *const idp =
16464
       (const struct ieee_double *) (*xpp);
16465
  {
16466
    const struct dbl_limits *lim;
16467
    int ii;
16468
    for (ii = 0, lim = dbl_limits;
16469
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
16470
      ii++, lim++)
16471
    {
16472
      if ((idp->mant_lo == lim->ieee.mant_lo)
16473
        && (idp->mant_4 == lim->ieee.mant_4)
16474
        && (idp->mant_5 == lim->ieee.mant_5)
16475
        && (idp->mant_6 == lim->ieee.mant_6)
16476
        && (idp->exp_lo == lim->ieee.exp_lo)
16477
        && (idp->exp_hi == lim->ieee.exp_hi)
16478
        )
16479
      {
16480
        *vdp = lim->d;
16481
        goto doneit;
16482
      }
16483
    }
16484
  }
16485
  {
16486
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
16487
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
16488
  }
16489
  {
16490
    unsigned mant_hi = ((idp->mant_6 << 16)
16491
         | (idp->mant_5 << 8)
16492
         | idp->mant_4);
16493
    unsigned mant_lo = SWAP4(idp->mant_lo);
16494
    vdp->mantissa1 = (mant_hi >> 13);
16495
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
16496
        | (mant_lo >> 29);
16497
    vdp->mantissa3 = (mant_lo >> 13);
16498
    vdp->mantissa4 = (mant_lo << 3);
16499
  }
16500
  doneit:
16501
    vdp->sign = idp->sign;
16502
16503
    ip++;
16504
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
16505
  }
16506
  return NC_NOERR;
16507
}
16508
  /* vax */
16509
#else
16510
int
16511
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16512
{
16513
  const char *xp = *xpp;
16514
  int status = NC_NOERR;
16515
16516
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16517
  {
16518
    const int lstatus = ncx_get_double_double(xp, tp, fillp);
16519
    if (status == NC_NOERR) /* report the first encountered error */
16520
      status = lstatus;
16521
  }
16522
16523
  *xpp = (const void *)xp;
16524
  return status;
16525
}
16526
#endif
16527
int
16528
ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
16529
0
{
16530
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16531
16532
 /* basic algorithm is:
16533
  *   - ensure sane alignment of input data
16534
  *   - copy (conversion happens automatically) input data
16535
  *     to output
16536
  *   - update xpp to point at next unconverted input, and tp to point
16537
  *     at next location for converted output
16538
  */
16539
  long i, j, ni;
16540
  double tmp[LOOPCNT];        /* in case input is misaligned */
16541
  double *xp;
16542
  int nrange = 0;         /* number of range errors */
16543
  int realign = 0;        /* "do we need to fix input data alignment?" */
16544
  long cxp = (long) *((char**)xpp);
16545
16546
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16547
  /* sjl: manually stripmine so we can limit amount of
16548
   * vector work space reserved to LOOPCNT elements. Also
16549
   * makes vectorisation easy */
16550
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16551
    ni=Min(nelems-j,LOOPCNT);
16552
    if (realign) {
16553
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16554
      xp = tmp;
16555
    } else {
16556
      xp = (double *) *xpp;
16557
    }
16558
   /* copy the next block */
16559
#pragma cdir loopcnt=LOOPCNT
16560
#pragma cdir shortloop
16561
    for (i=0; i<ni; i++) {
16562
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
16563
     /* test for range errors (not always needed but do it anyway) */
16564
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16565
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16566
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
16567
    }
16568
   /* update xpp and tp */
16569
    if (realign) xp = (double *) *xpp;
16570
    xp += ni;
16571
    tp += ni;
16572
    *xpp = (void*)xp;
16573
  }
16574
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16575
16576
#else   /* not SX */
16577
0
  const char *xp = (const char *) *xpp;
16578
0
  int status = NC_NOERR;
16579
16580
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16581
0
  {
16582
0
    const int lstatus = ncx_get_double_schar(xp, tp);
16583
0
    if (status == NC_NOERR) /* report the first encountered error */
16584
0
      status = lstatus;
16585
0
  }
16586
16587
0
  *xpp = (const void *)xp;
16588
0
  return status;
16589
0
#endif
16590
0
}
16591
16592
int
16593
ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
16594
0
{
16595
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16596
16597
 /* basic algorithm is:
16598
  *   - ensure sane alignment of input data
16599
  *   - copy (conversion happens automatically) input data
16600
  *     to output
16601
  *   - update xpp to point at next unconverted input, and tp to point
16602
  *     at next location for converted output
16603
  */
16604
  long i, j, ni;
16605
  double tmp[LOOPCNT];        /* in case input is misaligned */
16606
  double *xp;
16607
  int nrange = 0;         /* number of range errors */
16608
  int realign = 0;        /* "do we need to fix input data alignment?" */
16609
  long cxp = (long) *((char**)xpp);
16610
16611
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16612
  /* sjl: manually stripmine so we can limit amount of
16613
   * vector work space reserved to LOOPCNT elements. Also
16614
   * makes vectorisation easy */
16615
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16616
    ni=Min(nelems-j,LOOPCNT);
16617
    if (realign) {
16618
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16619
      xp = tmp;
16620
    } else {
16621
      xp = (double *) *xpp;
16622
    }
16623
   /* copy the next block */
16624
#pragma cdir loopcnt=LOOPCNT
16625
#pragma cdir shortloop
16626
    for (i=0; i<ni; i++) {
16627
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
16628
     /* test for range errors (not always needed but do it anyway) */
16629
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16630
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16631
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
16632
    }
16633
   /* update xpp and tp */
16634
    if (realign) xp = (double *) *xpp;
16635
    xp += ni;
16636
    tp += ni;
16637
    *xpp = (void*)xp;
16638
  }
16639
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16640
16641
#else   /* not SX */
16642
0
  const char *xp = (const char *) *xpp;
16643
0
  int status = NC_NOERR;
16644
16645
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16646
0
  {
16647
0
    const int lstatus = ncx_get_double_short(xp, tp);
16648
0
    if (status == NC_NOERR) /* report the first encountered error */
16649
0
      status = lstatus;
16650
0
  }
16651
16652
0
  *xpp = (const void *)xp;
16653
0
  return status;
16654
0
#endif
16655
0
}
16656
16657
int
16658
ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
16659
0
{
16660
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16661
16662
 /* basic algorithm is:
16663
  *   - ensure sane alignment of input data
16664
  *   - copy (conversion happens automatically) input data
16665
  *     to output
16666
  *   - update xpp to point at next unconverted input, and tp to point
16667
  *     at next location for converted output
16668
  */
16669
  long i, j, ni;
16670
  double tmp[LOOPCNT];        /* in case input is misaligned */
16671
  double *xp;
16672
  int nrange = 0;         /* number of range errors */
16673
  int realign = 0;        /* "do we need to fix input data alignment?" */
16674
  long cxp = (long) *((char**)xpp);
16675
16676
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16677
  /* sjl: manually stripmine so we can limit amount of
16678
   * vector work space reserved to LOOPCNT elements. Also
16679
   * makes vectorisation easy */
16680
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16681
    ni=Min(nelems-j,LOOPCNT);
16682
    if (realign) {
16683
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16684
      xp = tmp;
16685
    } else {
16686
      xp = (double *) *xpp;
16687
    }
16688
   /* copy the next block */
16689
#pragma cdir loopcnt=LOOPCNT
16690
#pragma cdir shortloop
16691
    for (i=0; i<ni; i++) {
16692
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
16693
     /* test for range errors (not always needed but do it anyway) */
16694
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16695
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16696
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
16697
    }
16698
   /* update xpp and tp */
16699
    if (realign) xp = (double *) *xpp;
16700
    xp += ni;
16701
    tp += ni;
16702
    *xpp = (void*)xp;
16703
  }
16704
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16705
16706
#else   /* not SX */
16707
0
  const char *xp = (const char *) *xpp;
16708
0
  int status = NC_NOERR;
16709
16710
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16711
0
  {
16712
0
    const int lstatus = ncx_get_double_int(xp, tp);
16713
0
    if (status == NC_NOERR) /* report the first encountered error */
16714
0
      status = lstatus;
16715
0
  }
16716
16717
0
  *xpp = (const void *)xp;
16718
0
  return status;
16719
0
#endif
16720
0
}
16721
16722
int
16723
ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
16724
0
{
16725
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16726
16727
 /* basic algorithm is:
16728
  *   - ensure sane alignment of input data
16729
  *   - copy (conversion happens automatically) input data
16730
  *     to output
16731
  *   - update xpp to point at next unconverted input, and tp to point
16732
  *     at next location for converted output
16733
  */
16734
  long i, j, ni;
16735
  double tmp[LOOPCNT];        /* in case input is misaligned */
16736
  double *xp;
16737
  int nrange = 0;         /* number of range errors */
16738
  int realign = 0;        /* "do we need to fix input data alignment?" */
16739
  long cxp = (long) *((char**)xpp);
16740
16741
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16742
  /* sjl: manually stripmine so we can limit amount of
16743
   * vector work space reserved to LOOPCNT elements. Also
16744
   * makes vectorisation easy */
16745
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16746
    ni=Min(nelems-j,LOOPCNT);
16747
    if (realign) {
16748
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16749
      xp = tmp;
16750
    } else {
16751
      xp = (double *) *xpp;
16752
    }
16753
   /* copy the next block */
16754
#pragma cdir loopcnt=LOOPCNT
16755
#pragma cdir shortloop
16756
    for (i=0; i<ni; i++) {
16757
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
16758
     /* test for range errors (not always needed but do it anyway) */
16759
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16760
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16761
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
16762
    }
16763
   /* update xpp and tp */
16764
    if (realign) xp = (double *) *xpp;
16765
    xp += ni;
16766
    tp += ni;
16767
    *xpp = (void*)xp;
16768
  }
16769
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16770
16771
#else   /* not SX */
16772
0
  const char *xp = (const char *) *xpp;
16773
0
  int status = NC_NOERR;
16774
16775
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16776
0
  {
16777
0
    const int lstatus = ncx_get_double_long(xp, tp);
16778
0
    if (status == NC_NOERR) /* report the first encountered error */
16779
0
      status = lstatus;
16780
0
  }
16781
16782
0
  *xpp = (const void *)xp;
16783
0
  return status;
16784
0
#endif
16785
0
}
16786
16787
int
16788
ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
16789
0
{
16790
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16791
16792
 /* basic algorithm is:
16793
  *   - ensure sane alignment of input data
16794
  *   - copy (conversion happens automatically) input data
16795
  *     to output
16796
  *   - update xpp to point at next unconverted input, and tp to point
16797
  *     at next location for converted output
16798
  */
16799
  long i, j, ni;
16800
  double tmp[LOOPCNT];        /* in case input is misaligned */
16801
  double *xp;
16802
  int nrange = 0;         /* number of range errors */
16803
  int realign = 0;        /* "do we need to fix input data alignment?" */
16804
  long cxp = (long) *((char**)xpp);
16805
16806
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16807
  /* sjl: manually stripmine so we can limit amount of
16808
   * vector work space reserved to LOOPCNT elements. Also
16809
   * makes vectorisation easy */
16810
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16811
    ni=Min(nelems-j,LOOPCNT);
16812
    if (realign) {
16813
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16814
      xp = tmp;
16815
    } else {
16816
      xp = (double *) *xpp;
16817
    }
16818
   /* copy the next block */
16819
#pragma cdir loopcnt=LOOPCNT
16820
#pragma cdir shortloop
16821
    for (i=0; i<ni; i++) {
16822
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
16823
     /* test for range errors (not always needed but do it anyway) */
16824
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16825
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16826
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
16827
    }
16828
   /* update xpp and tp */
16829
    if (realign) xp = (double *) *xpp;
16830
    xp += ni;
16831
    tp += ni;
16832
    *xpp = (void*)xp;
16833
  }
16834
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16835
16836
#else   /* not SX */
16837
0
  const char *xp = (const char *) *xpp;
16838
0
  int status = NC_NOERR;
16839
16840
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16841
0
  {
16842
0
    const int lstatus = ncx_get_double_float(xp, tp);
16843
0
    if (status == NC_NOERR) /* report the first encountered error */
16844
0
      status = lstatus;
16845
0
  }
16846
16847
0
  *xpp = (const void *)xp;
16848
0
  return status;
16849
0
#endif
16850
0
}
16851
16852
int
16853
ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp)
16854
0
{
16855
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16856
16857
 /* basic algorithm is:
16858
  *   - ensure sane alignment of input data
16859
  *   - copy (conversion happens automatically) input data
16860
  *     to output
16861
  *   - update xpp to point at next unconverted input, and tp to point
16862
  *     at next location for converted output
16863
  */
16864
  long i, j, ni;
16865
  double tmp[LOOPCNT];        /* in case input is misaligned */
16866
  double *xp;
16867
  int nrange = 0;         /* number of range errors */
16868
  int realign = 0;        /* "do we need to fix input data alignment?" */
16869
  long cxp = (long) *((char**)xpp);
16870
16871
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16872
  /* sjl: manually stripmine so we can limit amount of
16873
   * vector work space reserved to LOOPCNT elements. Also
16874
   * makes vectorisation easy */
16875
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16876
    ni=Min(nelems-j,LOOPCNT);
16877
    if (realign) {
16878
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16879
      xp = tmp;
16880
    } else {
16881
      xp = (double *) *xpp;
16882
    }
16883
   /* copy the next block */
16884
#pragma cdir loopcnt=LOOPCNT
16885
#pragma cdir shortloop
16886
    for (i=0; i<ni; i++) {
16887
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
16888
     /* test for range errors (not always needed but do it anyway) */
16889
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16890
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16891
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
16892
    }
16893
   /* update xpp and tp */
16894
    if (realign) xp = (double *) *xpp;
16895
    xp += ni;
16896
    tp += ni;
16897
    *xpp = (void*)xp;
16898
  }
16899
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16900
16901
#else   /* not SX */
16902
0
  const char *xp = (const char *) *xpp;
16903
0
  int status = NC_NOERR;
16904
16905
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16906
0
  {
16907
0
    const int lstatus = ncx_get_double_longlong(xp, tp);
16908
0
    if (status == NC_NOERR) /* report the first encountered error */
16909
0
      status = lstatus;
16910
0
  }
16911
16912
0
  *xpp = (const void *)xp;
16913
0
  return status;
16914
0
#endif
16915
0
}
16916
16917
int
16918
ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
16919
0
{
16920
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16921
16922
 /* basic algorithm is:
16923
  *   - ensure sane alignment of input data
16924
  *   - copy (conversion happens automatically) input data
16925
  *     to output
16926
  *   - update xpp to point at next unconverted input, and tp to point
16927
  *     at next location for converted output
16928
  */
16929
  long i, j, ni;
16930
  double tmp[LOOPCNT];        /* in case input is misaligned */
16931
  double *xp;
16932
  int nrange = 0;         /* number of range errors */
16933
  int realign = 0;        /* "do we need to fix input data alignment?" */
16934
  long cxp = (long) *((char**)xpp);
16935
16936
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16937
  /* sjl: manually stripmine so we can limit amount of
16938
   * vector work space reserved to LOOPCNT elements. Also
16939
   * makes vectorisation easy */
16940
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16941
    ni=Min(nelems-j,LOOPCNT);
16942
    if (realign) {
16943
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16944
      xp = tmp;
16945
    } else {
16946
      xp = (double *) *xpp;
16947
    }
16948
   /* copy the next block */
16949
#pragma cdir loopcnt=LOOPCNT
16950
#pragma cdir shortloop
16951
    for (i=0; i<ni; i++) {
16952
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
16953
     /* test for range errors (not always needed but do it anyway) */
16954
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16955
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16956
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
16957
    }
16958
   /* update xpp and tp */
16959
    if (realign) xp = (double *) *xpp;
16960
    xp += ni;
16961
    tp += ni;
16962
    *xpp = (void*)xp;
16963
  }
16964
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16965
16966
#else   /* not SX */
16967
0
  const char *xp = (const char *) *xpp;
16968
0
  int status = NC_NOERR;
16969
16970
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16971
0
  {
16972
0
    const int lstatus = ncx_get_double_uchar(xp, tp);
16973
0
    if (status == NC_NOERR) /* report the first encountered error */
16974
0
      status = lstatus;
16975
0
  }
16976
16977
0
  *xpp = (const void *)xp;
16978
0
  return status;
16979
0
#endif
16980
0
}
16981
16982
int
16983
ncx_getn_double_ushort(const void **xpp, size_t nelems, ushort *tp)
16984
0
{
16985
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16986
16987
 /* basic algorithm is:
16988
  *   - ensure sane alignment of input data
16989
  *   - copy (conversion happens automatically) input data
16990
  *     to output
16991
  *   - update xpp to point at next unconverted input, and tp to point
16992
  *     at next location for converted output
16993
  */
16994
  long i, j, ni;
16995
  double tmp[LOOPCNT];        /* in case input is misaligned */
16996
  double *xp;
16997
  int nrange = 0;         /* number of range errors */
16998
  int realign = 0;        /* "do we need to fix input data alignment?" */
16999
  long cxp = (long) *((char**)xpp);
17000
17001
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17002
  /* sjl: manually stripmine so we can limit amount of
17003
   * vector work space reserved to LOOPCNT elements. Also
17004
   * makes vectorisation easy */
17005
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17006
    ni=Min(nelems-j,LOOPCNT);
17007
    if (realign) {
17008
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17009
      xp = tmp;
17010
    } else {
17011
      xp = (double *) *xpp;
17012
    }
17013
   /* copy the next block */
17014
#pragma cdir loopcnt=LOOPCNT
17015
#pragma cdir shortloop
17016
    for (i=0; i<ni; i++) {
17017
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
17018
     /* test for range errors (not always needed but do it anyway) */
17019
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17020
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17021
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
17022
    }
17023
   /* update xpp and tp */
17024
    if (realign) xp = (double *) *xpp;
17025
    xp += ni;
17026
    tp += ni;
17027
    *xpp = (void*)xp;
17028
  }
17029
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17030
17031
#else   /* not SX */
17032
0
  const char *xp = (const char *) *xpp;
17033
0
  int status = NC_NOERR;
17034
17035
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17036
0
  {
17037
0
    const int lstatus = ncx_get_double_ushort(xp, tp);
17038
0
    if (status == NC_NOERR) /* report the first encountered error */
17039
0
      status = lstatus;
17040
0
  }
17041
17042
0
  *xpp = (const void *)xp;
17043
0
  return status;
17044
0
#endif
17045
0
}
17046
17047
int
17048
ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp)
17049
0
{
17050
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17051
17052
 /* basic algorithm is:
17053
  *   - ensure sane alignment of input data
17054
  *   - copy (conversion happens automatically) input data
17055
  *     to output
17056
  *   - update xpp to point at next unconverted input, and tp to point
17057
  *     at next location for converted output
17058
  */
17059
  long i, j, ni;
17060
  double tmp[LOOPCNT];        /* in case input is misaligned */
17061
  double *xp;
17062
  int nrange = 0;         /* number of range errors */
17063
  int realign = 0;        /* "do we need to fix input data alignment?" */
17064
  long cxp = (long) *((char**)xpp);
17065
17066
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17067
  /* sjl: manually stripmine so we can limit amount of
17068
   * vector work space reserved to LOOPCNT elements. Also
17069
   * makes vectorisation easy */
17070
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17071
    ni=Min(nelems-j,LOOPCNT);
17072
    if (realign) {
17073
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17074
      xp = tmp;
17075
    } else {
17076
      xp = (double *) *xpp;
17077
    }
17078
   /* copy the next block */
17079
#pragma cdir loopcnt=LOOPCNT
17080
#pragma cdir shortloop
17081
    for (i=0; i<ni; i++) {
17082
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
17083
     /* test for range errors (not always needed but do it anyway) */
17084
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17085
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17086
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
17087
    }
17088
   /* update xpp and tp */
17089
    if (realign) xp = (double *) *xpp;
17090
    xp += ni;
17091
    tp += ni;
17092
    *xpp = (void*)xp;
17093
  }
17094
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17095
17096
#else   /* not SX */
17097
0
  const char *xp = (const char *) *xpp;
17098
0
  int status = NC_NOERR;
17099
17100
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17101
0
  {
17102
0
    const int lstatus = ncx_get_double_uint(xp, tp);
17103
0
    if (status == NC_NOERR) /* report the first encountered error */
17104
0
      status = lstatus;
17105
0
  }
17106
17107
0
  *xpp = (const void *)xp;
17108
0
  return status;
17109
0
#endif
17110
0
}
17111
17112
int
17113
ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
17114
0
{
17115
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17116
17117
 /* basic algorithm is:
17118
  *   - ensure sane alignment of input data
17119
  *   - copy (conversion happens automatically) input data
17120
  *     to output
17121
  *   - update xpp to point at next unconverted input, and tp to point
17122
  *     at next location for converted output
17123
  */
17124
  long i, j, ni;
17125
  double tmp[LOOPCNT];        /* in case input is misaligned */
17126
  double *xp;
17127
  int nrange = 0;         /* number of range errors */
17128
  int realign = 0;        /* "do we need to fix input data alignment?" */
17129
  long cxp = (long) *((char**)xpp);
17130
17131
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17132
  /* sjl: manually stripmine so we can limit amount of
17133
   * vector work space reserved to LOOPCNT elements. Also
17134
   * makes vectorisation easy */
17135
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17136
    ni=Min(nelems-j,LOOPCNT);
17137
    if (realign) {
17138
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17139
      xp = tmp;
17140
    } else {
17141
      xp = (double *) *xpp;
17142
    }
17143
   /* copy the next block */
17144
#pragma cdir loopcnt=LOOPCNT
17145
#pragma cdir shortloop
17146
    for (i=0; i<ni; i++) {
17147
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
17148
     /* test for range errors (not always needed but do it anyway) */
17149
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17150
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17151
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
17152
    }
17153
   /* update xpp and tp */
17154
    if (realign) xp = (double *) *xpp;
17155
    xp += ni;
17156
    tp += ni;
17157
    *xpp = (void*)xp;
17158
  }
17159
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17160
17161
#else   /* not SX */
17162
0
  const char *xp = (const char *) *xpp;
17163
0
  int status = NC_NOERR;
17164
17165
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17166
0
  {
17167
0
    const int lstatus = ncx_get_double_ulonglong(xp, tp);
17168
0
    if (status == NC_NOERR) /* report the first encountered error */
17169
0
      status = lstatus;
17170
0
  }
17171
17172
0
  *xpp = (const void *)xp;
17173
0
  return status;
17174
0
#endif
17175
0
}
17176
17177
17178
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
17179
/* optimized version */
17180
int
17181
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17182
13.0k
{
17183
#ifdef WORDS_BIGENDIAN
17184
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
17185
# else
17186
13.0k
  swapn8b(*xpp, tp, nelems);
17187
13.0k
# endif
17188
13.0k
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
17189
13.0k
  return NC_NOERR;
17190
13.0k
}
17191
#elif defined(vax) && vax != 0
17192
int
17193
ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip, void *fillp)
17194
{
17195
  const double *const end = ip + ndoubles;
17196
17197
  while (ip < end)
17198
  {
17199
  const struct vax_double *const vdp =
17200
      (const struct vax_double *)ip;
17201
  struct ieee_double *const idp =
17202
       (struct ieee_double *) (*xpp);
17203
17204
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
17205
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
17206
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
17207
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
17208
    (vdp->exp == dbl_limits[0].d.exp))
17209
  {
17210
    *idp = dbl_limits[0].ieee;
17211
    goto shipit;
17212
  }
17213
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
17214
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
17215
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
17216
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
17217
    (vdp->exp == dbl_limits[1].d.exp))
17218
  {
17219
    *idp = dbl_limits[1].ieee;
17220
    goto shipit;
17221
  }
17222
17223
  {
17224
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
17225
17226
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
17227
      (vdp->mantissa3 << 13) |
17228
      ((vdp->mantissa4 >> 3) & MASK(13));
17229
17230
    unsigned mant_hi = (vdp->mantissa1 << 13)
17231
         | (vdp->mantissa2 >> 3);
17232
17233
    if ((vdp->mantissa4 & 7) > 4)
17234
    {
17235
      /* round up */
17236
      mant_lo++;
17237
      if (mant_lo == 0)
17238
      {
17239
        mant_hi++;
17240
        if (mant_hi > 0xffffff)
17241
        {
17242
          mant_hi = 0;
17243
          exp++;
17244
        }
17245
      }
17246
    }
17247
17248
    idp->mant_lo = SWAP4(mant_lo);
17249
    idp->mant_6 = mant_hi >> 16;
17250
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
17251
    idp->mant_4 = mant_hi;
17252
    idp->exp_hi = exp >> 4;
17253
    idp->exp_lo = exp;
17254
  }
17255
17256
  shipit:
17257
    idp->sign = vdp->sign;
17258
17259
    ip++;
17260
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
17261
  }
17262
  return NC_NOERR;
17263
}
17264
  /* vax */
17265
#else
17266
int
17267
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17268
{
17269
  char *xp = *xpp;
17270
  int status = NC_NOERR;
17271
17272
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17273
  {
17274
    int lstatus = ncx_put_double_double(xp, tp, fillp);
17275
    if (status == NC_NOERR) /* report the first encountered error */
17276
      status = lstatus;
17277
  }
17278
17279
  *xpp = (void *)xp;
17280
  return status;
17281
}
17282
#endif
17283
int
17284
ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
17285
0
{
17286
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17287
17288
 /* basic algorithm is:
17289
  *   - ensure sane alignment of output data
17290
  *   - copy (conversion happens automatically) input data
17291
  *     to output
17292
  *   - update tp to point at next unconverted input, and xpp to point
17293
  *     at next location for converted output
17294
  */
17295
  long i, j, ni;
17296
  double tmp[LOOPCNT];        /* in case input is misaligned */
17297
  double *xp;
17298
  int nrange = 0;         /* number of range errors */
17299
  int realign = 0;        /* "do we need to fix input data alignment?" */
17300
  long cxp = (long) *((char**)xpp);
17301
17302
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17303
  /* sjl: manually stripmine so we can limit amount of
17304
   * vector work space reserved to LOOPCNT elements. Also
17305
   * makes vectorisation easy */
17306
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17307
    ni=Min(nelems-j,LOOPCNT);
17308
    if (realign) {
17309
      xp = tmp;
17310
    } else {
17311
      xp = (double *) *xpp;
17312
    }
17313
   /* copy the next block */
17314
#pragma cdir loopcnt=LOOPCNT
17315
#pragma cdir shortloop
17316
    for (i=0; i<ni; i++) {
17317
      /* the normal case: */
17318
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17319
     /* test for range errors (not always needed but do it anyway) */
17320
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17321
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17322
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17323
    }
17324
   /* copy workspace back if necessary */
17325
    if (realign) {
17326
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17327
      xp = (double *) *xpp;
17328
    }
17329
   /* update xpp and tp */
17330
    xp += ni;
17331
    tp += ni;
17332
    *xpp = (void*)xp;
17333
  }
17334
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17335
17336
#else   /* not SX */
17337
17338
0
  char *xp = (char *) *xpp;
17339
0
  int status = NC_NOERR;
17340
17341
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17342
0
  {
17343
0
    int lstatus = ncx_put_double_schar(xp, tp, fillp);
17344
0
    if (status == NC_NOERR) /* report the first encountered error */
17345
0
      status = lstatus;
17346
0
  }
17347
17348
0
  *xpp = (void *)xp;
17349
0
  return status;
17350
0
#endif
17351
0
}
17352
17353
int
17354
ncx_putn_double_short(void **xpp, size_t nelems, const short *tp, void *fillp)
17355
0
{
17356
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17357
17358
 /* basic algorithm is:
17359
  *   - ensure sane alignment of output data
17360
  *   - copy (conversion happens automatically) input data
17361
  *     to output
17362
  *   - update tp to point at next unconverted input, and xpp to point
17363
  *     at next location for converted output
17364
  */
17365
  long i, j, ni;
17366
  double tmp[LOOPCNT];        /* in case input is misaligned */
17367
  double *xp;
17368
  int nrange = 0;         /* number of range errors */
17369
  int realign = 0;        /* "do we need to fix input data alignment?" */
17370
  long cxp = (long) *((char**)xpp);
17371
17372
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17373
  /* sjl: manually stripmine so we can limit amount of
17374
   * vector work space reserved to LOOPCNT elements. Also
17375
   * makes vectorisation easy */
17376
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17377
    ni=Min(nelems-j,LOOPCNT);
17378
    if (realign) {
17379
      xp = tmp;
17380
    } else {
17381
      xp = (double *) *xpp;
17382
    }
17383
   /* copy the next block */
17384
#pragma cdir loopcnt=LOOPCNT
17385
#pragma cdir shortloop
17386
    for (i=0; i<ni; i++) {
17387
      /* the normal case: */
17388
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17389
     /* test for range errors (not always needed but do it anyway) */
17390
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17391
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17392
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17393
    }
17394
   /* copy workspace back if necessary */
17395
    if (realign) {
17396
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17397
      xp = (double *) *xpp;
17398
    }
17399
   /* update xpp and tp */
17400
    xp += ni;
17401
    tp += ni;
17402
    *xpp = (void*)xp;
17403
  }
17404
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17405
17406
#else   /* not SX */
17407
17408
0
  char *xp = (char *) *xpp;
17409
0
  int status = NC_NOERR;
17410
17411
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17412
0
  {
17413
0
    int lstatus = ncx_put_double_short(xp, tp, fillp);
17414
0
    if (status == NC_NOERR) /* report the first encountered error */
17415
0
      status = lstatus;
17416
0
  }
17417
17418
0
  *xpp = (void *)xp;
17419
0
  return status;
17420
0
#endif
17421
0
}
17422
17423
int
17424
ncx_putn_double_int(void **xpp, size_t nelems, const int *tp, void *fillp)
17425
0
{
17426
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17427
17428
 /* basic algorithm is:
17429
  *   - ensure sane alignment of output data
17430
  *   - copy (conversion happens automatically) input data
17431
  *     to output
17432
  *   - update tp to point at next unconverted input, and xpp to point
17433
  *     at next location for converted output
17434
  */
17435
  long i, j, ni;
17436
  double tmp[LOOPCNT];        /* in case input is misaligned */
17437
  double *xp;
17438
  int nrange = 0;         /* number of range errors */
17439
  int realign = 0;        /* "do we need to fix input data alignment?" */
17440
  long cxp = (long) *((char**)xpp);
17441
17442
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17443
  /* sjl: manually stripmine so we can limit amount of
17444
   * vector work space reserved to LOOPCNT elements. Also
17445
   * makes vectorisation easy */
17446
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17447
    ni=Min(nelems-j,LOOPCNT);
17448
    if (realign) {
17449
      xp = tmp;
17450
    } else {
17451
      xp = (double *) *xpp;
17452
    }
17453
   /* copy the next block */
17454
#pragma cdir loopcnt=LOOPCNT
17455
#pragma cdir shortloop
17456
    for (i=0; i<ni; i++) {
17457
      /* the normal case: */
17458
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17459
     /* test for range errors (not always needed but do it anyway) */
17460
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17461
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17462
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17463
    }
17464
   /* copy workspace back if necessary */
17465
    if (realign) {
17466
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17467
      xp = (double *) *xpp;
17468
    }
17469
   /* update xpp and tp */
17470
    xp += ni;
17471
    tp += ni;
17472
    *xpp = (void*)xp;
17473
  }
17474
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17475
17476
#else   /* not SX */
17477
17478
0
  char *xp = (char *) *xpp;
17479
0
  int status = NC_NOERR;
17480
17481
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17482
0
  {
17483
0
    int lstatus = ncx_put_double_int(xp, tp, fillp);
17484
0
    if (status == NC_NOERR) /* report the first encountered error */
17485
0
      status = lstatus;
17486
0
  }
17487
17488
0
  *xpp = (void *)xp;
17489
0
  return status;
17490
0
#endif
17491
0
}
17492
17493
int
17494
ncx_putn_double_long(void **xpp, size_t nelems, const long *tp, void *fillp)
17495
0
{
17496
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17497
17498
 /* basic algorithm is:
17499
  *   - ensure sane alignment of output data
17500
  *   - copy (conversion happens automatically) input data
17501
  *     to output
17502
  *   - update tp to point at next unconverted input, and xpp to point
17503
  *     at next location for converted output
17504
  */
17505
  long i, j, ni;
17506
  double tmp[LOOPCNT];        /* in case input is misaligned */
17507
  double *xp;
17508
  int nrange = 0;         /* number of range errors */
17509
  int realign = 0;        /* "do we need to fix input data alignment?" */
17510
  long cxp = (long) *((char**)xpp);
17511
17512
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17513
  /* sjl: manually stripmine so we can limit amount of
17514
   * vector work space reserved to LOOPCNT elements. Also
17515
   * makes vectorisation easy */
17516
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17517
    ni=Min(nelems-j,LOOPCNT);
17518
    if (realign) {
17519
      xp = tmp;
17520
    } else {
17521
      xp = (double *) *xpp;
17522
    }
17523
   /* copy the next block */
17524
#pragma cdir loopcnt=LOOPCNT
17525
#pragma cdir shortloop
17526
    for (i=0; i<ni; i++) {
17527
      /* the normal case: */
17528
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17529
     /* test for range errors (not always needed but do it anyway) */
17530
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17531
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17532
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17533
    }
17534
   /* copy workspace back if necessary */
17535
    if (realign) {
17536
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17537
      xp = (double *) *xpp;
17538
    }
17539
   /* update xpp and tp */
17540
    xp += ni;
17541
    tp += ni;
17542
    *xpp = (void*)xp;
17543
  }
17544
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17545
17546
#else   /* not SX */
17547
17548
0
  char *xp = (char *) *xpp;
17549
0
  int status = NC_NOERR;
17550
17551
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17552
0
  {
17553
0
    int lstatus = ncx_put_double_long(xp, tp, fillp);
17554
0
    if (status == NC_NOERR) /* report the first encountered error */
17555
0
      status = lstatus;
17556
0
  }
17557
17558
0
  *xpp = (void *)xp;
17559
0
  return status;
17560
0
#endif
17561
0
}
17562
17563
int
17564
ncx_putn_double_float(void **xpp, size_t nelems, const float *tp, void *fillp)
17565
0
{
17566
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17567
17568
 /* basic algorithm is:
17569
  *   - ensure sane alignment of output data
17570
  *   - copy (conversion happens automatically) input data
17571
  *     to output
17572
  *   - update tp to point at next unconverted input, and xpp to point
17573
  *     at next location for converted output
17574
  */
17575
  long i, j, ni;
17576
  double tmp[LOOPCNT];        /* in case input is misaligned */
17577
  double *xp;
17578
  int nrange = 0;         /* number of range errors */
17579
  int realign = 0;        /* "do we need to fix input data alignment?" */
17580
  long cxp = (long) *((char**)xpp);
17581
17582
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17583
  /* sjl: manually stripmine so we can limit amount of
17584
   * vector work space reserved to LOOPCNT elements. Also
17585
   * makes vectorisation easy */
17586
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17587
    ni=Min(nelems-j,LOOPCNT);
17588
    if (realign) {
17589
      xp = tmp;
17590
    } else {
17591
      xp = (double *) *xpp;
17592
    }
17593
   /* copy the next block */
17594
#pragma cdir loopcnt=LOOPCNT
17595
#pragma cdir shortloop
17596
    for (i=0; i<ni; i++) {
17597
      /* the normal case: */
17598
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17599
     /* test for range errors (not always needed but do it anyway) */
17600
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17601
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17602
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17603
    }
17604
   /* copy workspace back if necessary */
17605
    if (realign) {
17606
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17607
      xp = (double *) *xpp;
17608
    }
17609
   /* update xpp and tp */
17610
    xp += ni;
17611
    tp += ni;
17612
    *xpp = (void*)xp;
17613
  }
17614
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17615
17616
#else   /* not SX */
17617
17618
0
  char *xp = (char *) *xpp;
17619
0
  int status = NC_NOERR;
17620
17621
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17622
0
  {
17623
0
    int lstatus = ncx_put_double_float(xp, tp, fillp);
17624
0
    if (status == NC_NOERR) /* report the first encountered error */
17625
0
      status = lstatus;
17626
0
  }
17627
17628
0
  *xpp = (void *)xp;
17629
0
  return status;
17630
0
#endif
17631
0
}
17632
17633
int
17634
ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
17635
0
{
17636
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17637
17638
 /* basic algorithm is:
17639
  *   - ensure sane alignment of output data
17640
  *   - copy (conversion happens automatically) input data
17641
  *     to output
17642
  *   - update tp to point at next unconverted input, and xpp to point
17643
  *     at next location for converted output
17644
  */
17645
  long i, j, ni;
17646
  double tmp[LOOPCNT];        /* in case input is misaligned */
17647
  double *xp;
17648
  int nrange = 0;         /* number of range errors */
17649
  int realign = 0;        /* "do we need to fix input data alignment?" */
17650
  long cxp = (long) *((char**)xpp);
17651
17652
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17653
  /* sjl: manually stripmine so we can limit amount of
17654
   * vector work space reserved to LOOPCNT elements. Also
17655
   * makes vectorisation easy */
17656
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17657
    ni=Min(nelems-j,LOOPCNT);
17658
    if (realign) {
17659
      xp = tmp;
17660
    } else {
17661
      xp = (double *) *xpp;
17662
    }
17663
   /* copy the next block */
17664
#pragma cdir loopcnt=LOOPCNT
17665
#pragma cdir shortloop
17666
    for (i=0; i<ni; i++) {
17667
      /* the normal case: */
17668
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17669
     /* test for range errors (not always needed but do it anyway) */
17670
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17671
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17672
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17673
    }
17674
   /* copy workspace back if necessary */
17675
    if (realign) {
17676
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17677
      xp = (double *) *xpp;
17678
    }
17679
   /* update xpp and tp */
17680
    xp += ni;
17681
    tp += ni;
17682
    *xpp = (void*)xp;
17683
  }
17684
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17685
17686
#else   /* not SX */
17687
17688
0
  char *xp = (char *) *xpp;
17689
0
  int status = NC_NOERR;
17690
17691
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17692
0
  {
17693
0
    int lstatus = ncx_put_double_longlong(xp, tp, fillp);
17694
0
    if (status == NC_NOERR) /* report the first encountered error */
17695
0
      status = lstatus;
17696
0
  }
17697
17698
0
  *xpp = (void *)xp;
17699
0
  return status;
17700
0
#endif
17701
0
}
17702
17703
int
17704
ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
17705
0
{
17706
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17707
17708
 /* basic algorithm is:
17709
  *   - ensure sane alignment of output data
17710
  *   - copy (conversion happens automatically) input data
17711
  *     to output
17712
  *   - update tp to point at next unconverted input, and xpp to point
17713
  *     at next location for converted output
17714
  */
17715
  long i, j, ni;
17716
  double tmp[LOOPCNT];        /* in case input is misaligned */
17717
  double *xp;
17718
  int nrange = 0;         /* number of range errors */
17719
  int realign = 0;        /* "do we need to fix input data alignment?" */
17720
  long cxp = (long) *((char**)xpp);
17721
17722
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17723
  /* sjl: manually stripmine so we can limit amount of
17724
   * vector work space reserved to LOOPCNT elements. Also
17725
   * makes vectorisation easy */
17726
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17727
    ni=Min(nelems-j,LOOPCNT);
17728
    if (realign) {
17729
      xp = tmp;
17730
    } else {
17731
      xp = (double *) *xpp;
17732
    }
17733
   /* copy the next block */
17734
#pragma cdir loopcnt=LOOPCNT
17735
#pragma cdir shortloop
17736
    for (i=0; i<ni; i++) {
17737
      /* the normal case: */
17738
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17739
     /* test for range errors (not always needed but do it anyway) */
17740
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17741
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17742
      nrange += tp[i] > X_DOUBLE_MAX ;
17743
    }
17744
   /* copy workspace back if necessary */
17745
    if (realign) {
17746
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17747
      xp = (double *) *xpp;
17748
    }
17749
   /* update xpp and tp */
17750
    xp += ni;
17751
    tp += ni;
17752
    *xpp = (void*)xp;
17753
  }
17754
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17755
17756
#else   /* not SX */
17757
17758
0
  char *xp = (char *) *xpp;
17759
0
  int status = NC_NOERR;
17760
17761
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17762
0
  {
17763
0
    int lstatus = ncx_put_double_uchar(xp, tp, fillp);
17764
0
    if (status == NC_NOERR) /* report the first encountered error */
17765
0
      status = lstatus;
17766
0
  }
17767
17768
0
  *xpp = (void *)xp;
17769
0
  return status;
17770
0
#endif
17771
0
}
17772
17773
int
17774
ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
17775
0
{
17776
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17777
17778
 /* basic algorithm is:
17779
  *   - ensure sane alignment of output data
17780
  *   - copy (conversion happens automatically) input data
17781
  *     to output
17782
  *   - update tp to point at next unconverted input, and xpp to point
17783
  *     at next location for converted output
17784
  */
17785
  long i, j, ni;
17786
  double tmp[LOOPCNT];        /* in case input is misaligned */
17787
  double *xp;
17788
  int nrange = 0;         /* number of range errors */
17789
  int realign = 0;        /* "do we need to fix input data alignment?" */
17790
  long cxp = (long) *((char**)xpp);
17791
17792
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17793
  /* sjl: manually stripmine so we can limit amount of
17794
   * vector work space reserved to LOOPCNT elements. Also
17795
   * makes vectorisation easy */
17796
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17797
    ni=Min(nelems-j,LOOPCNT);
17798
    if (realign) {
17799
      xp = tmp;
17800
    } else {
17801
      xp = (double *) *xpp;
17802
    }
17803
   /* copy the next block */
17804
#pragma cdir loopcnt=LOOPCNT
17805
#pragma cdir shortloop
17806
    for (i=0; i<ni; i++) {
17807
      /* the normal case: */
17808
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17809
     /* test for range errors (not always needed but do it anyway) */
17810
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17811
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17812
      nrange += tp[i] > X_DOUBLE_MAX ;
17813
    }
17814
   /* copy workspace back if necessary */
17815
    if (realign) {
17816
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17817
      xp = (double *) *xpp;
17818
    }
17819
   /* update xpp and tp */
17820
    xp += ni;
17821
    tp += ni;
17822
    *xpp = (void*)xp;
17823
  }
17824
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17825
17826
#else   /* not SX */
17827
17828
0
  char *xp = (char *) *xpp;
17829
0
  int status = NC_NOERR;
17830
17831
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17832
0
  {
17833
0
    int lstatus = ncx_put_double_ushort(xp, tp, fillp);
17834
0
    if (status == NC_NOERR) /* report the first encountered error */
17835
0
      status = lstatus;
17836
0
  }
17837
17838
0
  *xpp = (void *)xp;
17839
0
  return status;
17840
0
#endif
17841
0
}
17842
17843
int
17844
ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
17845
0
{
17846
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17847
17848
 /* basic algorithm is:
17849
  *   - ensure sane alignment of output data
17850
  *   - copy (conversion happens automatically) input data
17851
  *     to output
17852
  *   - update tp to point at next unconverted input, and xpp to point
17853
  *     at next location for converted output
17854
  */
17855
  long i, j, ni;
17856
  double tmp[LOOPCNT];        /* in case input is misaligned */
17857
  double *xp;
17858
  int nrange = 0;         /* number of range errors */
17859
  int realign = 0;        /* "do we need to fix input data alignment?" */
17860
  long cxp = (long) *((char**)xpp);
17861
17862
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17863
  /* sjl: manually stripmine so we can limit amount of
17864
   * vector work space reserved to LOOPCNT elements. Also
17865
   * makes vectorisation easy */
17866
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17867
    ni=Min(nelems-j,LOOPCNT);
17868
    if (realign) {
17869
      xp = tmp;
17870
    } else {
17871
      xp = (double *) *xpp;
17872
    }
17873
   /* copy the next block */
17874
#pragma cdir loopcnt=LOOPCNT
17875
#pragma cdir shortloop
17876
    for (i=0; i<ni; i++) {
17877
      /* the normal case: */
17878
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17879
     /* test for range errors (not always needed but do it anyway) */
17880
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17881
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17882
      nrange += tp[i] > X_DOUBLE_MAX ;
17883
    }
17884
   /* copy workspace back if necessary */
17885
    if (realign) {
17886
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17887
      xp = (double *) *xpp;
17888
    }
17889
   /* update xpp and tp */
17890
    xp += ni;
17891
    tp += ni;
17892
    *xpp = (void*)xp;
17893
  }
17894
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17895
17896
#else   /* not SX */
17897
17898
0
  char *xp = (char *) *xpp;
17899
0
  int status = NC_NOERR;
17900
17901
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17902
0
  {
17903
0
    int lstatus = ncx_put_double_uint(xp, tp, fillp);
17904
0
    if (status == NC_NOERR) /* report the first encountered error */
17905
0
      status = lstatus;
17906
0
  }
17907
17908
0
  *xpp = (void *)xp;
17909
0
  return status;
17910
0
#endif
17911
0
}
17912
17913
int
17914
ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
17915
0
{
17916
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17917
17918
 /* basic algorithm is:
17919
  *   - ensure sane alignment of output data
17920
  *   - copy (conversion happens automatically) input data
17921
  *     to output
17922
  *   - update tp to point at next unconverted input, and xpp to point
17923
  *     at next location for converted output
17924
  */
17925
  long i, j, ni;
17926
  double tmp[LOOPCNT];        /* in case input is misaligned */
17927
  double *xp;
17928
  int nrange = 0;         /* number of range errors */
17929
  int realign = 0;        /* "do we need to fix input data alignment?" */
17930
  long cxp = (long) *((char**)xpp);
17931
17932
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17933
  /* sjl: manually stripmine so we can limit amount of
17934
   * vector work space reserved to LOOPCNT elements. Also
17935
   * makes vectorisation easy */
17936
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17937
    ni=Min(nelems-j,LOOPCNT);
17938
    if (realign) {
17939
      xp = tmp;
17940
    } else {
17941
      xp = (double *) *xpp;
17942
    }
17943
   /* copy the next block */
17944
#pragma cdir loopcnt=LOOPCNT
17945
#pragma cdir shortloop
17946
    for (i=0; i<ni; i++) {
17947
      /* the normal case: */
17948
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17949
     /* test for range errors (not always needed but do it anyway) */
17950
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17951
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17952
      nrange += tp[i] > X_DOUBLE_MAX ;
17953
    }
17954
   /* copy workspace back if necessary */
17955
    if (realign) {
17956
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17957
      xp = (double *) *xpp;
17958
    }
17959
   /* update xpp and tp */
17960
    xp += ni;
17961
    tp += ni;
17962
    *xpp = (void*)xp;
17963
  }
17964
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17965
17966
#else   /* not SX */
17967
17968
0
  char *xp = (char *) *xpp;
17969
0
  int status = NC_NOERR;
17970
17971
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17972
0
  {
17973
0
    int lstatus = ncx_put_double_ulonglong(xp, tp, fillp);
17974
0
    if (status == NC_NOERR) /* report the first encountered error */
17975
0
      status = lstatus;
17976
0
  }
17977
17978
0
  *xpp = (void *)xp;
17979
0
  return status;
17980
0
#endif
17981
0
}
17982
17983
17984
17985
/* longlong ------------------------------------------------------------------*/
17986
17987
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
17988
/* optimized version */
17989
int
17990
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
17991
0
{
17992
#ifdef WORDS_BIGENDIAN
17993
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
17994
# else
17995
0
  swapn8b(tp, *xpp, nelems);
17996
0
# endif
17997
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
17998
0
  return NC_NOERR;
17999
0
}
18000
#else
18001
int
18002
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, longlong *tp)
18003
{
18004
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18005
18006
 /* basic algorithm is:
18007
  *   - ensure sane alignment of input data
18008
  *   - copy (conversion happens automatically) input data
18009
  *     to output
18010
  *   - update xpp to point at next unconverted input, and tp to point
18011
  *     at next location for converted output
18012
  */
18013
  long i, j, ni;
18014
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18015
  int64 *xp;
18016
  int nrange = 0;         /* number of range errors */
18017
  int realign = 0;        /* "do we need to fix input data alignment?" */
18018
  long cxp = (long) *((char**)xpp);
18019
18020
  realign = (cxp & 7) % SIZEOF_INT64;
18021
  /* sjl: manually stripmine so we can limit amount of
18022
   * vector work space reserved to LOOPCNT elements. Also
18023
   * makes vectorisation easy */
18024
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18025
    ni=Min(nelems-j,LOOPCNT);
18026
    if (realign) {
18027
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18028
      xp = tmp;
18029
    } else {
18030
      xp = (int64 *) *xpp;
18031
    }
18032
   /* copy the next block */
18033
#pragma cdir loopcnt=LOOPCNT
18034
#pragma cdir shortloop
18035
    for (i=0; i<ni; i++) {
18036
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
18037
     /* test for range errors (not always needed but do it anyway) */
18038
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18039
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18040
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
18041
    }
18042
   /* update xpp and tp */
18043
    if (realign) xp = (int64 *) *xpp;
18044
    xp += ni;
18045
    tp += ni;
18046
    *xpp = (void*)xp;
18047
  }
18048
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18049
18050
#else   /* not SX */
18051
  const char *xp = (const char *) *xpp;
18052
  int status = NC_NOERR;
18053
18054
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18055
  {
18056
    const int lstatus = ncx_get_longlong_longlong(xp, tp);
18057
    if (status == NC_NOERR) /* report the first encountered error */
18058
      status = lstatus;
18059
  }
18060
18061
  *xpp = (const void *)xp;
18062
  return status;
18063
#endif
18064
}
18065
18066
#endif
18067
int
18068
ncx_getn_longlong_schar(const void **xpp, size_t nelems, schar *tp)
18069
0
{
18070
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18071
18072
 /* basic algorithm is:
18073
  *   - ensure sane alignment of input data
18074
  *   - copy (conversion happens automatically) input data
18075
  *     to output
18076
  *   - update xpp to point at next unconverted input, and tp to point
18077
  *     at next location for converted output
18078
  */
18079
  long i, j, ni;
18080
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18081
  int64 *xp;
18082
  int nrange = 0;         /* number of range errors */
18083
  int realign = 0;        /* "do we need to fix input data alignment?" */
18084
  long cxp = (long) *((char**)xpp);
18085
18086
  realign = (cxp & 7) % SIZEOF_INT64;
18087
  /* sjl: manually stripmine so we can limit amount of
18088
   * vector work space reserved to LOOPCNT elements. Also
18089
   * makes vectorisation easy */
18090
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18091
    ni=Min(nelems-j,LOOPCNT);
18092
    if (realign) {
18093
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18094
      xp = tmp;
18095
    } else {
18096
      xp = (int64 *) *xpp;
18097
    }
18098
   /* copy the next block */
18099
#pragma cdir loopcnt=LOOPCNT
18100
#pragma cdir shortloop
18101
    for (i=0; i<ni; i++) {
18102
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
18103
     /* test for range errors (not always needed but do it anyway) */
18104
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18105
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18106
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
18107
    }
18108
   /* update xpp and tp */
18109
    if (realign) xp = (int64 *) *xpp;
18110
    xp += ni;
18111
    tp += ni;
18112
    *xpp = (void*)xp;
18113
  }
18114
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18115
18116
#else   /* not SX */
18117
0
  const char *xp = (const char *) *xpp;
18118
0
  int status = NC_NOERR;
18119
18120
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18121
0
  {
18122
0
    const int lstatus = ncx_get_longlong_schar(xp, tp);
18123
0
    if (status == NC_NOERR) /* report the first encountered error */
18124
0
      status = lstatus;
18125
0
  }
18126
18127
0
  *xpp = (const void *)xp;
18128
0
  return status;
18129
0
#endif
18130
0
}
18131
18132
int
18133
ncx_getn_longlong_short(const void **xpp, size_t nelems, short *tp)
18134
0
{
18135
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18136
18137
 /* basic algorithm is:
18138
  *   - ensure sane alignment of input data
18139
  *   - copy (conversion happens automatically) input data
18140
  *     to output
18141
  *   - update xpp to point at next unconverted input, and tp to point
18142
  *     at next location for converted output
18143
  */
18144
  long i, j, ni;
18145
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18146
  int64 *xp;
18147
  int nrange = 0;         /* number of range errors */
18148
  int realign = 0;        /* "do we need to fix input data alignment?" */
18149
  long cxp = (long) *((char**)xpp);
18150
18151
  realign = (cxp & 7) % SIZEOF_INT64;
18152
  /* sjl: manually stripmine so we can limit amount of
18153
   * vector work space reserved to LOOPCNT elements. Also
18154
   * makes vectorisation easy */
18155
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18156
    ni=Min(nelems-j,LOOPCNT);
18157
    if (realign) {
18158
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18159
      xp = tmp;
18160
    } else {
18161
      xp = (int64 *) *xpp;
18162
    }
18163
   /* copy the next block */
18164
#pragma cdir loopcnt=LOOPCNT
18165
#pragma cdir shortloop
18166
    for (i=0; i<ni; i++) {
18167
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
18168
     /* test for range errors (not always needed but do it anyway) */
18169
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18170
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18171
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
18172
    }
18173
   /* update xpp and tp */
18174
    if (realign) xp = (int64 *) *xpp;
18175
    xp += ni;
18176
    tp += ni;
18177
    *xpp = (void*)xp;
18178
  }
18179
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18180
18181
#else   /* not SX */
18182
0
  const char *xp = (const char *) *xpp;
18183
0
  int status = NC_NOERR;
18184
18185
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18186
0
  {
18187
0
    const int lstatus = ncx_get_longlong_short(xp, tp);
18188
0
    if (status == NC_NOERR) /* report the first encountered error */
18189
0
      status = lstatus;
18190
0
  }
18191
18192
0
  *xpp = (const void *)xp;
18193
0
  return status;
18194
0
#endif
18195
0
}
18196
18197
int
18198
ncx_getn_longlong_int(const void **xpp, size_t nelems, int *tp)
18199
0
{
18200
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18201
18202
 /* basic algorithm is:
18203
  *   - ensure sane alignment of input data
18204
  *   - copy (conversion happens automatically) input data
18205
  *     to output
18206
  *   - update xpp to point at next unconverted input, and tp to point
18207
  *     at next location for converted output
18208
  */
18209
  long i, j, ni;
18210
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18211
  int64 *xp;
18212
  int nrange = 0;         /* number of range errors */
18213
  int realign = 0;        /* "do we need to fix input data alignment?" */
18214
  long cxp = (long) *((char**)xpp);
18215
18216
  realign = (cxp & 7) % SIZEOF_INT64;
18217
  /* sjl: manually stripmine so we can limit amount of
18218
   * vector work space reserved to LOOPCNT elements. Also
18219
   * makes vectorisation easy */
18220
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18221
    ni=Min(nelems-j,LOOPCNT);
18222
    if (realign) {
18223
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18224
      xp = tmp;
18225
    } else {
18226
      xp = (int64 *) *xpp;
18227
    }
18228
   /* copy the next block */
18229
#pragma cdir loopcnt=LOOPCNT
18230
#pragma cdir shortloop
18231
    for (i=0; i<ni; i++) {
18232
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
18233
     /* test for range errors (not always needed but do it anyway) */
18234
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18235
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18236
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
18237
    }
18238
   /* update xpp and tp */
18239
    if (realign) xp = (int64 *) *xpp;
18240
    xp += ni;
18241
    tp += ni;
18242
    *xpp = (void*)xp;
18243
  }
18244
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18245
18246
#else   /* not SX */
18247
0
  const char *xp = (const char *) *xpp;
18248
0
  int status = NC_NOERR;
18249
18250
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18251
0
  {
18252
0
    const int lstatus = ncx_get_longlong_int(xp, tp);
18253
0
    if (status == NC_NOERR) /* report the first encountered error */
18254
0
      status = lstatus;
18255
0
  }
18256
18257
0
  *xpp = (const void *)xp;
18258
0
  return status;
18259
0
#endif
18260
0
}
18261
18262
int
18263
ncx_getn_longlong_long(const void **xpp, size_t nelems, long *tp)
18264
0
{
18265
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18266
18267
 /* basic algorithm is:
18268
  *   - ensure sane alignment of input data
18269
  *   - copy (conversion happens automatically) input data
18270
  *     to output
18271
  *   - update xpp to point at next unconverted input, and tp to point
18272
  *     at next location for converted output
18273
  */
18274
  long i, j, ni;
18275
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18276
  int64 *xp;
18277
  int nrange = 0;         /* number of range errors */
18278
  int realign = 0;        /* "do we need to fix input data alignment?" */
18279
  long cxp = (long) *((char**)xpp);
18280
18281
  realign = (cxp & 7) % SIZEOF_INT64;
18282
  /* sjl: manually stripmine so we can limit amount of
18283
   * vector work space reserved to LOOPCNT elements. Also
18284
   * makes vectorisation easy */
18285
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18286
    ni=Min(nelems-j,LOOPCNT);
18287
    if (realign) {
18288
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18289
      xp = tmp;
18290
    } else {
18291
      xp = (int64 *) *xpp;
18292
    }
18293
   /* copy the next block */
18294
#pragma cdir loopcnt=LOOPCNT
18295
#pragma cdir shortloop
18296
    for (i=0; i<ni; i++) {
18297
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
18298
     /* test for range errors (not always needed but do it anyway) */
18299
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18300
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18301
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
18302
    }
18303
   /* update xpp and tp */
18304
    if (realign) xp = (int64 *) *xpp;
18305
    xp += ni;
18306
    tp += ni;
18307
    *xpp = (void*)xp;
18308
  }
18309
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18310
18311
#else   /* not SX */
18312
0
  const char *xp = (const char *) *xpp;
18313
0
  int status = NC_NOERR;
18314
18315
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18316
0
  {
18317
0
    const int lstatus = ncx_get_longlong_long(xp, tp);
18318
0
    if (status == NC_NOERR) /* report the first encountered error */
18319
0
      status = lstatus;
18320
0
  }
18321
18322
0
  *xpp = (const void *)xp;
18323
0
  return status;
18324
0
#endif
18325
0
}
18326
18327
int
18328
ncx_getn_longlong_float(const void **xpp, size_t nelems, float *tp)
18329
0
{
18330
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18331
18332
 /* basic algorithm is:
18333
  *   - ensure sane alignment of input data
18334
  *   - copy (conversion happens automatically) input data
18335
  *     to output
18336
  *   - update xpp to point at next unconverted input, and tp to point
18337
  *     at next location for converted output
18338
  */
18339
  long i, j, ni;
18340
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18341
  int64 *xp;
18342
  int nrange = 0;         /* number of range errors */
18343
  int realign = 0;        /* "do we need to fix input data alignment?" */
18344
  long cxp = (long) *((char**)xpp);
18345
18346
  realign = (cxp & 7) % SIZEOF_INT64;
18347
  /* sjl: manually stripmine so we can limit amount of
18348
   * vector work space reserved to LOOPCNT elements. Also
18349
   * makes vectorisation easy */
18350
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18351
    ni=Min(nelems-j,LOOPCNT);
18352
    if (realign) {
18353
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18354
      xp = tmp;
18355
    } else {
18356
      xp = (int64 *) *xpp;
18357
    }
18358
   /* copy the next block */
18359
#pragma cdir loopcnt=LOOPCNT
18360
#pragma cdir shortloop
18361
    for (i=0; i<ni; i++) {
18362
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
18363
     /* test for range errors (not always needed but do it anyway) */
18364
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18365
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18366
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
18367
    }
18368
   /* update xpp and tp */
18369
    if (realign) xp = (int64 *) *xpp;
18370
    xp += ni;
18371
    tp += ni;
18372
    *xpp = (void*)xp;
18373
  }
18374
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18375
18376
#else   /* not SX */
18377
0
  const char *xp = (const char *) *xpp;
18378
0
  int status = NC_NOERR;
18379
18380
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18381
0
  {
18382
0
    const int lstatus = ncx_get_longlong_float(xp, tp);
18383
0
    if (status == NC_NOERR) /* report the first encountered error */
18384
0
      status = lstatus;
18385
0
  }
18386
18387
0
  *xpp = (const void *)xp;
18388
0
  return status;
18389
0
#endif
18390
0
}
18391
18392
int
18393
ncx_getn_longlong_double(const void **xpp, size_t nelems, double *tp)
18394
0
{
18395
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18396
18397
 /* basic algorithm is:
18398
  *   - ensure sane alignment of input data
18399
  *   - copy (conversion happens automatically) input data
18400
  *     to output
18401
  *   - update xpp to point at next unconverted input, and tp to point
18402
  *     at next location for converted output
18403
  */
18404
  long i, j, ni;
18405
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18406
  int64 *xp;
18407
  int nrange = 0;         /* number of range errors */
18408
  int realign = 0;        /* "do we need to fix input data alignment?" */
18409
  long cxp = (long) *((char**)xpp);
18410
18411
  realign = (cxp & 7) % SIZEOF_INT64;
18412
  /* sjl: manually stripmine so we can limit amount of
18413
   * vector work space reserved to LOOPCNT elements. Also
18414
   * makes vectorisation easy */
18415
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18416
    ni=Min(nelems-j,LOOPCNT);
18417
    if (realign) {
18418
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18419
      xp = tmp;
18420
    } else {
18421
      xp = (int64 *) *xpp;
18422
    }
18423
   /* copy the next block */
18424
#pragma cdir loopcnt=LOOPCNT
18425
#pragma cdir shortloop
18426
    for (i=0; i<ni; i++) {
18427
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
18428
     /* test for range errors (not always needed but do it anyway) */
18429
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18430
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18431
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
18432
    }
18433
   /* update xpp and tp */
18434
    if (realign) xp = (int64 *) *xpp;
18435
    xp += ni;
18436
    tp += ni;
18437
    *xpp = (void*)xp;
18438
  }
18439
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18440
18441
#else   /* not SX */
18442
0
  const char *xp = (const char *) *xpp;
18443
0
  int status = NC_NOERR;
18444
18445
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18446
0
  {
18447
0
    const int lstatus = ncx_get_longlong_double(xp, tp);
18448
0
    if (status == NC_NOERR) /* report the first encountered error */
18449
0
      status = lstatus;
18450
0
  }
18451
18452
0
  *xpp = (const void *)xp;
18453
0
  return status;
18454
0
#endif
18455
0
}
18456
18457
int
18458
ncx_getn_longlong_uchar(const void **xpp, size_t nelems, uchar *tp)
18459
0
{
18460
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18461
18462
 /* basic algorithm is:
18463
  *   - ensure sane alignment of input data
18464
  *   - copy (conversion happens automatically) input data
18465
  *     to output
18466
  *   - update xpp to point at next unconverted input, and tp to point
18467
  *     at next location for converted output
18468
  */
18469
  long i, j, ni;
18470
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18471
  int64 *xp;
18472
  int nrange = 0;         /* number of range errors */
18473
  int realign = 0;        /* "do we need to fix input data alignment?" */
18474
  long cxp = (long) *((char**)xpp);
18475
18476
  realign = (cxp & 7) % SIZEOF_INT64;
18477
  /* sjl: manually stripmine so we can limit amount of
18478
   * vector work space reserved to LOOPCNT elements. Also
18479
   * makes vectorisation easy */
18480
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18481
    ni=Min(nelems-j,LOOPCNT);
18482
    if (realign) {
18483
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18484
      xp = tmp;
18485
    } else {
18486
      xp = (int64 *) *xpp;
18487
    }
18488
   /* copy the next block */
18489
#pragma cdir loopcnt=LOOPCNT
18490
#pragma cdir shortloop
18491
    for (i=0; i<ni; i++) {
18492
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
18493
     /* test for range errors (not always needed but do it anyway) */
18494
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18495
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18496
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
18497
    }
18498
   /* update xpp and tp */
18499
    if (realign) xp = (int64 *) *xpp;
18500
    xp += ni;
18501
    tp += ni;
18502
    *xpp = (void*)xp;
18503
  }
18504
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18505
18506
#else   /* not SX */
18507
0
  const char *xp = (const char *) *xpp;
18508
0
  int status = NC_NOERR;
18509
18510
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18511
0
  {
18512
0
    const int lstatus = ncx_get_longlong_uchar(xp, tp);
18513
0
    if (status == NC_NOERR) /* report the first encountered error */
18514
0
      status = lstatus;
18515
0
  }
18516
18517
0
  *xpp = (const void *)xp;
18518
0
  return status;
18519
0
#endif
18520
0
}
18521
18522
int
18523
ncx_getn_longlong_ushort(const void **xpp, size_t nelems, ushort *tp)
18524
0
{
18525
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18526
18527
 /* basic algorithm is:
18528
  *   - ensure sane alignment of input data
18529
  *   - copy (conversion happens automatically) input data
18530
  *     to output
18531
  *   - update xpp to point at next unconverted input, and tp to point
18532
  *     at next location for converted output
18533
  */
18534
  long i, j, ni;
18535
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18536
  int64 *xp;
18537
  int nrange = 0;         /* number of range errors */
18538
  int realign = 0;        /* "do we need to fix input data alignment?" */
18539
  long cxp = (long) *((char**)xpp);
18540
18541
  realign = (cxp & 7) % SIZEOF_INT64;
18542
  /* sjl: manually stripmine so we can limit amount of
18543
   * vector work space reserved to LOOPCNT elements. Also
18544
   * makes vectorisation easy */
18545
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18546
    ni=Min(nelems-j,LOOPCNT);
18547
    if (realign) {
18548
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18549
      xp = tmp;
18550
    } else {
18551
      xp = (int64 *) *xpp;
18552
    }
18553
   /* copy the next block */
18554
#pragma cdir loopcnt=LOOPCNT
18555
#pragma cdir shortloop
18556
    for (i=0; i<ni; i++) {
18557
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
18558
     /* test for range errors (not always needed but do it anyway) */
18559
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18560
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18561
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
18562
    }
18563
   /* update xpp and tp */
18564
    if (realign) xp = (int64 *) *xpp;
18565
    xp += ni;
18566
    tp += ni;
18567
    *xpp = (void*)xp;
18568
  }
18569
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18570
18571
#else   /* not SX */
18572
0
  const char *xp = (const char *) *xpp;
18573
0
  int status = NC_NOERR;
18574
18575
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18576
0
  {
18577
0
    const int lstatus = ncx_get_longlong_ushort(xp, tp);
18578
0
    if (status == NC_NOERR) /* report the first encountered error */
18579
0
      status = lstatus;
18580
0
  }
18581
18582
0
  *xpp = (const void *)xp;
18583
0
  return status;
18584
0
#endif
18585
0
}
18586
18587
int
18588
ncx_getn_longlong_uint(const void **xpp, size_t nelems, uint *tp)
18589
0
{
18590
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18591
18592
 /* basic algorithm is:
18593
  *   - ensure sane alignment of input data
18594
  *   - copy (conversion happens automatically) input data
18595
  *     to output
18596
  *   - update xpp to point at next unconverted input, and tp to point
18597
  *     at next location for converted output
18598
  */
18599
  long i, j, ni;
18600
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18601
  int64 *xp;
18602
  int nrange = 0;         /* number of range errors */
18603
  int realign = 0;        /* "do we need to fix input data alignment?" */
18604
  long cxp = (long) *((char**)xpp);
18605
18606
  realign = (cxp & 7) % SIZEOF_INT64;
18607
  /* sjl: manually stripmine so we can limit amount of
18608
   * vector work space reserved to LOOPCNT elements. Also
18609
   * makes vectorisation easy */
18610
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18611
    ni=Min(nelems-j,LOOPCNT);
18612
    if (realign) {
18613
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18614
      xp = tmp;
18615
    } else {
18616
      xp = (int64 *) *xpp;
18617
    }
18618
   /* copy the next block */
18619
#pragma cdir loopcnt=LOOPCNT
18620
#pragma cdir shortloop
18621
    for (i=0; i<ni; i++) {
18622
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
18623
     /* test for range errors (not always needed but do it anyway) */
18624
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18625
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18626
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
18627
    }
18628
   /* update xpp and tp */
18629
    if (realign) xp = (int64 *) *xpp;
18630
    xp += ni;
18631
    tp += ni;
18632
    *xpp = (void*)xp;
18633
  }
18634
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18635
18636
#else   /* not SX */
18637
0
  const char *xp = (const char *) *xpp;
18638
0
  int status = NC_NOERR;
18639
18640
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18641
0
  {
18642
0
    const int lstatus = ncx_get_longlong_uint(xp, tp);
18643
0
    if (status == NC_NOERR) /* report the first encountered error */
18644
0
      status = lstatus;
18645
0
  }
18646
18647
0
  *xpp = (const void *)xp;
18648
0
  return status;
18649
0
#endif
18650
0
}
18651
18652
int
18653
ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
18654
0
{
18655
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18656
18657
 /* basic algorithm is:
18658
  *   - ensure sane alignment of input data
18659
  *   - copy (conversion happens automatically) input data
18660
  *     to output
18661
  *   - update xpp to point at next unconverted input, and tp to point
18662
  *     at next location for converted output
18663
  */
18664
  long i, j, ni;
18665
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18666
  int64 *xp;
18667
  int nrange = 0;         /* number of range errors */
18668
  int realign = 0;        /* "do we need to fix input data alignment?" */
18669
  long cxp = (long) *((char**)xpp);
18670
18671
  realign = (cxp & 7) % SIZEOF_INT64;
18672
  /* sjl: manually stripmine so we can limit amount of
18673
   * vector work space reserved to LOOPCNT elements. Also
18674
   * makes vectorisation easy */
18675
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18676
    ni=Min(nelems-j,LOOPCNT);
18677
    if (realign) {
18678
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18679
      xp = tmp;
18680
    } else {
18681
      xp = (int64 *) *xpp;
18682
    }
18683
   /* copy the next block */
18684
#pragma cdir loopcnt=LOOPCNT
18685
#pragma cdir shortloop
18686
    for (i=0; i<ni; i++) {
18687
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
18688
     /* test for range errors (not always needed but do it anyway) */
18689
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18690
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18691
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
18692
    }
18693
   /* update xpp and tp */
18694
    if (realign) xp = (int64 *) *xpp;
18695
    xp += ni;
18696
    tp += ni;
18697
    *xpp = (void*)xp;
18698
  }
18699
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18700
18701
#else   /* not SX */
18702
0
  const char *xp = (const char *) *xpp;
18703
0
  int status = NC_NOERR;
18704
18705
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18706
0
  {
18707
0
    const int lstatus = ncx_get_longlong_ulonglong(xp, tp);
18708
0
    if (status == NC_NOERR) /* report the first encountered error */
18709
0
      status = lstatus;
18710
0
  }
18711
18712
0
  *xpp = (const void *)xp;
18713
0
  return status;
18714
0
#endif
18715
0
}
18716
18717
18718
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
18719
/* optimized version */
18720
int
18721
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp, void *fillp)
18722
0
{
18723
#ifdef WORDS_BIGENDIAN
18724
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
18725
# else
18726
0
  swapn8b(*xpp, tp, nelems);
18727
0
# endif
18728
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
18729
0
  return NC_NOERR;
18730
0
}
18731
#else
18732
int
18733
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
18734
{
18735
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18736
18737
 /* basic algorithm is:
18738
  *   - ensure sane alignment of output data
18739
  *   - copy (conversion happens automatically) input data
18740
  *     to output
18741
  *   - update tp to point at next unconverted input, and xpp to point
18742
  *     at next location for converted output
18743
  */
18744
  long i, j, ni;
18745
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18746
  int64 *xp;
18747
  int nrange = 0;         /* number of range errors */
18748
  int realign = 0;        /* "do we need to fix input data alignment?" */
18749
  long cxp = (long) *((char**)xpp);
18750
18751
  realign = (cxp & 7) % SIZEOF_INT64;
18752
  /* sjl: manually stripmine so we can limit amount of
18753
   * vector work space reserved to LOOPCNT elements. Also
18754
   * makes vectorisation easy */
18755
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18756
    ni=Min(nelems-j,LOOPCNT);
18757
    if (realign) {
18758
      xp = tmp;
18759
    } else {
18760
      xp = (int64 *) *xpp;
18761
    }
18762
   /* copy the next block */
18763
#pragma cdir loopcnt=LOOPCNT
18764
#pragma cdir shortloop
18765
    for (i=0; i<ni; i++) {
18766
      /* the normal case: */
18767
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18768
     /* test for range errors (not always needed but do it anyway) */
18769
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18770
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18771
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18772
    }
18773
   /* copy workspace back if necessary */
18774
    if (realign) {
18775
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18776
      xp = (int64 *) *xpp;
18777
    }
18778
   /* update xpp and tp */
18779
    xp += ni;
18780
    tp += ni;
18781
    *xpp = (void*)xp;
18782
  }
18783
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18784
18785
#else   /* not SX */
18786
18787
  char *xp = (char *) *xpp;
18788
  int status = NC_NOERR;
18789
18790
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18791
  {
18792
    int lstatus = ncx_put_longlong_longlong(xp, tp, fillp);
18793
    if (status == NC_NOERR) /* report the first encountered error */
18794
      status = lstatus;
18795
  }
18796
18797
  *xpp = (void *)xp;
18798
  return status;
18799
#endif
18800
}
18801
18802
#endif
18803
int
18804
ncx_putn_longlong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
18805
0
{
18806
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18807
18808
 /* basic algorithm is:
18809
  *   - ensure sane alignment of output data
18810
  *   - copy (conversion happens automatically) input data
18811
  *     to output
18812
  *   - update tp to point at next unconverted input, and xpp to point
18813
  *     at next location for converted output
18814
  */
18815
  long i, j, ni;
18816
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18817
  int64 *xp;
18818
  int nrange = 0;         /* number of range errors */
18819
  int realign = 0;        /* "do we need to fix input data alignment?" */
18820
  long cxp = (long) *((char**)xpp);
18821
18822
  realign = (cxp & 7) % SIZEOF_INT64;
18823
  /* sjl: manually stripmine so we can limit amount of
18824
   * vector work space reserved to LOOPCNT elements. Also
18825
   * makes vectorisation easy */
18826
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18827
    ni=Min(nelems-j,LOOPCNT);
18828
    if (realign) {
18829
      xp = tmp;
18830
    } else {
18831
      xp = (int64 *) *xpp;
18832
    }
18833
   /* copy the next block */
18834
#pragma cdir loopcnt=LOOPCNT
18835
#pragma cdir shortloop
18836
    for (i=0; i<ni; i++) {
18837
      /* the normal case: */
18838
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18839
     /* test for range errors (not always needed but do it anyway) */
18840
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18841
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18842
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18843
    }
18844
   /* copy workspace back if necessary */
18845
    if (realign) {
18846
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18847
      xp = (int64 *) *xpp;
18848
    }
18849
   /* update xpp and tp */
18850
    xp += ni;
18851
    tp += ni;
18852
    *xpp = (void*)xp;
18853
  }
18854
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18855
18856
#else   /* not SX */
18857
18858
0
  char *xp = (char *) *xpp;
18859
0
  int status = NC_NOERR;
18860
18861
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18862
0
  {
18863
0
    int lstatus = ncx_put_longlong_schar(xp, tp, fillp);
18864
0
    if (status == NC_NOERR) /* report the first encountered error */
18865
0
      status = lstatus;
18866
0
  }
18867
18868
0
  *xpp = (void *)xp;
18869
0
  return status;
18870
0
#endif
18871
0
}
18872
18873
int
18874
ncx_putn_longlong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
18875
0
{
18876
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18877
18878
 /* basic algorithm is:
18879
  *   - ensure sane alignment of output data
18880
  *   - copy (conversion happens automatically) input data
18881
  *     to output
18882
  *   - update tp to point at next unconverted input, and xpp to point
18883
  *     at next location for converted output
18884
  */
18885
  long i, j, ni;
18886
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18887
  int64 *xp;
18888
  int nrange = 0;         /* number of range errors */
18889
  int realign = 0;        /* "do we need to fix input data alignment?" */
18890
  long cxp = (long) *((char**)xpp);
18891
18892
  realign = (cxp & 7) % SIZEOF_INT64;
18893
  /* sjl: manually stripmine so we can limit amount of
18894
   * vector work space reserved to LOOPCNT elements. Also
18895
   * makes vectorisation easy */
18896
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18897
    ni=Min(nelems-j,LOOPCNT);
18898
    if (realign) {
18899
      xp = tmp;
18900
    } else {
18901
      xp = (int64 *) *xpp;
18902
    }
18903
   /* copy the next block */
18904
#pragma cdir loopcnt=LOOPCNT
18905
#pragma cdir shortloop
18906
    for (i=0; i<ni; i++) {
18907
      /* the normal case: */
18908
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18909
     /* test for range errors (not always needed but do it anyway) */
18910
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18911
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18912
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18913
    }
18914
   /* copy workspace back if necessary */
18915
    if (realign) {
18916
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18917
      xp = (int64 *) *xpp;
18918
    }
18919
   /* update xpp and tp */
18920
    xp += ni;
18921
    tp += ni;
18922
    *xpp = (void*)xp;
18923
  }
18924
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18925
18926
#else   /* not SX */
18927
18928
0
  char *xp = (char *) *xpp;
18929
0
  int status = NC_NOERR;
18930
18931
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18932
0
  {
18933
0
    int lstatus = ncx_put_longlong_short(xp, tp, fillp);
18934
0
    if (status == NC_NOERR) /* report the first encountered error */
18935
0
      status = lstatus;
18936
0
  }
18937
18938
0
  *xpp = (void *)xp;
18939
0
  return status;
18940
0
#endif
18941
0
}
18942
18943
int
18944
ncx_putn_longlong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
18945
0
{
18946
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18947
18948
 /* basic algorithm is:
18949
  *   - ensure sane alignment of output data
18950
  *   - copy (conversion happens automatically) input data
18951
  *     to output
18952
  *   - update tp to point at next unconverted input, and xpp to point
18953
  *     at next location for converted output
18954
  */
18955
  long i, j, ni;
18956
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18957
  int64 *xp;
18958
  int nrange = 0;         /* number of range errors */
18959
  int realign = 0;        /* "do we need to fix input data alignment?" */
18960
  long cxp = (long) *((char**)xpp);
18961
18962
  realign = (cxp & 7) % SIZEOF_INT64;
18963
  /* sjl: manually stripmine so we can limit amount of
18964
   * vector work space reserved to LOOPCNT elements. Also
18965
   * makes vectorisation easy */
18966
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18967
    ni=Min(nelems-j,LOOPCNT);
18968
    if (realign) {
18969
      xp = tmp;
18970
    } else {
18971
      xp = (int64 *) *xpp;
18972
    }
18973
   /* copy the next block */
18974
#pragma cdir loopcnt=LOOPCNT
18975
#pragma cdir shortloop
18976
    for (i=0; i<ni; i++) {
18977
      /* the normal case: */
18978
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18979
     /* test for range errors (not always needed but do it anyway) */
18980
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18981
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18982
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18983
    }
18984
   /* copy workspace back if necessary */
18985
    if (realign) {
18986
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18987
      xp = (int64 *) *xpp;
18988
    }
18989
   /* update xpp and tp */
18990
    xp += ni;
18991
    tp += ni;
18992
    *xpp = (void*)xp;
18993
  }
18994
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18995
18996
#else   /* not SX */
18997
18998
0
  char *xp = (char *) *xpp;
18999
0
  int status = NC_NOERR;
19000
19001
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19002
0
  {
19003
0
    int lstatus = ncx_put_longlong_int(xp, tp, fillp);
19004
0
    if (status == NC_NOERR) /* report the first encountered error */
19005
0
      status = lstatus;
19006
0
  }
19007
19008
0
  *xpp = (void *)xp;
19009
0
  return status;
19010
0
#endif
19011
0
}
19012
19013
int
19014
ncx_putn_longlong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
19015
0
{
19016
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19017
19018
 /* basic algorithm is:
19019
  *   - ensure sane alignment of output data
19020
  *   - copy (conversion happens automatically) input data
19021
  *     to output
19022
  *   - update tp to point at next unconverted input, and xpp to point
19023
  *     at next location for converted output
19024
  */
19025
  long i, j, ni;
19026
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19027
  int64 *xp;
19028
  int nrange = 0;         /* number of range errors */
19029
  int realign = 0;        /* "do we need to fix input data alignment?" */
19030
  long cxp = (long) *((char**)xpp);
19031
19032
  realign = (cxp & 7) % SIZEOF_INT64;
19033
  /* sjl: manually stripmine so we can limit amount of
19034
   * vector work space reserved to LOOPCNT elements. Also
19035
   * makes vectorisation easy */
19036
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19037
    ni=Min(nelems-j,LOOPCNT);
19038
    if (realign) {
19039
      xp = tmp;
19040
    } else {
19041
      xp = (int64 *) *xpp;
19042
    }
19043
   /* copy the next block */
19044
#pragma cdir loopcnt=LOOPCNT
19045
#pragma cdir shortloop
19046
    for (i=0; i<ni; i++) {
19047
      /* the normal case: */
19048
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19049
     /* test for range errors (not always needed but do it anyway) */
19050
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19051
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19052
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19053
    }
19054
   /* copy workspace back if necessary */
19055
    if (realign) {
19056
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19057
      xp = (int64 *) *xpp;
19058
    }
19059
   /* update xpp and tp */
19060
    xp += ni;
19061
    tp += ni;
19062
    *xpp = (void*)xp;
19063
  }
19064
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19065
19066
#else   /* not SX */
19067
19068
0
  char *xp = (char *) *xpp;
19069
0
  int status = NC_NOERR;
19070
19071
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19072
0
  {
19073
0
    int lstatus = ncx_put_longlong_long(xp, tp, fillp);
19074
0
    if (status == NC_NOERR) /* report the first encountered error */
19075
0
      status = lstatus;
19076
0
  }
19077
19078
0
  *xpp = (void *)xp;
19079
0
  return status;
19080
0
#endif
19081
0
}
19082
19083
int
19084
ncx_putn_longlong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
19085
0
{
19086
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19087
19088
 /* basic algorithm is:
19089
  *   - ensure sane alignment of output data
19090
  *   - copy (conversion happens automatically) input data
19091
  *     to output
19092
  *   - update tp to point at next unconverted input, and xpp to point
19093
  *     at next location for converted output
19094
  */
19095
  long i, j, ni;
19096
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19097
  int64 *xp;
19098
  int nrange = 0;         /* number of range errors */
19099
  int realign = 0;        /* "do we need to fix input data alignment?" */
19100
  long cxp = (long) *((char**)xpp);
19101
19102
  realign = (cxp & 7) % SIZEOF_INT64;
19103
  /* sjl: manually stripmine so we can limit amount of
19104
   * vector work space reserved to LOOPCNT elements. Also
19105
   * makes vectorisation easy */
19106
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19107
    ni=Min(nelems-j,LOOPCNT);
19108
    if (realign) {
19109
      xp = tmp;
19110
    } else {
19111
      xp = (int64 *) *xpp;
19112
    }
19113
   /* copy the next block */
19114
#pragma cdir loopcnt=LOOPCNT
19115
#pragma cdir shortloop
19116
    for (i=0; i<ni; i++) {
19117
      /* the normal case: */
19118
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19119
     /* test for range errors (not always needed but do it anyway) */
19120
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19121
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19122
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19123
    }
19124
   /* copy workspace back if necessary */
19125
    if (realign) {
19126
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19127
      xp = (int64 *) *xpp;
19128
    }
19129
   /* update xpp and tp */
19130
    xp += ni;
19131
    tp += ni;
19132
    *xpp = (void*)xp;
19133
  }
19134
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19135
19136
#else   /* not SX */
19137
19138
0
  char *xp = (char *) *xpp;
19139
0
  int status = NC_NOERR;
19140
19141
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19142
0
  {
19143
0
    int lstatus = ncx_put_longlong_float(xp, tp, fillp);
19144
0
    if (status == NC_NOERR) /* report the first encountered error */
19145
0
      status = lstatus;
19146
0
  }
19147
19148
0
  *xpp = (void *)xp;
19149
0
  return status;
19150
0
#endif
19151
0
}
19152
19153
int
19154
ncx_putn_longlong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
19155
0
{
19156
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19157
19158
 /* basic algorithm is:
19159
  *   - ensure sane alignment of output data
19160
  *   - copy (conversion happens automatically) input data
19161
  *     to output
19162
  *   - update tp to point at next unconverted input, and xpp to point
19163
  *     at next location for converted output
19164
  */
19165
  long i, j, ni;
19166
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19167
  int64 *xp;
19168
  int nrange = 0;         /* number of range errors */
19169
  int realign = 0;        /* "do we need to fix input data alignment?" */
19170
  long cxp = (long) *((char**)xpp);
19171
19172
  realign = (cxp & 7) % SIZEOF_INT64;
19173
  /* sjl: manually stripmine so we can limit amount of
19174
   * vector work space reserved to LOOPCNT elements. Also
19175
   * makes vectorisation easy */
19176
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19177
    ni=Min(nelems-j,LOOPCNT);
19178
    if (realign) {
19179
      xp = tmp;
19180
    } else {
19181
      xp = (int64 *) *xpp;
19182
    }
19183
   /* copy the next block */
19184
#pragma cdir loopcnt=LOOPCNT
19185
#pragma cdir shortloop
19186
    for (i=0; i<ni; i++) {
19187
      /* the normal case: */
19188
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19189
     /* test for range errors (not always needed but do it anyway) */
19190
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19191
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19192
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19193
    }
19194
   /* copy workspace back if necessary */
19195
    if (realign) {
19196
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19197
      xp = (int64 *) *xpp;
19198
    }
19199
   /* update xpp and tp */
19200
    xp += ni;
19201
    tp += ni;
19202
    *xpp = (void*)xp;
19203
  }
19204
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19205
19206
#else   /* not SX */
19207
19208
0
  char *xp = (char *) *xpp;
19209
0
  int status = NC_NOERR;
19210
19211
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19212
0
  {
19213
0
    int lstatus = ncx_put_longlong_double(xp, tp, fillp);
19214
0
    if (status == NC_NOERR) /* report the first encountered error */
19215
0
      status = lstatus;
19216
0
  }
19217
19218
0
  *xpp = (void *)xp;
19219
0
  return status;
19220
0
#endif
19221
0
}
19222
19223
int
19224
ncx_putn_longlong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
19225
0
{
19226
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19227
19228
 /* basic algorithm is:
19229
  *   - ensure sane alignment of output data
19230
  *   - copy (conversion happens automatically) input data
19231
  *     to output
19232
  *   - update tp to point at next unconverted input, and xpp to point
19233
  *     at next location for converted output
19234
  */
19235
  long i, j, ni;
19236
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19237
  int64 *xp;
19238
  int nrange = 0;         /* number of range errors */
19239
  int realign = 0;        /* "do we need to fix input data alignment?" */
19240
  long cxp = (long) *((char**)xpp);
19241
19242
  realign = (cxp & 7) % SIZEOF_INT64;
19243
  /* sjl: manually stripmine so we can limit amount of
19244
   * vector work space reserved to LOOPCNT elements. Also
19245
   * makes vectorisation easy */
19246
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19247
    ni=Min(nelems-j,LOOPCNT);
19248
    if (realign) {
19249
      xp = tmp;
19250
    } else {
19251
      xp = (int64 *) *xpp;
19252
    }
19253
   /* copy the next block */
19254
#pragma cdir loopcnt=LOOPCNT
19255
#pragma cdir shortloop
19256
    for (i=0; i<ni; i++) {
19257
      /* the normal case: */
19258
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19259
     /* test for range errors (not always needed but do it anyway) */
19260
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19261
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19262
      nrange += tp[i] > X_INT64_MAX ;
19263
    }
19264
   /* copy workspace back if necessary */
19265
    if (realign) {
19266
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19267
      xp = (int64 *) *xpp;
19268
    }
19269
   /* update xpp and tp */
19270
    xp += ni;
19271
    tp += ni;
19272
    *xpp = (void*)xp;
19273
  }
19274
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19275
19276
#else   /* not SX */
19277
19278
0
  char *xp = (char *) *xpp;
19279
0
  int status = NC_NOERR;
19280
19281
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19282
0
  {
19283
0
    int lstatus = ncx_put_longlong_uchar(xp, tp, fillp);
19284
0
    if (status == NC_NOERR) /* report the first encountered error */
19285
0
      status = lstatus;
19286
0
  }
19287
19288
0
  *xpp = (void *)xp;
19289
0
  return status;
19290
0
#endif
19291
0
}
19292
19293
int
19294
ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
19295
0
{
19296
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19297
19298
 /* basic algorithm is:
19299
  *   - ensure sane alignment of output data
19300
  *   - copy (conversion happens automatically) input data
19301
  *     to output
19302
  *   - update tp to point at next unconverted input, and xpp to point
19303
  *     at next location for converted output
19304
  */
19305
  long i, j, ni;
19306
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19307
  int64 *xp;
19308
  int nrange = 0;         /* number of range errors */
19309
  int realign = 0;        /* "do we need to fix input data alignment?" */
19310
  long cxp = (long) *((char**)xpp);
19311
19312
  realign = (cxp & 7) % SIZEOF_INT64;
19313
  /* sjl: manually stripmine so we can limit amount of
19314
   * vector work space reserved to LOOPCNT elements. Also
19315
   * makes vectorisation easy */
19316
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19317
    ni=Min(nelems-j,LOOPCNT);
19318
    if (realign) {
19319
      xp = tmp;
19320
    } else {
19321
      xp = (int64 *) *xpp;
19322
    }
19323
   /* copy the next block */
19324
#pragma cdir loopcnt=LOOPCNT
19325
#pragma cdir shortloop
19326
    for (i=0; i<ni; i++) {
19327
      /* the normal case: */
19328
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19329
     /* test for range errors (not always needed but do it anyway) */
19330
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19331
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19332
      nrange += tp[i] > X_INT64_MAX ;
19333
    }
19334
   /* copy workspace back if necessary */
19335
    if (realign) {
19336
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19337
      xp = (int64 *) *xpp;
19338
    }
19339
   /* update xpp and tp */
19340
    xp += ni;
19341
    tp += ni;
19342
    *xpp = (void*)xp;
19343
  }
19344
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19345
19346
#else   /* not SX */
19347
19348
0
  char *xp = (char *) *xpp;
19349
0
  int status = NC_NOERR;
19350
19351
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19352
0
  {
19353
0
    int lstatus = ncx_put_longlong_ushort(xp, tp, fillp);
19354
0
    if (status == NC_NOERR) /* report the first encountered error */
19355
0
      status = lstatus;
19356
0
  }
19357
19358
0
  *xpp = (void *)xp;
19359
0
  return status;
19360
0
#endif
19361
0
}
19362
19363
int
19364
ncx_putn_longlong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
19365
0
{
19366
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19367
19368
 /* basic algorithm is:
19369
  *   - ensure sane alignment of output data
19370
  *   - copy (conversion happens automatically) input data
19371
  *     to output
19372
  *   - update tp to point at next unconverted input, and xpp to point
19373
  *     at next location for converted output
19374
  */
19375
  long i, j, ni;
19376
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19377
  int64 *xp;
19378
  int nrange = 0;         /* number of range errors */
19379
  int realign = 0;        /* "do we need to fix input data alignment?" */
19380
  long cxp = (long) *((char**)xpp);
19381
19382
  realign = (cxp & 7) % SIZEOF_INT64;
19383
  /* sjl: manually stripmine so we can limit amount of
19384
   * vector work space reserved to LOOPCNT elements. Also
19385
   * makes vectorisation easy */
19386
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19387
    ni=Min(nelems-j,LOOPCNT);
19388
    if (realign) {
19389
      xp = tmp;
19390
    } else {
19391
      xp = (int64 *) *xpp;
19392
    }
19393
   /* copy the next block */
19394
#pragma cdir loopcnt=LOOPCNT
19395
#pragma cdir shortloop
19396
    for (i=0; i<ni; i++) {
19397
      /* the normal case: */
19398
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19399
     /* test for range errors (not always needed but do it anyway) */
19400
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19401
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19402
      nrange += tp[i] > X_INT64_MAX ;
19403
    }
19404
   /* copy workspace back if necessary */
19405
    if (realign) {
19406
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19407
      xp = (int64 *) *xpp;
19408
    }
19409
   /* update xpp and tp */
19410
    xp += ni;
19411
    tp += ni;
19412
    *xpp = (void*)xp;
19413
  }
19414
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19415
19416
#else   /* not SX */
19417
19418
0
  char *xp = (char *) *xpp;
19419
0
  int status = NC_NOERR;
19420
19421
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19422
0
  {
19423
0
    int lstatus = ncx_put_longlong_uint(xp, tp, fillp);
19424
0
    if (status == NC_NOERR) /* report the first encountered error */
19425
0
      status = lstatus;
19426
0
  }
19427
19428
0
  *xpp = (void *)xp;
19429
0
  return status;
19430
0
#endif
19431
0
}
19432
19433
int
19434
ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
19435
0
{
19436
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19437
19438
 /* basic algorithm is:
19439
  *   - ensure sane alignment of output data
19440
  *   - copy (conversion happens automatically) input data
19441
  *     to output
19442
  *   - update tp to point at next unconverted input, and xpp to point
19443
  *     at next location for converted output
19444
  */
19445
  long i, j, ni;
19446
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19447
  int64 *xp;
19448
  int nrange = 0;         /* number of range errors */
19449
  int realign = 0;        /* "do we need to fix input data alignment?" */
19450
  long cxp = (long) *((char**)xpp);
19451
19452
  realign = (cxp & 7) % SIZEOF_INT64;
19453
  /* sjl: manually stripmine so we can limit amount of
19454
   * vector work space reserved to LOOPCNT elements. Also
19455
   * makes vectorisation easy */
19456
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19457
    ni=Min(nelems-j,LOOPCNT);
19458
    if (realign) {
19459
      xp = tmp;
19460
    } else {
19461
      xp = (int64 *) *xpp;
19462
    }
19463
   /* copy the next block */
19464
#pragma cdir loopcnt=LOOPCNT
19465
#pragma cdir shortloop
19466
    for (i=0; i<ni; i++) {
19467
      /* the normal case: */
19468
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19469
     /* test for range errors (not always needed but do it anyway) */
19470
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19471
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19472
      nrange += tp[i] > X_INT64_MAX ;
19473
    }
19474
   /* copy workspace back if necessary */
19475
    if (realign) {
19476
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19477
      xp = (int64 *) *xpp;
19478
    }
19479
   /* update xpp and tp */
19480
    xp += ni;
19481
    tp += ni;
19482
    *xpp = (void*)xp;
19483
  }
19484
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19485
19486
#else   /* not SX */
19487
19488
0
  char *xp = (char *) *xpp;
19489
0
  int status = NC_NOERR;
19490
19491
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19492
0
  {
19493
0
    int lstatus = ncx_put_longlong_ulonglong(xp, tp, fillp);
19494
0
    if (status == NC_NOERR) /* report the first encountered error */
19495
0
      status = lstatus;
19496
0
  }
19497
19498
0
  *xpp = (void *)xp;
19499
0
  return status;
19500
0
#endif
19501
0
}
19502
19503
19504
/* uint64 --------------------------------------------------------------------*/
19505
19506
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
19507
/* optimized version */
19508
int
19509
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp)
19510
0
{
19511
#ifdef WORDS_BIGENDIAN
19512
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
19513
# else
19514
0
  swapn8b(tp, *xpp, nelems);
19515
0
# endif
19516
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
19517
0
  return NC_NOERR;
19518
0
}
19519
#else
19520
int
19521
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
19522
{
19523
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19524
19525
 /* basic algorithm is:
19526
  *   - ensure sane alignment of input data
19527
  *   - copy (conversion happens automatically) input data
19528
  *     to output
19529
  *   - update xpp to point at next unconverted input, and tp to point
19530
  *     at next location for converted output
19531
  */
19532
  long i, j, ni;
19533
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19534
  uint64 *xp;
19535
  int nrange = 0;         /* number of range errors */
19536
  int realign = 0;        /* "do we need to fix input data alignment?" */
19537
  long cxp = (long) *((char**)xpp);
19538
19539
  realign = (cxp & 7) % SIZEOF_UINT64;
19540
  /* sjl: manually stripmine so we can limit amount of
19541
   * vector work space reserved to LOOPCNT elements. Also
19542
   * makes vectorisation easy */
19543
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19544
    ni=Min(nelems-j,LOOPCNT);
19545
    if (realign) {
19546
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19547
      xp = tmp;
19548
    } else {
19549
      xp = (uint64 *) *xpp;
19550
    }
19551
   /* copy the next block */
19552
#pragma cdir loopcnt=LOOPCNT
19553
#pragma cdir shortloop
19554
    for (i=0; i<ni; i++) {
19555
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
19556
     /* test for range errors (not always needed but do it anyway) */
19557
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19558
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19559
      nrange += xp[i] > ULONGLONG_MAX ;
19560
    }
19561
   /* update xpp and tp */
19562
    if (realign) xp = (uint64 *) *xpp;
19563
    xp += ni;
19564
    tp += ni;
19565
    *xpp = (void*)xp;
19566
  }
19567
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19568
19569
#else   /* not SX */
19570
  const char *xp = (const char *) *xpp;
19571
  int status = NC_NOERR;
19572
19573
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19574
  {
19575
    const int lstatus = ncx_get_ulonglong_ulonglong(xp, tp);
19576
    if (status == NC_NOERR) /* report the first encountered error */
19577
      status = lstatus;
19578
  }
19579
19580
  *xpp = (const void *)xp;
19581
  return status;
19582
#endif
19583
}
19584
19585
#endif
19586
int
19587
ncx_getn_ulonglong_schar(const void **xpp, size_t nelems, schar *tp)
19588
0
{
19589
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19590
19591
 /* basic algorithm is:
19592
  *   - ensure sane alignment of input data
19593
  *   - copy (conversion happens automatically) input data
19594
  *     to output
19595
  *   - update xpp to point at next unconverted input, and tp to point
19596
  *     at next location for converted output
19597
  */
19598
  long i, j, ni;
19599
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19600
  uint64 *xp;
19601
  int nrange = 0;         /* number of range errors */
19602
  int realign = 0;        /* "do we need to fix input data alignment?" */
19603
  long cxp = (long) *((char**)xpp);
19604
19605
  realign = (cxp & 7) % SIZEOF_UINT64;
19606
  /* sjl: manually stripmine so we can limit amount of
19607
   * vector work space reserved to LOOPCNT elements. Also
19608
   * makes vectorisation easy */
19609
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19610
    ni=Min(nelems-j,LOOPCNT);
19611
    if (realign) {
19612
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19613
      xp = tmp;
19614
    } else {
19615
      xp = (uint64 *) *xpp;
19616
    }
19617
   /* copy the next block */
19618
#pragma cdir loopcnt=LOOPCNT
19619
#pragma cdir shortloop
19620
    for (i=0; i<ni; i++) {
19621
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
19622
     /* test for range errors (not always needed but do it anyway) */
19623
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19624
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19625
      nrange += xp[i] > SCHAR_MAX ;
19626
    }
19627
   /* update xpp and tp */
19628
    if (realign) xp = (uint64 *) *xpp;
19629
    xp += ni;
19630
    tp += ni;
19631
    *xpp = (void*)xp;
19632
  }
19633
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19634
19635
#else   /* not SX */
19636
0
  const char *xp = (const char *) *xpp;
19637
0
  int status = NC_NOERR;
19638
19639
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19640
0
  {
19641
0
    const int lstatus = ncx_get_ulonglong_schar(xp, tp);
19642
0
    if (status == NC_NOERR) /* report the first encountered error */
19643
0
      status = lstatus;
19644
0
  }
19645
19646
0
  *xpp = (const void *)xp;
19647
0
  return status;
19648
0
#endif
19649
0
}
19650
19651
int
19652
ncx_getn_ulonglong_short(const void **xpp, size_t nelems, short *tp)
19653
0
{
19654
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19655
19656
 /* basic algorithm is:
19657
  *   - ensure sane alignment of input data
19658
  *   - copy (conversion happens automatically) input data
19659
  *     to output
19660
  *   - update xpp to point at next unconverted input, and tp to point
19661
  *     at next location for converted output
19662
  */
19663
  long i, j, ni;
19664
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19665
  uint64 *xp;
19666
  int nrange = 0;         /* number of range errors */
19667
  int realign = 0;        /* "do we need to fix input data alignment?" */
19668
  long cxp = (long) *((char**)xpp);
19669
19670
  realign = (cxp & 7) % SIZEOF_UINT64;
19671
  /* sjl: manually stripmine so we can limit amount of
19672
   * vector work space reserved to LOOPCNT elements. Also
19673
   * makes vectorisation easy */
19674
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19675
    ni=Min(nelems-j,LOOPCNT);
19676
    if (realign) {
19677
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19678
      xp = tmp;
19679
    } else {
19680
      xp = (uint64 *) *xpp;
19681
    }
19682
   /* copy the next block */
19683
#pragma cdir loopcnt=LOOPCNT
19684
#pragma cdir shortloop
19685
    for (i=0; i<ni; i++) {
19686
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
19687
     /* test for range errors (not always needed but do it anyway) */
19688
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19689
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19690
      nrange += xp[i] > SHORT_MAX ;
19691
    }
19692
   /* update xpp and tp */
19693
    if (realign) xp = (uint64 *) *xpp;
19694
    xp += ni;
19695
    tp += ni;
19696
    *xpp = (void*)xp;
19697
  }
19698
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19699
19700
#else   /* not SX */
19701
0
  const char *xp = (const char *) *xpp;
19702
0
  int status = NC_NOERR;
19703
19704
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19705
0
  {
19706
0
    const int lstatus = ncx_get_ulonglong_short(xp, tp);
19707
0
    if (status == NC_NOERR) /* report the first encountered error */
19708
0
      status = lstatus;
19709
0
  }
19710
19711
0
  *xpp = (const void *)xp;
19712
0
  return status;
19713
0
#endif
19714
0
}
19715
19716
int
19717
ncx_getn_ulonglong_int(const void **xpp, size_t nelems, int *tp)
19718
0
{
19719
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19720
19721
 /* basic algorithm is:
19722
  *   - ensure sane alignment of input data
19723
  *   - copy (conversion happens automatically) input data
19724
  *     to output
19725
  *   - update xpp to point at next unconverted input, and tp to point
19726
  *     at next location for converted output
19727
  */
19728
  long i, j, ni;
19729
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19730
  uint64 *xp;
19731
  int nrange = 0;         /* number of range errors */
19732
  int realign = 0;        /* "do we need to fix input data alignment?" */
19733
  long cxp = (long) *((char**)xpp);
19734
19735
  realign = (cxp & 7) % SIZEOF_UINT64;
19736
  /* sjl: manually stripmine so we can limit amount of
19737
   * vector work space reserved to LOOPCNT elements. Also
19738
   * makes vectorisation easy */
19739
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19740
    ni=Min(nelems-j,LOOPCNT);
19741
    if (realign) {
19742
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19743
      xp = tmp;
19744
    } else {
19745
      xp = (uint64 *) *xpp;
19746
    }
19747
   /* copy the next block */
19748
#pragma cdir loopcnt=LOOPCNT
19749
#pragma cdir shortloop
19750
    for (i=0; i<ni; i++) {
19751
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
19752
     /* test for range errors (not always needed but do it anyway) */
19753
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19754
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19755
      nrange += xp[i] > INT_MAX ;
19756
    }
19757
   /* update xpp and tp */
19758
    if (realign) xp = (uint64 *) *xpp;
19759
    xp += ni;
19760
    tp += ni;
19761
    *xpp = (void*)xp;
19762
  }
19763
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19764
19765
#else   /* not SX */
19766
0
  const char *xp = (const char *) *xpp;
19767
0
  int status = NC_NOERR;
19768
19769
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19770
0
  {
19771
0
    const int lstatus = ncx_get_ulonglong_int(xp, tp);
19772
0
    if (status == NC_NOERR) /* report the first encountered error */
19773
0
      status = lstatus;
19774
0
  }
19775
19776
0
  *xpp = (const void *)xp;
19777
0
  return status;
19778
0
#endif
19779
0
}
19780
19781
int
19782
ncx_getn_ulonglong_long(const void **xpp, size_t nelems, long *tp)
19783
0
{
19784
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19785
19786
 /* basic algorithm is:
19787
  *   - ensure sane alignment of input data
19788
  *   - copy (conversion happens automatically) input data
19789
  *     to output
19790
  *   - update xpp to point at next unconverted input, and tp to point
19791
  *     at next location for converted output
19792
  */
19793
  long i, j, ni;
19794
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19795
  uint64 *xp;
19796
  int nrange = 0;         /* number of range errors */
19797
  int realign = 0;        /* "do we need to fix input data alignment?" */
19798
  long cxp = (long) *((char**)xpp);
19799
19800
  realign = (cxp & 7) % SIZEOF_UINT64;
19801
  /* sjl: manually stripmine so we can limit amount of
19802
   * vector work space reserved to LOOPCNT elements. Also
19803
   * makes vectorisation easy */
19804
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19805
    ni=Min(nelems-j,LOOPCNT);
19806
    if (realign) {
19807
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19808
      xp = tmp;
19809
    } else {
19810
      xp = (uint64 *) *xpp;
19811
    }
19812
   /* copy the next block */
19813
#pragma cdir loopcnt=LOOPCNT
19814
#pragma cdir shortloop
19815
    for (i=0; i<ni; i++) {
19816
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
19817
     /* test for range errors (not always needed but do it anyway) */
19818
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19819
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19820
      nrange += xp[i] > LONG_MAX ;
19821
    }
19822
   /* update xpp and tp */
19823
    if (realign) xp = (uint64 *) *xpp;
19824
    xp += ni;
19825
    tp += ni;
19826
    *xpp = (void*)xp;
19827
  }
19828
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19829
19830
#else   /* not SX */
19831
0
  const char *xp = (const char *) *xpp;
19832
0
  int status = NC_NOERR;
19833
19834
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19835
0
  {
19836
0
    const int lstatus = ncx_get_ulonglong_long(xp, tp);
19837
0
    if (status == NC_NOERR) /* report the first encountered error */
19838
0
      status = lstatus;
19839
0
  }
19840
19841
0
  *xpp = (const void *)xp;
19842
0
  return status;
19843
0
#endif
19844
0
}
19845
19846
int
19847
ncx_getn_ulonglong_float(const void **xpp, size_t nelems, float *tp)
19848
0
{
19849
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19850
19851
 /* basic algorithm is:
19852
  *   - ensure sane alignment of input data
19853
  *   - copy (conversion happens automatically) input data
19854
  *     to output
19855
  *   - update xpp to point at next unconverted input, and tp to point
19856
  *     at next location for converted output
19857
  */
19858
  long i, j, ni;
19859
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19860
  uint64 *xp;
19861
  int nrange = 0;         /* number of range errors */
19862
  int realign = 0;        /* "do we need to fix input data alignment?" */
19863
  long cxp = (long) *((char**)xpp);
19864
19865
  realign = (cxp & 7) % SIZEOF_UINT64;
19866
  /* sjl: manually stripmine so we can limit amount of
19867
   * vector work space reserved to LOOPCNT elements. Also
19868
   * makes vectorisation easy */
19869
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19870
    ni=Min(nelems-j,LOOPCNT);
19871
    if (realign) {
19872
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19873
      xp = tmp;
19874
    } else {
19875
      xp = (uint64 *) *xpp;
19876
    }
19877
   /* copy the next block */
19878
#pragma cdir loopcnt=LOOPCNT
19879
#pragma cdir shortloop
19880
    for (i=0; i<ni; i++) {
19881
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
19882
     /* test for range errors (not always needed but do it anyway) */
19883
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19884
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19885
      nrange += xp[i] > FLOAT_MAX ;
19886
    }
19887
   /* update xpp and tp */
19888
    if (realign) xp = (uint64 *) *xpp;
19889
    xp += ni;
19890
    tp += ni;
19891
    *xpp = (void*)xp;
19892
  }
19893
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19894
19895
#else   /* not SX */
19896
0
  const char *xp = (const char *) *xpp;
19897
0
  int status = NC_NOERR;
19898
19899
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19900
0
  {
19901
0
    const int lstatus = ncx_get_ulonglong_float(xp, tp);
19902
0
    if (status == NC_NOERR) /* report the first encountered error */
19903
0
      status = lstatus;
19904
0
  }
19905
19906
0
  *xpp = (const void *)xp;
19907
0
  return status;
19908
0
#endif
19909
0
}
19910
19911
int
19912
ncx_getn_ulonglong_double(const void **xpp, size_t nelems, double *tp)
19913
0
{
19914
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19915
19916
 /* basic algorithm is:
19917
  *   - ensure sane alignment of input data
19918
  *   - copy (conversion happens automatically) input data
19919
  *     to output
19920
  *   - update xpp to point at next unconverted input, and tp to point
19921
  *     at next location for converted output
19922
  */
19923
  long i, j, ni;
19924
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19925
  uint64 *xp;
19926
  int nrange = 0;         /* number of range errors */
19927
  int realign = 0;        /* "do we need to fix input data alignment?" */
19928
  long cxp = (long) *((char**)xpp);
19929
19930
  realign = (cxp & 7) % SIZEOF_UINT64;
19931
  /* sjl: manually stripmine so we can limit amount of
19932
   * vector work space reserved to LOOPCNT elements. Also
19933
   * makes vectorisation easy */
19934
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19935
    ni=Min(nelems-j,LOOPCNT);
19936
    if (realign) {
19937
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19938
      xp = tmp;
19939
    } else {
19940
      xp = (uint64 *) *xpp;
19941
    }
19942
   /* copy the next block */
19943
#pragma cdir loopcnt=LOOPCNT
19944
#pragma cdir shortloop
19945
    for (i=0; i<ni; i++) {
19946
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
19947
     /* test for range errors (not always needed but do it anyway) */
19948
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19949
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19950
      nrange += xp[i] > DOUBLE_MAX ;
19951
    }
19952
   /* update xpp and tp */
19953
    if (realign) xp = (uint64 *) *xpp;
19954
    xp += ni;
19955
    tp += ni;
19956
    *xpp = (void*)xp;
19957
  }
19958
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19959
19960
#else   /* not SX */
19961
0
  const char *xp = (const char *) *xpp;
19962
0
  int status = NC_NOERR;
19963
19964
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19965
0
  {
19966
0
    const int lstatus = ncx_get_ulonglong_double(xp, tp);
19967
0
    if (status == NC_NOERR) /* report the first encountered error */
19968
0
      status = lstatus;
19969
0
  }
19970
19971
0
  *xpp = (const void *)xp;
19972
0
  return status;
19973
0
#endif
19974
0
}
19975
19976
int
19977
ncx_getn_ulonglong_longlong(const void **xpp, size_t nelems, longlong *tp)
19978
0
{
19979
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19980
19981
 /* basic algorithm is:
19982
  *   - ensure sane alignment of input data
19983
  *   - copy (conversion happens automatically) input data
19984
  *     to output
19985
  *   - update xpp to point at next unconverted input, and tp to point
19986
  *     at next location for converted output
19987
  */
19988
  long i, j, ni;
19989
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19990
  uint64 *xp;
19991
  int nrange = 0;         /* number of range errors */
19992
  int realign = 0;        /* "do we need to fix input data alignment?" */
19993
  long cxp = (long) *((char**)xpp);
19994
19995
  realign = (cxp & 7) % SIZEOF_UINT64;
19996
  /* sjl: manually stripmine so we can limit amount of
19997
   * vector work space reserved to LOOPCNT elements. Also
19998
   * makes vectorisation easy */
19999
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20000
    ni=Min(nelems-j,LOOPCNT);
20001
    if (realign) {
20002
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20003
      xp = tmp;
20004
    } else {
20005
      xp = (uint64 *) *xpp;
20006
    }
20007
   /* copy the next block */
20008
#pragma cdir loopcnt=LOOPCNT
20009
#pragma cdir shortloop
20010
    for (i=0; i<ni; i++) {
20011
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
20012
     /* test for range errors (not always needed but do it anyway) */
20013
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20014
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20015
      nrange += xp[i] > LONGLONG_MAX ;
20016
    }
20017
   /* update xpp and tp */
20018
    if (realign) xp = (uint64 *) *xpp;
20019
    xp += ni;
20020
    tp += ni;
20021
    *xpp = (void*)xp;
20022
  }
20023
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20024
20025
#else   /* not SX */
20026
0
  const char *xp = (const char *) *xpp;
20027
0
  int status = NC_NOERR;
20028
20029
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20030
0
  {
20031
0
    const int lstatus = ncx_get_ulonglong_longlong(xp, tp);
20032
0
    if (status == NC_NOERR) /* report the first encountered error */
20033
0
      status = lstatus;
20034
0
  }
20035
20036
0
  *xpp = (const void *)xp;
20037
0
  return status;
20038
0
#endif
20039
0
}
20040
20041
int
20042
ncx_getn_ulonglong_uchar(const void **xpp, size_t nelems, uchar *tp)
20043
0
{
20044
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20045
20046
 /* basic algorithm is:
20047
  *   - ensure sane alignment of input data
20048
  *   - copy (conversion happens automatically) input data
20049
  *     to output
20050
  *   - update xpp to point at next unconverted input, and tp to point
20051
  *     at next location for converted output
20052
  */
20053
  long i, j, ni;
20054
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20055
  uint64 *xp;
20056
  int nrange = 0;         /* number of range errors */
20057
  int realign = 0;        /* "do we need to fix input data alignment?" */
20058
  long cxp = (long) *((char**)xpp);
20059
20060
  realign = (cxp & 7) % SIZEOF_UINT64;
20061
  /* sjl: manually stripmine so we can limit amount of
20062
   * vector work space reserved to LOOPCNT elements. Also
20063
   * makes vectorisation easy */
20064
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20065
    ni=Min(nelems-j,LOOPCNT);
20066
    if (realign) {
20067
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20068
      xp = tmp;
20069
    } else {
20070
      xp = (uint64 *) *xpp;
20071
    }
20072
   /* copy the next block */
20073
#pragma cdir loopcnt=LOOPCNT
20074
#pragma cdir shortloop
20075
    for (i=0; i<ni; i++) {
20076
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
20077
     /* test for range errors (not always needed but do it anyway) */
20078
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20079
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20080
      nrange += xp[i] > UCHAR_MAX ;
20081
    }
20082
   /* update xpp and tp */
20083
    if (realign) xp = (uint64 *) *xpp;
20084
    xp += ni;
20085
    tp += ni;
20086
    *xpp = (void*)xp;
20087
  }
20088
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20089
20090
#else   /* not SX */
20091
0
  const char *xp = (const char *) *xpp;
20092
0
  int status = NC_NOERR;
20093
20094
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20095
0
  {
20096
0
    const int lstatus = ncx_get_ulonglong_uchar(xp, tp);
20097
0
    if (status == NC_NOERR) /* report the first encountered error */
20098
0
      status = lstatus;
20099
0
  }
20100
20101
0
  *xpp = (const void *)xp;
20102
0
  return status;
20103
0
#endif
20104
0
}
20105
20106
int
20107
ncx_getn_ulonglong_ushort(const void **xpp, size_t nelems, ushort *tp)
20108
0
{
20109
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20110
20111
 /* basic algorithm is:
20112
  *   - ensure sane alignment of input data
20113
  *   - copy (conversion happens automatically) input data
20114
  *     to output
20115
  *   - update xpp to point at next unconverted input, and tp to point
20116
  *     at next location for converted output
20117
  */
20118
  long i, j, ni;
20119
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20120
  uint64 *xp;
20121
  int nrange = 0;         /* number of range errors */
20122
  int realign = 0;        /* "do we need to fix input data alignment?" */
20123
  long cxp = (long) *((char**)xpp);
20124
20125
  realign = (cxp & 7) % SIZEOF_UINT64;
20126
  /* sjl: manually stripmine so we can limit amount of
20127
   * vector work space reserved to LOOPCNT elements. Also
20128
   * makes vectorisation easy */
20129
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20130
    ni=Min(nelems-j,LOOPCNT);
20131
    if (realign) {
20132
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20133
      xp = tmp;
20134
    } else {
20135
      xp = (uint64 *) *xpp;
20136
    }
20137
   /* copy the next block */
20138
#pragma cdir loopcnt=LOOPCNT
20139
#pragma cdir shortloop
20140
    for (i=0; i<ni; i++) {
20141
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
20142
     /* test for range errors (not always needed but do it anyway) */
20143
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20144
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20145
      nrange += xp[i] > USHORT_MAX ;
20146
    }
20147
   /* update xpp and tp */
20148
    if (realign) xp = (uint64 *) *xpp;
20149
    xp += ni;
20150
    tp += ni;
20151
    *xpp = (void*)xp;
20152
  }
20153
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20154
20155
#else   /* not SX */
20156
0
  const char *xp = (const char *) *xpp;
20157
0
  int status = NC_NOERR;
20158
20159
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20160
0
  {
20161
0
    const int lstatus = ncx_get_ulonglong_ushort(xp, tp);
20162
0
    if (status == NC_NOERR) /* report the first encountered error */
20163
0
      status = lstatus;
20164
0
  }
20165
20166
0
  *xpp = (const void *)xp;
20167
0
  return status;
20168
0
#endif
20169
0
}
20170
20171
int
20172
ncx_getn_ulonglong_uint(const void **xpp, size_t nelems, uint *tp)
20173
0
{
20174
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20175
20176
 /* basic algorithm is:
20177
  *   - ensure sane alignment of input data
20178
  *   - copy (conversion happens automatically) input data
20179
  *     to output
20180
  *   - update xpp to point at next unconverted input, and tp to point
20181
  *     at next location for converted output
20182
  */
20183
  long i, j, ni;
20184
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20185
  uint64 *xp;
20186
  int nrange = 0;         /* number of range errors */
20187
  int realign = 0;        /* "do we need to fix input data alignment?" */
20188
  long cxp = (long) *((char**)xpp);
20189
20190
  realign = (cxp & 7) % SIZEOF_UINT64;
20191
  /* sjl: manually stripmine so we can limit amount of
20192
   * vector work space reserved to LOOPCNT elements. Also
20193
   * makes vectorisation easy */
20194
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20195
    ni=Min(nelems-j,LOOPCNT);
20196
    if (realign) {
20197
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20198
      xp = tmp;
20199
    } else {
20200
      xp = (uint64 *) *xpp;
20201
    }
20202
   /* copy the next block */
20203
#pragma cdir loopcnt=LOOPCNT
20204
#pragma cdir shortloop
20205
    for (i=0; i<ni; i++) {
20206
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
20207
     /* test for range errors (not always needed but do it anyway) */
20208
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20209
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20210
      nrange += xp[i] > UINT_MAX ;
20211
    }
20212
   /* update xpp and tp */
20213
    if (realign) xp = (uint64 *) *xpp;
20214
    xp += ni;
20215
    tp += ni;
20216
    *xpp = (void*)xp;
20217
  }
20218
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20219
20220
#else   /* not SX */
20221
0
  const char *xp = (const char *) *xpp;
20222
0
  int status = NC_NOERR;
20223
20224
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20225
0
  {
20226
0
    const int lstatus = ncx_get_ulonglong_uint(xp, tp);
20227
0
    if (status == NC_NOERR) /* report the first encountered error */
20228
0
      status = lstatus;
20229
0
  }
20230
20231
0
  *xpp = (const void *)xp;
20232
0
  return status;
20233
0
#endif
20234
0
}
20235
20236
20237
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
20238
/* optimized version */
20239
int
20240
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp, void *fillp)
20241
0
{
20242
#ifdef WORDS_BIGENDIAN
20243
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
20244
# else
20245
0
  swapn8b(*xpp, tp, nelems);
20246
0
# endif
20247
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
20248
0
  return NC_NOERR;
20249
0
}
20250
#else
20251
int
20252
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
20253
{
20254
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20255
20256
 /* basic algorithm is:
20257
  *   - ensure sane alignment of output data
20258
  *   - copy (conversion happens automatically) input data
20259
  *     to output
20260
  *   - update tp to point at next unconverted input, and xpp to point
20261
  *     at next location for converted output
20262
  */
20263
  long i, j, ni;
20264
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20265
  uint64 *xp;
20266
  int nrange = 0;         /* number of range errors */
20267
  int realign = 0;        /* "do we need to fix input data alignment?" */
20268
  long cxp = (long) *((char**)xpp);
20269
20270
  realign = (cxp & 7) % SIZEOF_UINT64;
20271
  /* sjl: manually stripmine so we can limit amount of
20272
   * vector work space reserved to LOOPCNT elements. Also
20273
   * makes vectorisation easy */
20274
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20275
    ni=Min(nelems-j,LOOPCNT);
20276
    if (realign) {
20277
      xp = tmp;
20278
    } else {
20279
      xp = (uint64 *) *xpp;
20280
    }
20281
   /* copy the next block */
20282
#pragma cdir loopcnt=LOOPCNT
20283
#pragma cdir shortloop
20284
    for (i=0; i<ni; i++) {
20285
      /* the normal case: */
20286
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20287
     /* test for range errors (not always needed but do it anyway) */
20288
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20289
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20290
      nrange += tp[i] > X_UINT64_MAX ;
20291
    }
20292
   /* copy workspace back if necessary */
20293
    if (realign) {
20294
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20295
      xp = (uint64 *) *xpp;
20296
    }
20297
   /* update xpp and tp */
20298
    xp += ni;
20299
    tp += ni;
20300
    *xpp = (void*)xp;
20301
  }
20302
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20303
20304
#else   /* not SX */
20305
20306
  char *xp = (char *) *xpp;
20307
  int status = NC_NOERR;
20308
20309
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20310
  {
20311
    int lstatus = ncx_put_ulonglong_ulonglong(xp, tp, fillp);
20312
    if (status == NC_NOERR) /* report the first encountered error */
20313
      status = lstatus;
20314
  }
20315
20316
  *xpp = (void *)xp;
20317
  return status;
20318
#endif
20319
}
20320
20321
#endif
20322
int
20323
ncx_putn_ulonglong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
20324
0
{
20325
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20326
20327
 /* basic algorithm is:
20328
  *   - ensure sane alignment of output data
20329
  *   - copy (conversion happens automatically) input data
20330
  *     to output
20331
  *   - update tp to point at next unconverted input, and xpp to point
20332
  *     at next location for converted output
20333
  */
20334
  long i, j, ni;
20335
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20336
  uint64 *xp;
20337
  int nrange = 0;         /* number of range errors */
20338
  int realign = 0;        /* "do we need to fix input data alignment?" */
20339
  long cxp = (long) *((char**)xpp);
20340
20341
  realign = (cxp & 7) % SIZEOF_UINT64;
20342
  /* sjl: manually stripmine so we can limit amount of
20343
   * vector work space reserved to LOOPCNT elements. Also
20344
   * makes vectorisation easy */
20345
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20346
    ni=Min(nelems-j,LOOPCNT);
20347
    if (realign) {
20348
      xp = tmp;
20349
    } else {
20350
      xp = (uint64 *) *xpp;
20351
    }
20352
   /* copy the next block */
20353
#pragma cdir loopcnt=LOOPCNT
20354
#pragma cdir shortloop
20355
    for (i=0; i<ni; i++) {
20356
      /* the normal case: */
20357
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20358
     /* test for range errors (not always needed but do it anyway) */
20359
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20360
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20361
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20362
    }
20363
   /* copy workspace back if necessary */
20364
    if (realign) {
20365
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20366
      xp = (uint64 *) *xpp;
20367
    }
20368
   /* update xpp and tp */
20369
    xp += ni;
20370
    tp += ni;
20371
    *xpp = (void*)xp;
20372
  }
20373
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20374
20375
#else   /* not SX */
20376
20377
0
  char *xp = (char *) *xpp;
20378
0
  int status = NC_NOERR;
20379
20380
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20381
0
  {
20382
0
    int lstatus = ncx_put_ulonglong_schar(xp, tp, fillp);
20383
0
    if (status == NC_NOERR) /* report the first encountered error */
20384
0
      status = lstatus;
20385
0
  }
20386
20387
0
  *xpp = (void *)xp;
20388
0
  return status;
20389
0
#endif
20390
0
}
20391
20392
int
20393
ncx_putn_ulonglong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
20394
0
{
20395
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20396
20397
 /* basic algorithm is:
20398
  *   - ensure sane alignment of output data
20399
  *   - copy (conversion happens automatically) input data
20400
  *     to output
20401
  *   - update tp to point at next unconverted input, and xpp to point
20402
  *     at next location for converted output
20403
  */
20404
  long i, j, ni;
20405
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20406
  uint64 *xp;
20407
  int nrange = 0;         /* number of range errors */
20408
  int realign = 0;        /* "do we need to fix input data alignment?" */
20409
  long cxp = (long) *((char**)xpp);
20410
20411
  realign = (cxp & 7) % SIZEOF_UINT64;
20412
  /* sjl: manually stripmine so we can limit amount of
20413
   * vector work space reserved to LOOPCNT elements. Also
20414
   * makes vectorisation easy */
20415
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20416
    ni=Min(nelems-j,LOOPCNT);
20417
    if (realign) {
20418
      xp = tmp;
20419
    } else {
20420
      xp = (uint64 *) *xpp;
20421
    }
20422
   /* copy the next block */
20423
#pragma cdir loopcnt=LOOPCNT
20424
#pragma cdir shortloop
20425
    for (i=0; i<ni; i++) {
20426
      /* the normal case: */
20427
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20428
     /* test for range errors (not always needed but do it anyway) */
20429
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20430
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20431
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20432
    }
20433
   /* copy workspace back if necessary */
20434
    if (realign) {
20435
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20436
      xp = (uint64 *) *xpp;
20437
    }
20438
   /* update xpp and tp */
20439
    xp += ni;
20440
    tp += ni;
20441
    *xpp = (void*)xp;
20442
  }
20443
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20444
20445
#else   /* not SX */
20446
20447
0
  char *xp = (char *) *xpp;
20448
0
  int status = NC_NOERR;
20449
20450
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20451
0
  {
20452
0
    int lstatus = ncx_put_ulonglong_short(xp, tp, fillp);
20453
0
    if (status == NC_NOERR) /* report the first encountered error */
20454
0
      status = lstatus;
20455
0
  }
20456
20457
0
  *xpp = (void *)xp;
20458
0
  return status;
20459
0
#endif
20460
0
}
20461
20462
int
20463
ncx_putn_ulonglong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
20464
0
{
20465
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20466
20467
 /* basic algorithm is:
20468
  *   - ensure sane alignment of output data
20469
  *   - copy (conversion happens automatically) input data
20470
  *     to output
20471
  *   - update tp to point at next unconverted input, and xpp to point
20472
  *     at next location for converted output
20473
  */
20474
  long i, j, ni;
20475
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20476
  uint64 *xp;
20477
  int nrange = 0;         /* number of range errors */
20478
  int realign = 0;        /* "do we need to fix input data alignment?" */
20479
  long cxp = (long) *((char**)xpp);
20480
20481
  realign = (cxp & 7) % SIZEOF_UINT64;
20482
  /* sjl: manually stripmine so we can limit amount of
20483
   * vector work space reserved to LOOPCNT elements. Also
20484
   * makes vectorisation easy */
20485
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20486
    ni=Min(nelems-j,LOOPCNT);
20487
    if (realign) {
20488
      xp = tmp;
20489
    } else {
20490
      xp = (uint64 *) *xpp;
20491
    }
20492
   /* copy the next block */
20493
#pragma cdir loopcnt=LOOPCNT
20494
#pragma cdir shortloop
20495
    for (i=0; i<ni; i++) {
20496
      /* the normal case: */
20497
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20498
     /* test for range errors (not always needed but do it anyway) */
20499
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20500
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20501
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20502
    }
20503
   /* copy workspace back if necessary */
20504
    if (realign) {
20505
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20506
      xp = (uint64 *) *xpp;
20507
    }
20508
   /* update xpp and tp */
20509
    xp += ni;
20510
    tp += ni;
20511
    *xpp = (void*)xp;
20512
  }
20513
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20514
20515
#else   /* not SX */
20516
20517
0
  char *xp = (char *) *xpp;
20518
0
  int status = NC_NOERR;
20519
20520
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20521
0
  {
20522
0
    int lstatus = ncx_put_ulonglong_int(xp, tp, fillp);
20523
0
    if (status == NC_NOERR) /* report the first encountered error */
20524
0
      status = lstatus;
20525
0
  }
20526
20527
0
  *xpp = (void *)xp;
20528
0
  return status;
20529
0
#endif
20530
0
}
20531
20532
int
20533
ncx_putn_ulonglong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
20534
0
{
20535
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20536
20537
 /* basic algorithm is:
20538
  *   - ensure sane alignment of output data
20539
  *   - copy (conversion happens automatically) input data
20540
  *     to output
20541
  *   - update tp to point at next unconverted input, and xpp to point
20542
  *     at next location for converted output
20543
  */
20544
  long i, j, ni;
20545
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20546
  uint64 *xp;
20547
  int nrange = 0;         /* number of range errors */
20548
  int realign = 0;        /* "do we need to fix input data alignment?" */
20549
  long cxp = (long) *((char**)xpp);
20550
20551
  realign = (cxp & 7) % SIZEOF_UINT64;
20552
  /* sjl: manually stripmine so we can limit amount of
20553
   * vector work space reserved to LOOPCNT elements. Also
20554
   * makes vectorisation easy */
20555
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20556
    ni=Min(nelems-j,LOOPCNT);
20557
    if (realign) {
20558
      xp = tmp;
20559
    } else {
20560
      xp = (uint64 *) *xpp;
20561
    }
20562
   /* copy the next block */
20563
#pragma cdir loopcnt=LOOPCNT
20564
#pragma cdir shortloop
20565
    for (i=0; i<ni; i++) {
20566
      /* the normal case: */
20567
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20568
     /* test for range errors (not always needed but do it anyway) */
20569
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20570
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20571
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20572
    }
20573
   /* copy workspace back if necessary */
20574
    if (realign) {
20575
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20576
      xp = (uint64 *) *xpp;
20577
    }
20578
   /* update xpp and tp */
20579
    xp += ni;
20580
    tp += ni;
20581
    *xpp = (void*)xp;
20582
  }
20583
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20584
20585
#else   /* not SX */
20586
20587
0
  char *xp = (char *) *xpp;
20588
0
  int status = NC_NOERR;
20589
20590
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20591
0
  {
20592
0
    int lstatus = ncx_put_ulonglong_long(xp, tp, fillp);
20593
0
    if (status == NC_NOERR) /* report the first encountered error */
20594
0
      status = lstatus;
20595
0
  }
20596
20597
0
  *xpp = (void *)xp;
20598
0
  return status;
20599
0
#endif
20600
0
}
20601
20602
int
20603
ncx_putn_ulonglong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
20604
0
{
20605
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20606
20607
 /* basic algorithm is:
20608
  *   - ensure sane alignment of output data
20609
  *   - copy (conversion happens automatically) input data
20610
  *     to output
20611
  *   - update tp to point at next unconverted input, and xpp to point
20612
  *     at next location for converted output
20613
  */
20614
  long i, j, ni;
20615
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20616
  uint64 *xp;
20617
  int nrange = 0;         /* number of range errors */
20618
  int realign = 0;        /* "do we need to fix input data alignment?" */
20619
  long cxp = (long) *((char**)xpp);
20620
20621
  realign = (cxp & 7) % SIZEOF_UINT64;
20622
  /* sjl: manually stripmine so we can limit amount of
20623
   * vector work space reserved to LOOPCNT elements. Also
20624
   * makes vectorisation easy */
20625
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20626
    ni=Min(nelems-j,LOOPCNT);
20627
    if (realign) {
20628
      xp = tmp;
20629
    } else {
20630
      xp = (uint64 *) *xpp;
20631
    }
20632
   /* copy the next block */
20633
#pragma cdir loopcnt=LOOPCNT
20634
#pragma cdir shortloop
20635
    for (i=0; i<ni; i++) {
20636
      /* the normal case: */
20637
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20638
     /* test for range errors (not always needed but do it anyway) */
20639
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20640
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20641
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20642
    }
20643
   /* copy workspace back if necessary */
20644
    if (realign) {
20645
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20646
      xp = (uint64 *) *xpp;
20647
    }
20648
   /* update xpp and tp */
20649
    xp += ni;
20650
    tp += ni;
20651
    *xpp = (void*)xp;
20652
  }
20653
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20654
20655
#else   /* not SX */
20656
20657
0
  char *xp = (char *) *xpp;
20658
0
  int status = NC_NOERR;
20659
20660
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20661
0
  {
20662
0
    int lstatus = ncx_put_ulonglong_float(xp, tp, fillp);
20663
0
    if (status == NC_NOERR) /* report the first encountered error */
20664
0
      status = lstatus;
20665
0
  }
20666
20667
0
  *xpp = (void *)xp;
20668
0
  return status;
20669
0
#endif
20670
0
}
20671
20672
int
20673
ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
20674
0
{
20675
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20676
20677
 /* basic algorithm is:
20678
  *   - ensure sane alignment of output data
20679
  *   - copy (conversion happens automatically) input data
20680
  *     to output
20681
  *   - update tp to point at next unconverted input, and xpp to point
20682
  *     at next location for converted output
20683
  */
20684
  long i, j, ni;
20685
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20686
  uint64 *xp;
20687
  int nrange = 0;         /* number of range errors */
20688
  int realign = 0;        /* "do we need to fix input data alignment?" */
20689
  long cxp = (long) *((char**)xpp);
20690
20691
  realign = (cxp & 7) % SIZEOF_UINT64;
20692
  /* sjl: manually stripmine so we can limit amount of
20693
   * vector work space reserved to LOOPCNT elements. Also
20694
   * makes vectorisation easy */
20695
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20696
    ni=Min(nelems-j,LOOPCNT);
20697
    if (realign) {
20698
      xp = tmp;
20699
    } else {
20700
      xp = (uint64 *) *xpp;
20701
    }
20702
   /* copy the next block */
20703
#pragma cdir loopcnt=LOOPCNT
20704
#pragma cdir shortloop
20705
    for (i=0; i<ni; i++) {
20706
      /* the normal case: */
20707
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20708
     /* test for range errors (not always needed but do it anyway) */
20709
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20710
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20711
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20712
    }
20713
   /* copy workspace back if necessary */
20714
    if (realign) {
20715
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20716
      xp = (uint64 *) *xpp;
20717
    }
20718
   /* update xpp and tp */
20719
    xp += ni;
20720
    tp += ni;
20721
    *xpp = (void*)xp;
20722
  }
20723
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20724
20725
#else   /* not SX */
20726
20727
0
  char *xp = (char *) *xpp;
20728
0
  int status = NC_NOERR;
20729
20730
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20731
0
  {
20732
0
    int lstatus = ncx_put_ulonglong_double(xp, tp, fillp);
20733
0
    if (status == NC_NOERR) /* report the first encountered error */
20734
0
      status = lstatus;
20735
0
  }
20736
20737
0
  *xpp = (void *)xp;
20738
0
  return status;
20739
0
#endif
20740
0
}
20741
20742
int
20743
ncx_putn_ulonglong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
20744
0
{
20745
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20746
20747
 /* basic algorithm is:
20748
  *   - ensure sane alignment of output data
20749
  *   - copy (conversion happens automatically) input data
20750
  *     to output
20751
  *   - update tp to point at next unconverted input, and xpp to point
20752
  *     at next location for converted output
20753
  */
20754
  long i, j, ni;
20755
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20756
  uint64 *xp;
20757
  int nrange = 0;         /* number of range errors */
20758
  int realign = 0;        /* "do we need to fix input data alignment?" */
20759
  long cxp = (long) *((char**)xpp);
20760
20761
  realign = (cxp & 7) % SIZEOF_UINT64;
20762
  /* sjl: manually stripmine so we can limit amount of
20763
   * vector work space reserved to LOOPCNT elements. Also
20764
   * makes vectorisation easy */
20765
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20766
    ni=Min(nelems-j,LOOPCNT);
20767
    if (realign) {
20768
      xp = tmp;
20769
    } else {
20770
      xp = (uint64 *) *xpp;
20771
    }
20772
   /* copy the next block */
20773
#pragma cdir loopcnt=LOOPCNT
20774
#pragma cdir shortloop
20775
    for (i=0; i<ni; i++) {
20776
      /* the normal case: */
20777
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20778
     /* test for range errors (not always needed but do it anyway) */
20779
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20780
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20781
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20782
    }
20783
   /* copy workspace back if necessary */
20784
    if (realign) {
20785
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20786
      xp = (uint64 *) *xpp;
20787
    }
20788
   /* update xpp and tp */
20789
    xp += ni;
20790
    tp += ni;
20791
    *xpp = (void*)xp;
20792
  }
20793
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20794
20795
#else   /* not SX */
20796
20797
0
  char *xp = (char *) *xpp;
20798
0
  int status = NC_NOERR;
20799
20800
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20801
0
  {
20802
0
    int lstatus = ncx_put_ulonglong_longlong(xp, tp, fillp);
20803
0
    if (status == NC_NOERR) /* report the first encountered error */
20804
0
      status = lstatus;
20805
0
  }
20806
20807
0
  *xpp = (void *)xp;
20808
0
  return status;
20809
0
#endif
20810
0
}
20811
20812
int
20813
ncx_putn_ulonglong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
20814
0
{
20815
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20816
20817
 /* basic algorithm is:
20818
  *   - ensure sane alignment of output data
20819
  *   - copy (conversion happens automatically) input data
20820
  *     to output
20821
  *   - update tp to point at next unconverted input, and xpp to point
20822
  *     at next location for converted output
20823
  */
20824
  long i, j, ni;
20825
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20826
  uint64 *xp;
20827
  int nrange = 0;         /* number of range errors */
20828
  int realign = 0;        /* "do we need to fix input data alignment?" */
20829
  long cxp = (long) *((char**)xpp);
20830
20831
  realign = (cxp & 7) % SIZEOF_UINT64;
20832
  /* sjl: manually stripmine so we can limit amount of
20833
   * vector work space reserved to LOOPCNT elements. Also
20834
   * makes vectorisation easy */
20835
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20836
    ni=Min(nelems-j,LOOPCNT);
20837
    if (realign) {
20838
      xp = tmp;
20839
    } else {
20840
      xp = (uint64 *) *xpp;
20841
    }
20842
   /* copy the next block */
20843
#pragma cdir loopcnt=LOOPCNT
20844
#pragma cdir shortloop
20845
    for (i=0; i<ni; i++) {
20846
      /* the normal case: */
20847
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20848
     /* test for range errors (not always needed but do it anyway) */
20849
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20850
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20851
      nrange += tp[i] > X_UINT64_MAX ;
20852
    }
20853
   /* copy workspace back if necessary */
20854
    if (realign) {
20855
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20856
      xp = (uint64 *) *xpp;
20857
    }
20858
   /* update xpp and tp */
20859
    xp += ni;
20860
    tp += ni;
20861
    *xpp = (void*)xp;
20862
  }
20863
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20864
20865
#else   /* not SX */
20866
20867
0
  char *xp = (char *) *xpp;
20868
0
  int status = NC_NOERR;
20869
20870
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20871
0
  {
20872
0
    int lstatus = ncx_put_ulonglong_uchar(xp, tp, fillp);
20873
0
    if (status == NC_NOERR) /* report the first encountered error */
20874
0
      status = lstatus;
20875
0
  }
20876
20877
0
  *xpp = (void *)xp;
20878
0
  return status;
20879
0
#endif
20880
0
}
20881
20882
int
20883
ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
20884
0
{
20885
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20886
20887
 /* basic algorithm is:
20888
  *   - ensure sane alignment of output data
20889
  *   - copy (conversion happens automatically) input data
20890
  *     to output
20891
  *   - update tp to point at next unconverted input, and xpp to point
20892
  *     at next location for converted output
20893
  */
20894
  long i, j, ni;
20895
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20896
  uint64 *xp;
20897
  int nrange = 0;         /* number of range errors */
20898
  int realign = 0;        /* "do we need to fix input data alignment?" */
20899
  long cxp = (long) *((char**)xpp);
20900
20901
  realign = (cxp & 7) % SIZEOF_UINT64;
20902
  /* sjl: manually stripmine so we can limit amount of
20903
   * vector work space reserved to LOOPCNT elements. Also
20904
   * makes vectorisation easy */
20905
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20906
    ni=Min(nelems-j,LOOPCNT);
20907
    if (realign) {
20908
      xp = tmp;
20909
    } else {
20910
      xp = (uint64 *) *xpp;
20911
    }
20912
   /* copy the next block */
20913
#pragma cdir loopcnt=LOOPCNT
20914
#pragma cdir shortloop
20915
    for (i=0; i<ni; i++) {
20916
      /* the normal case: */
20917
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20918
     /* test for range errors (not always needed but do it anyway) */
20919
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20920
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20921
      nrange += tp[i] > X_UINT64_MAX ;
20922
    }
20923
   /* copy workspace back if necessary */
20924
    if (realign) {
20925
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20926
      xp = (uint64 *) *xpp;
20927
    }
20928
   /* update xpp and tp */
20929
    xp += ni;
20930
    tp += ni;
20931
    *xpp = (void*)xp;
20932
  }
20933
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20934
20935
#else   /* not SX */
20936
20937
0
  char *xp = (char *) *xpp;
20938
0
  int status = NC_NOERR;
20939
20940
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20941
0
  {
20942
0
    int lstatus = ncx_put_ulonglong_ushort(xp, tp, fillp);
20943
0
    if (status == NC_NOERR) /* report the first encountered error */
20944
0
      status = lstatus;
20945
0
  }
20946
20947
0
  *xpp = (void *)xp;
20948
0
  return status;
20949
0
#endif
20950
0
}
20951
20952
int
20953
ncx_putn_ulonglong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
20954
0
{
20955
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20956
20957
 /* basic algorithm is:
20958
  *   - ensure sane alignment of output data
20959
  *   - copy (conversion happens automatically) input data
20960
  *     to output
20961
  *   - update tp to point at next unconverted input, and xpp to point
20962
  *     at next location for converted output
20963
  */
20964
  long i, j, ni;
20965
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20966
  uint64 *xp;
20967
  int nrange = 0;         /* number of range errors */
20968
  int realign = 0;        /* "do we need to fix input data alignment?" */
20969
  long cxp = (long) *((char**)xpp);
20970
20971
  realign = (cxp & 7) % SIZEOF_UINT64;
20972
  /* sjl: manually stripmine so we can limit amount of
20973
   * vector work space reserved to LOOPCNT elements. Also
20974
   * makes vectorisation easy */
20975
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20976
    ni=Min(nelems-j,LOOPCNT);
20977
    if (realign) {
20978
      xp = tmp;
20979
    } else {
20980
      xp = (uint64 *) *xpp;
20981
    }
20982
   /* copy the next block */
20983
#pragma cdir loopcnt=LOOPCNT
20984
#pragma cdir shortloop
20985
    for (i=0; i<ni; i++) {
20986
      /* the normal case: */
20987
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20988
     /* test for range errors (not always needed but do it anyway) */
20989
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20990
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20991
      nrange += tp[i] > X_UINT64_MAX ;
20992
    }
20993
   /* copy workspace back if necessary */
20994
    if (realign) {
20995
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20996
      xp = (uint64 *) *xpp;
20997
    }
20998
   /* update xpp and tp */
20999
    xp += ni;
21000
    tp += ni;
21001
    *xpp = (void*)xp;
21002
  }
21003
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
21004
21005
#else   /* not SX */
21006
21007
0
  char *xp = (char *) *xpp;
21008
0
  int status = NC_NOERR;
21009
21010
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
21011
0
  {
21012
0
    int lstatus = ncx_put_ulonglong_uint(xp, tp, fillp);
21013
0
    if (status == NC_NOERR) /* report the first encountered error */
21014
0
      status = lstatus;
21015
0
  }
21016
21017
0
  *xpp = (void *)xp;
21018
0
  return status;
21019
0
#endif
21020
0
}
21021
21022
21023
21024
/*
21025
 * Other aggregate conversion functions.
21026
 */
21027
21028
/* text */
21029
21030
int
21031
ncx_getn_text(const void **xpp, size_t nelems, char *tp)
21032
0
{
21033
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
21034
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21035
0
  return NC_NOERR;
21036
21037
0
}
21038
21039
int
21040
ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
21041
190k
{
21042
190k
  size_t rndup = nelems % X_ALIGN;
21043
21044
190k
  if (rndup)
21045
156k
    rndup = X_ALIGN - rndup;
21046
21047
190k
  (void) memcpy(tp, *xpp, (size_t)nelems);
21048
190k
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
21049
21050
190k
  return NC_NOERR;
21051
21052
190k
}
21053
21054
int
21055
ncx_putn_text(void **xpp, size_t nelems, const char *tp)
21056
165k
{
21057
165k
  (void) memcpy(*xpp, tp, (size_t)nelems);
21058
165k
  *xpp = (void *)((char *)(*xpp) + nelems);
21059
21060
165k
  return NC_NOERR;
21061
21062
165k
}
21063
21064
int
21065
ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
21066
186k
{
21067
186k
  size_t rndup = nelems % X_ALIGN;
21068
21069
186k
  if (rndup)
21070
152k
    rndup = X_ALIGN - rndup;
21071
21072
186k
  (void) memcpy(*xpp, tp, (size_t)nelems);
21073
186k
  *xpp = (void *)((char *)(*xpp) + nelems);
21074
21075
186k
  if (rndup)
21076
152k
  {
21077
152k
    (void) memcpy(*xpp, nada, (size_t)rndup);
21078
152k
    *xpp = (void *)((char *)(*xpp) + rndup);
21079
152k
  }
21080
21081
186k
  return NC_NOERR;
21082
21083
186k
}
21084
21085
21086
/* opaque */
21087
21088
int
21089
ncx_getn_void(const void **xpp, size_t nelems, void *tp)
21090
0
{
21091
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
21092
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21093
0
  return NC_NOERR;
21094
21095
0
}
21096
21097
int
21098
ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
21099
0
{
21100
0
  size_t rndup = nelems % X_ALIGN;
21101
21102
0
  if (rndup)
21103
0
    rndup = X_ALIGN - rndup;
21104
21105
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
21106
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
21107
21108
0
  return NC_NOERR;
21109
21110
0
}
21111
21112
int
21113
ncx_putn_void(void **xpp, size_t nelems, const void *tp)
21114
0
{
21115
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
21116
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21117
21118
0
  return NC_NOERR;
21119
21120
0
}
21121
21122
int
21123
ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
21124
0
{
21125
0
  size_t rndup = nelems % X_ALIGN;
21126
21127
0
  if (rndup)
21128
0
    rndup = X_ALIGN - rndup;
21129
21130
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
21131
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21132
21133
0
  if (rndup)
21134
0
  {
21135
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
21136
0
    *xpp = (void *)((char *)(*xpp) + rndup);
21137
0
  }
21138
21139
0
  return NC_NOERR;
21140
21141
0
}