Coverage Report

Created: 2026-02-26 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/netcdf-c/build/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
#include <config.h>
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
0
#define SWAP2(a) ( (((a) & 0xff) << 8) | \
204
0
                   (((a) >> 8) & 0xff) )
205
206
39.2k
#define SWAP4(a) ( ((a) << 24) | \
207
39.2k
                  (((a) <<  8) & 0x00ff0000) | \
208
39.2k
                  (((a) >>  8) & 0x0000ff00) | \
209
39.2k
                  (((a) >> 24) & 0x000000ff) )
210
211
0
#define SWAP8(a) ( (((a) & 0x00000000000000FFULL) << 56) | \
212
0
                   (((a) & 0x000000000000FF00ULL) << 40) | \
213
0
                   (((a) & 0x0000000000FF0000ULL) << 24) | \
214
0
                   (((a) & 0x00000000FF000000ULL) <<  8) | \
215
0
                   (((a) & 0x000000FF00000000ULL) >>  8) | \
216
0
                   (((a) & 0x0000FF0000000000ULL) >> 24) | \
217
0
                   (((a) & 0x00FF000000000000ULL) >> 40) | \
218
0
                   (((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
0
{
227
    /* it is OK if dst == src */
228
0
    size_t i;
229
0
    char *op = (char*) dst;
230
0
    char *ip = (char*) src;
231
0
    uint16_t tmp;
232
0
    for (i=0; i<nn; i++) {
233
        /* memcpy is used to handle the case of unaligned memory */
234
0
        memcpy(&tmp, ip, sizeof(tmp));
235
0
        tmp = SWAP2(tmp);
236
0
        memcpy(op, &tmp, sizeof(tmp));
237
0
        ip += sizeof(uint16_t);
238
0
        op += sizeof(uint16_t);
239
0
    }
240
0
}
241
242
# ifndef vax
243
inline static void
244
swap4b(void *dst, const void *src)
245
0
{
246
0
    uint32_t tmp;
247
    /* memcpy is used to handle the case of unaligned memory */
248
0
    memcpy(&tmp, src, sizeof(tmp));
249
0
    tmp = SWAP4(tmp);
250
0
    memcpy(dst, &tmp, 4);
251
0
}
252
# endif /* !vax */
253
254
inline static void
255
swapn4b(void *dst, const void *src, size_t nn)
256
131k
{
257
131k
    size_t i;
258
131k
    char *op = (char*) dst;
259
131k
    char *ip = (char*) src;
260
131k
    uint32_t tmp;
261
170k
    for (i=0; i<nn; i++) {
262
        /* memcpy is used to handle the case of unaligned memory */
263
39.2k
        memcpy(&tmp, ip, sizeof(tmp));
264
39.2k
        tmp = SWAP4(tmp);
265
39.2k
        memcpy(op, &tmp, sizeof(tmp));
266
39.2k
        ip += sizeof(uint32_t);
267
39.2k
        op += sizeof(uint32_t);
268
39.2k
    }
269
131k
}
270
271
# ifndef vax
272
inline static void
273
swap8b(void *dst, const void *src)
274
0
{
275
0
    uint64_t tmp;
276
    /* memcpy is used to handle the case of unaligned memory */
277
0
    memcpy(&tmp, src, sizeof(tmp));
278
0
    tmp = SWAP8(tmp);
279
0
    memcpy(dst, &tmp, 8);
280
0
}
281
# endif /* !vax */
282
283
# ifndef vax
284
inline static void
285
swapn8b(void *dst, const void *src, size_t nn)
286
0
{
287
0
    size_t i;
288
0
    char *op = (char*) dst;
289
0
    char *ip = (char*) src;
290
0
    uint64_t tmp;
291
0
    for (i=0; i<nn; i++) {
292
        /* memcpy is used to handle the case of unaligned memory */
293
0
        memcpy(&tmp, ip, sizeof(tmp));
294
0
        tmp = SWAP8(tmp);
295
0
        memcpy(op, &tmp, sizeof(tmp));
296
0
        ip += sizeof(uint64_t);
297
0
        op += sizeof(uint64_t);
298
0
    }
299
0
}
300
# endif /* !vax */
301
302
#endif /* LITTLE_ENDIAN */
303
304
305
306
307
308
309
/*
310
 * Primitive numeric conversion functions.
311
 */
312
313
314
315
316
317
/* x_schar */
318
/* x_uchar */
319
320
/* We don't implement any x_schar and x_uchar primitives. */
321
322
323
/* external NC_SHORT --------------------------------------------------------*/
324
325
#if SHORT_MAX == X_SHORT_MAX
326
typedef short ix_short;
327
#define SIZEOF_IX_SHORT SIZEOF_SHORT
328
0
#define IX_SHORT_MAX SHORT_MAX
329
#elif INT_MAX >= X_SHORT_MAX
330
typedef int ix_short;
331
#define SIZEOF_IX_SHORT SIZEOF_INT
332
#define IX_SHORT_MAX INT_MAX
333
#elif LONG_MAX >= X_SHORT_MAX
334
typedef long ix_short;
335
#define SIZEOF_IX_SHORT SIZEOF_LONG
336
#define IX_SHORT_MAX LONG_MAX
337
#elif LLONG_MAX >= X_SHORT_MAX
338
typedef long long ix_short;
339
#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
340
#define IX_SHORT_MAX LLONG_MAX
341
#else
342
#error "ix_short implementation"
343
#endif
344
345
static void
346
get_ix_short(const void *xp, ix_short *ip)
347
0
{
348
0
  const uchar *cp = (const uchar *) xp;
349
0
  *ip = (ix_short)(*cp++ << 8);
350
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
351
  if (*ip & 0x8000)
352
  {
353
    /* extern is negative */
354
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
355
  }
356
#endif
357
0
  *ip = (ix_short)(*ip | *cp);
358
0
}
359
360
static void
361
put_ix_short(void *xp, const ix_short *ip)
362
0
{
363
0
  uchar *cp = (uchar *) xp;
364
0
  *cp++ = (uchar)((*ip) >> 8);
365
0
  *cp   = (uchar)((*ip) & 0xff);
366
0
}
367
368
static int
369
ncx_get_short_schar(const void *xp, schar *ip)
370
0
{
371
0
    int err=NC_NOERR;
372
0
    ix_short xx = 0;
373
0
    get_ix_short(xp, &xx);
374
375
0
#if IX_SHORT_MAX > SCHAR_MAX
376
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
377
0
#ifdef ERANGE_FILL
378
0
        *ip = NC_FILL_BYTE;
379
0
        return NC_ERANGE;
380
#else
381
        err = NC_ERANGE;
382
#endif
383
0
    }
384
0
#endif
385
386
387
0
    *ip = (schar) xx;
388
0
    return err;
389
0
}
390
391
static int
392
ncx_get_short_short(const void *xp, short *ip)
393
0
{
394
0
    int err=NC_NOERR;
395
0
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
396
0
    get_ix_short(xp, (ix_short *)ip);
397
#else
398
    ix_short xx = 0;
399
    get_ix_short(xp, &xx);
400
401
#if IX_SHORT_MAX > SHORT_MAX
402
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
403
#ifdef ERANGE_FILL
404
        *ip = NC_FILL_SHORT;
405
        return NC_ERANGE;
406
#else
407
        err = NC_ERANGE;
408
#endif
409
    }
410
#endif
411
412
413
    *ip = (short) xx;
414
#endif
415
0
    return err;
416
0
}
417
418
static int
419
ncx_get_short_int(const void *xp, int *ip)
420
0
{
421
0
    int err=NC_NOERR;
422
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
423
    get_ix_short(xp, (ix_short *)ip);
424
#else
425
0
    ix_short xx = 0;
426
0
    get_ix_short(xp, &xx);
427
428
#if IX_SHORT_MAX > INT_MAX
429
    if (xx > INT_MAX || xx < INT_MIN) {
430
#ifdef ERANGE_FILL
431
        *ip = NC_FILL_INT;
432
        return NC_ERANGE;
433
#else
434
        err = NC_ERANGE;
435
#endif
436
    }
437
#endif
438
439
440
0
    *ip = (int) xx;
441
0
#endif
442
0
    return err;
443
0
}
444
445
static int
446
ncx_get_short_long(const void *xp, long *ip)
447
0
{
448
0
    int err=NC_NOERR;
449
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
450
    get_ix_short(xp, (ix_short *)ip);
451
#else
452
0
    ix_short xx = 0;
453
0
    get_ix_short(xp, &xx);
454
455
#if IX_SHORT_MAX > LONG_MAX
456
    if (xx > LONG_MAX || xx < LONG_MIN) {
457
#ifdef ERANGE_FILL
458
        *ip = NC_FILL_INT;
459
        return NC_ERANGE;
460
#else
461
        err = NC_ERANGE;
462
#endif
463
    }
464
#endif
465
466
467
0
    *ip = (long) xx;
468
0
#endif
469
0
    return err;
470
0
}
471
472
static int
473
ncx_get_short_longlong(const void *xp, longlong *ip)
474
0
{
475
0
    int err=NC_NOERR;
476
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
477
    get_ix_short(xp, (ix_short *)ip);
478
#else
479
0
    ix_short xx = 0;
480
0
    get_ix_short(xp, &xx);
481
482
#if IX_SHORT_MAX > LONGLONG_MAX
483
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
484
#ifdef ERANGE_FILL
485
        *ip = NC_FILL_INT64;
486
        return NC_ERANGE;
487
#else
488
        err = NC_ERANGE;
489
#endif
490
    }
491
#endif
492
493
494
0
    *ip = (longlong) xx;
495
0
#endif
496
0
    return err;
497
0
}
498
499
static int
500
ncx_get_short_ushort(const void *xp, ushort *ip)
501
0
{
502
0
    int err=NC_NOERR;
503
0
    ix_short xx = 0;
504
0
    get_ix_short(xp, &xx);
505
506
#if IX_SHORT_MAX > USHORT_MAX
507
    if (xx > USHORT_MAX) {
508
#ifdef ERANGE_FILL
509
        *ip = NC_FILL_USHORT;
510
        return NC_ERANGE;
511
#else
512
        err = NC_ERANGE;
513
#endif
514
    }
515
#endif
516
517
0
    if (xx < 0) {
518
0
#ifdef ERANGE_FILL
519
0
        *ip = NC_FILL_USHORT;
520
0
        return NC_ERANGE;
521
#else
522
        err = NC_ERANGE; /* because ip is unsigned */
523
#endif
524
0
    }
525
0
    *ip = (ushort) xx;
526
0
    return err;
527
0
}
528
529
static int
530
ncx_get_short_uchar(const void *xp, uchar *ip)
531
0
{
532
0
    int err=NC_NOERR;
533
0
    ix_short xx = 0;
534
0
    get_ix_short(xp, &xx);
535
536
0
#if IX_SHORT_MAX > UCHAR_MAX
537
0
    if (xx > UCHAR_MAX) {
538
0
#ifdef ERANGE_FILL
539
0
        *ip = NC_FILL_UBYTE;
540
0
        return NC_ERANGE;
541
#else
542
        err = NC_ERANGE;
543
#endif
544
0
    }
545
0
#endif
546
547
0
    if (xx < 0) {
548
0
#ifdef ERANGE_FILL
549
0
        *ip = NC_FILL_UBYTE;
550
0
        return NC_ERANGE;
551
#else
552
        err = NC_ERANGE; /* because ip is unsigned */
553
#endif
554
0
    }
555
0
    *ip = (uchar) xx;
556
0
    return err;
557
0
}
558
559
static int
560
ncx_get_short_uint(const void *xp, uint *ip)
561
0
{
562
0
    int err=NC_NOERR;
563
0
    ix_short xx = 0;
564
0
    get_ix_short(xp, &xx);
565
566
#if IX_SHORT_MAX > UINT_MAX
567
    if (xx > UINT_MAX) {
568
#ifdef ERANGE_FILL
569
        *ip = NC_FILL_UINT;
570
        return NC_ERANGE;
571
#else
572
        err = NC_ERANGE;
573
#endif
574
    }
575
#endif
576
577
0
    if (xx < 0) {
578
0
#ifdef ERANGE_FILL
579
0
        *ip = NC_FILL_UINT;
580
0
        return NC_ERANGE;
581
#else
582
        err = NC_ERANGE; /* because ip is unsigned */
583
#endif
584
0
    }
585
0
    *ip = (uint) xx;
586
0
    return err;
587
0
}
588
589
static int
590
ncx_get_short_ulonglong(const void *xp, ulonglong *ip)
591
0
{
592
0
    int err=NC_NOERR;
593
0
    ix_short xx = 0;
594
0
    get_ix_short(xp, &xx);
595
596
#if IX_SHORT_MAX > ULONGLONG_MAX
597
    if (xx > ULONGLONG_MAX) {
598
#ifdef ERANGE_FILL
599
        *ip = NC_FILL_UINT64;
600
        return NC_ERANGE;
601
#else
602
        err = NC_ERANGE;
603
#endif
604
    }
605
#endif
606
607
0
    if (xx < 0) {
608
0
#ifdef ERANGE_FILL
609
0
        *ip = NC_FILL_UINT64;
610
0
        return NC_ERANGE;
611
#else
612
        err = NC_ERANGE; /* because ip is unsigned */
613
#endif
614
0
    }
615
0
    *ip = (ulonglong) xx;
616
0
    return err;
617
0
}
618
619
static int
620
ncx_get_short_float(const void *xp, float *ip)
621
0
{
622
0
  ix_short xx = 0;
623
0
  get_ix_short(xp, &xx);
624
0
  *ip = (float)xx;
625
0
  return NC_NOERR;
626
0
}
627
628
static int
629
ncx_get_short_double(const void *xp, double *ip)
630
0
{
631
0
  ix_short xx = 0;
632
0
  get_ix_short(xp, &xx);
633
0
  *ip = (double)xx;
634
0
  return NC_NOERR;
635
0
}
636
637
638
static int
639
ncx_put_short_schar(void *xp, const schar *ip, void *fillp)
640
0
{
641
0
  uchar *cp = (uchar *) xp;
642
0
  if (*ip & 0x80)
643
0
    *cp++ = 0xff;
644
0
  else
645
0
    *cp++ = 0;
646
0
  *cp = (uchar)*ip;
647
0
  return NC_NOERR;
648
0
}
649
650
static int
651
ncx_put_short_uchar(void *xp, const uchar *ip, void *fillp)
652
0
{
653
0
  uchar *cp = (uchar *) xp;
654
0
  *cp++ = 0;
655
0
  *cp = *ip;
656
0
  return NC_NOERR;
657
0
}
658
659
static int
660
ncx_put_short_short(void *xp, const short *ip, void *fillp)
661
0
{
662
0
    int err=NC_NOERR;
663
0
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
664
0
    put_ix_short(xp, (const ix_short *)ip);
665
#else
666
    ix_short xx = NC_FILL_SHORT;
667
668
#if IX_SHORT_MAX < SHORT_MAX
669
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
670
        
671
#ifdef ERANGE_FILL
672
            if (fillp != NULL) memcpy(&xx, fillp, 2);
673
#endif
674
        err = NC_ERANGE;
675
    }
676
#ifdef ERANGE_FILL
677
    else
678
#endif
679
#endif
680
        xx = (ix_short)*ip;
681
682
    put_ix_short(xp, &xx);
683
#endif
684
0
    return err;
685
0
}
686
687
static int
688
ncx_put_short_int(void *xp, const int *ip, void *fillp)
689
0
{
690
0
    int err=NC_NOERR;
691
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
692
    put_ix_short(xp, (const ix_short *)ip);
693
#else
694
0
    ix_short xx = NC_FILL_SHORT;
695
696
0
#if IX_SHORT_MAX < INT_MAX
697
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
698
        
699
0
#ifdef ERANGE_FILL
700
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
701
0
#endif
702
0
        err = NC_ERANGE;
703
0
    }
704
0
#ifdef ERANGE_FILL
705
0
    else
706
0
#endif
707
0
#endif
708
0
        xx = (ix_short)*ip;
709
710
0
    put_ix_short(xp, &xx);
711
0
#endif
712
0
    return err;
713
0
}
714
715
static int
716
ncx_put_short_long(void *xp, const long *ip, void *fillp)
717
0
{
718
0
    int err=NC_NOERR;
719
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
720
    put_ix_short(xp, (const ix_short *)ip);
721
#else
722
0
    ix_short xx = NC_FILL_SHORT;
723
724
0
#if IX_SHORT_MAX < LONG_MAX
725
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
726
        
727
0
#ifdef ERANGE_FILL
728
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
729
0
#endif
730
0
        err = NC_ERANGE;
731
0
    }
732
0
#ifdef ERANGE_FILL
733
0
    else
734
0
#endif
735
0
#endif
736
0
        xx = (ix_short)*ip;
737
738
0
    put_ix_short(xp, &xx);
739
0
#endif
740
0
    return err;
741
0
}
742
743
static int
744
ncx_put_short_longlong(void *xp, const longlong *ip, void *fillp)
745
0
{
746
0
    int err=NC_NOERR;
747
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
748
    put_ix_short(xp, (const ix_short *)ip);
749
#else
750
0
    ix_short xx = NC_FILL_SHORT;
751
752
0
#if IX_SHORT_MAX < LONGLONG_MAX
753
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
754
        
755
0
#ifdef ERANGE_FILL
756
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
757
0
#endif
758
0
        err = NC_ERANGE;
759
0
    }
760
0
#ifdef ERANGE_FILL
761
0
    else
762
0
#endif
763
0
#endif
764
0
        xx = (ix_short)*ip;
765
766
0
    put_ix_short(xp, &xx);
767
0
#endif
768
0
    return err;
769
0
}
770
771
static int
772
ncx_put_short_ushort(void *xp, const ushort *ip, void *fillp)
773
0
{
774
0
    int err=NC_NOERR;
775
0
    ix_short xx = NC_FILL_SHORT;
776
777
0
#if IX_SHORT_MAX < USHORT_MAX
778
0
    if (*ip > IX_SHORT_MAX) {
779
        
780
0
#ifdef ERANGE_FILL
781
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
782
0
#endif
783
0
        err = NC_ERANGE;
784
0
    }
785
0
#ifdef ERANGE_FILL
786
0
    else
787
0
#endif
788
0
#endif
789
0
        xx = (ix_short)*ip;
790
791
0
    put_ix_short(xp, &xx);
792
0
    return err;
793
0
}
794
795
static int
796
ncx_put_short_uint(void *xp, const uint *ip, void *fillp)
797
0
{
798
0
    int err=NC_NOERR;
799
0
    ix_short xx = NC_FILL_SHORT;
800
801
0
#if IX_SHORT_MAX < UINT_MAX
802
0
    if (*ip > IX_SHORT_MAX) {
803
        
804
0
#ifdef ERANGE_FILL
805
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
806
0
#endif
807
0
        err = NC_ERANGE;
808
0
    }
809
0
#ifdef ERANGE_FILL
810
0
    else
811
0
#endif
812
0
#endif
813
0
        xx = (ix_short)*ip;
814
815
0
    put_ix_short(xp, &xx);
816
0
    return err;
817
0
}
818
819
static int
820
ncx_put_short_ulonglong(void *xp, const ulonglong *ip, void *fillp)
821
0
{
822
0
    int err=NC_NOERR;
823
0
    ix_short xx = NC_FILL_SHORT;
824
825
0
#if IX_SHORT_MAX < ULONGLONG_MAX
826
0
    if (*ip > IX_SHORT_MAX) {
827
        
828
0
#ifdef ERANGE_FILL
829
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
830
0
#endif
831
0
        err = NC_ERANGE;
832
0
    }
833
0
#ifdef ERANGE_FILL
834
0
    else
835
0
#endif
836
0
#endif
837
0
        xx = (ix_short)*ip;
838
839
0
    put_ix_short(xp, &xx);
840
0
    return err;
841
0
}
842
843
static int
844
ncx_put_short_float(void *xp, const float *ip, void *fillp)
845
0
{
846
0
    int err=NC_NOERR;
847
0
    ix_short xx = NC_FILL_SHORT;
848
849
0
    if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
850
        
851
0
#ifdef ERANGE_FILL
852
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
853
0
#endif
854
0
        err = NC_ERANGE;
855
0
    }
856
0
#ifdef ERANGE_FILL
857
0
    else
858
0
#endif
859
0
        xx = (ix_short)*ip;
860
861
0
    put_ix_short(xp, &xx);
862
0
    return err;
863
0
}
864
865
static int
866
ncx_put_short_double(void *xp, const double *ip, void *fillp)
867
0
{
868
0
    int err=NC_NOERR;
869
0
    ix_short xx = NC_FILL_SHORT;
870
871
0
    if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) {
872
        
873
0
#ifdef ERANGE_FILL
874
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
875
0
#endif
876
0
        err = NC_ERANGE;
877
0
    }
878
0
#ifdef ERANGE_FILL
879
0
    else
880
0
#endif
881
0
        xx = (ix_short)*ip;
882
883
0
    put_ix_short(xp, &xx);
884
0
    return err;
885
0
}
886
887
888
/* external NC_USHORT -------------------------------------------------------*/
889
890
#if USHORT_MAX == X_USHORT_MAX
891
typedef unsigned short ix_ushort;
892
#define SIZEOF_IX_USHORT SIZEOF_USHORT
893
0
#define IX_USHORT_MAX USHORT_MAX
894
#elif UINT_MAX >= X_USHORT_MAX
895
typedef unsigned int ix_ushort;
896
#define SIZEOF_IX_USHORT SIZEOF_UINT
897
#define IX_USHORT_MAX UINT_MAX
898
#elif ULONG_MAX >= X_USHORT_MAX
899
typedef unsigned long ix_ushort;
900
#define SIZEOF_IX_USHORT SIZEOF_ULONG
901
#define IX_USHORT_MAX ULONG_MAX
902
#elif ULLONG_MAX >= X_USHORT_MAX
903
typedef unsigned long long ix_ushort;
904
#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
905
#define IX_USHORT_MAX ULLONG_MAX
906
#else
907
#error "ix_ushort implementation"
908
#endif
909
910
static void
911
get_ix_ushort(const void *xp, ix_ushort *ip)
912
0
{
913
0
  const uchar *cp = (const uchar *) xp;
914
0
  *ip = (ix_ushort)(*cp++ << 8);
915
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
916
  if (*ip & 0x8000)
917
  {
918
    /* extern is negative */
919
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
920
  }
921
#endif
922
0
  *ip = (ix_ushort)(*ip | *cp);
923
0
}
924
925
static void
926
put_ix_ushort(void *xp, const ix_ushort *ip)
927
0
{
928
0
  uchar *cp = (uchar *) xp;
929
0
  *cp++ = (uchar)((*ip) >> 8);
930
0
  *cp   = (uchar)((*ip) & 0xff);
931
0
}
932
933
static int
934
ncx_get_ushort_schar(const void *xp, schar *ip)
935
0
{
936
0
    int err=NC_NOERR;
937
0
    ix_ushort xx = 0;
938
0
    get_ix_ushort(xp, &xx);
939
940
0
#if IX_USHORT_MAX > SCHAR_MAX
941
0
    if (xx > SCHAR_MAX) {
942
0
#ifdef ERANGE_FILL
943
0
        *ip = NC_FILL_BYTE;
944
0
        return NC_ERANGE;
945
#else
946
        err = NC_ERANGE;
947
#endif
948
0
    }
949
0
#endif
950
951
952
0
    *ip = (schar) xx;
953
0
    return err;
954
0
}
955
956
static int
957
ncx_get_ushort_short(const void *xp, short *ip)
958
0
{
959
0
    int err=NC_NOERR;
960
0
    ix_ushort xx = 0;
961
0
    get_ix_ushort(xp, &xx);
962
963
0
#if IX_USHORT_MAX > SHORT_MAX
964
0
    if (xx > SHORT_MAX) {
965
0
#ifdef ERANGE_FILL
966
0
        *ip = NC_FILL_SHORT;
967
0
        return NC_ERANGE;
968
#else
969
        err = NC_ERANGE;
970
#endif
971
0
    }
972
0
#endif
973
974
975
0
    *ip = (short) xx;
976
0
    return err;
977
0
}
978
979
static int
980
ncx_get_ushort_int(const void *xp, int *ip)
981
0
{
982
0
    int err=NC_NOERR;
983
0
    ix_ushort xx = 0;
984
0
    get_ix_ushort(xp, &xx);
985
986
#if IX_USHORT_MAX > INT_MAX
987
    if (xx > INT_MAX) {
988
#ifdef ERANGE_FILL
989
        *ip = NC_FILL_INT;
990
        return NC_ERANGE;
991
#else
992
        err = NC_ERANGE;
993
#endif
994
    }
995
#endif
996
997
998
0
    *ip = (int) xx;
999
0
    return err;
1000
0
}
1001
1002
static int
1003
ncx_get_ushort_long(const void *xp, long *ip)
1004
0
{
1005
0
    int err=NC_NOERR;
1006
0
    ix_ushort xx = 0;
1007
0
    get_ix_ushort(xp, &xx);
1008
1009
#if IX_USHORT_MAX > LONG_MAX
1010
    if (xx > LONG_MAX) {
1011
#ifdef ERANGE_FILL
1012
        *ip = NC_FILL_INT;
1013
        return NC_ERANGE;
1014
#else
1015
        err = NC_ERANGE;
1016
#endif
1017
    }
1018
#endif
1019
1020
1021
0
    *ip = (long) xx;
1022
0
    return err;
1023
0
}
1024
1025
static int
1026
ncx_get_ushort_longlong(const void *xp, longlong *ip)
1027
0
{
1028
0
    int err=NC_NOERR;
1029
0
    ix_ushort xx = 0;
1030
0
    get_ix_ushort(xp, &xx);
1031
1032
#if IX_USHORT_MAX > LONGLONG_MAX
1033
    if (xx > LONGLONG_MAX) {
1034
#ifdef ERANGE_FILL
1035
        *ip = NC_FILL_INT64;
1036
        return NC_ERANGE;
1037
#else
1038
        err = NC_ERANGE;
1039
#endif
1040
    }
1041
#endif
1042
1043
1044
0
    *ip = (longlong) xx;
1045
0
    return err;
1046
0
}
1047
1048
static int
1049
ncx_get_ushort_ushort(const void *xp, ushort *ip)
1050
0
{
1051
0
    int err=NC_NOERR;
1052
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1053
0
    get_ix_ushort(xp, (ix_ushort *)ip);
1054
#else
1055
    ix_ushort xx = 0;
1056
    get_ix_ushort(xp, &xx);
1057
1058
#if IX_USHORT_MAX > USHORT_MAX
1059
    if (xx > USHORT_MAX) {
1060
#ifdef ERANGE_FILL
1061
        *ip = NC_FILL_USHORT;
1062
        return NC_ERANGE;
1063
#else
1064
        err = NC_ERANGE;
1065
#endif
1066
    }
1067
#endif
1068
1069
1070
    *ip = (ushort) xx;
1071
#endif
1072
0
    return err;
1073
0
}
1074
1075
static int
1076
ncx_get_ushort_uchar(const void *xp, uchar *ip)
1077
0
{
1078
0
    int err=NC_NOERR;
1079
#if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
1080
    get_ix_ushort(xp, (ix_ushort *)ip);
1081
#else
1082
0
    ix_ushort xx = 0;
1083
0
    get_ix_ushort(xp, &xx);
1084
1085
0
#if IX_USHORT_MAX > UCHAR_MAX
1086
0
    if (xx > UCHAR_MAX) {
1087
0
#ifdef ERANGE_FILL
1088
0
        *ip = NC_FILL_UBYTE;
1089
0
        return NC_ERANGE;
1090
#else
1091
        err = NC_ERANGE;
1092
#endif
1093
0
    }
1094
0
#endif
1095
1096
1097
0
    *ip = (uchar) xx;
1098
0
#endif
1099
0
    return err;
1100
0
}
1101
1102
static int
1103
ncx_get_ushort_uint(const void *xp, uint *ip)
1104
0
{
1105
0
    int err=NC_NOERR;
1106
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1107
    get_ix_ushort(xp, (ix_ushort *)ip);
1108
#else
1109
0
    ix_ushort xx = 0;
1110
0
    get_ix_ushort(xp, &xx);
1111
1112
#if IX_USHORT_MAX > UINT_MAX
1113
    if (xx > UINT_MAX) {
1114
#ifdef ERANGE_FILL
1115
        *ip = NC_FILL_UINT;
1116
        return NC_ERANGE;
1117
#else
1118
        err = NC_ERANGE;
1119
#endif
1120
    }
1121
#endif
1122
1123
1124
0
    *ip = (uint) xx;
1125
0
#endif
1126
0
    return err;
1127
0
}
1128
1129
static int
1130
ncx_get_ushort_ulonglong(const void *xp, ulonglong *ip)
1131
0
{
1132
0
    int err=NC_NOERR;
1133
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1134
    get_ix_ushort(xp, (ix_ushort *)ip);
1135
#else
1136
0
    ix_ushort xx = 0;
1137
0
    get_ix_ushort(xp, &xx);
1138
1139
#if IX_USHORT_MAX > ULONGLONG_MAX
1140
    if (xx > ULONGLONG_MAX) {
1141
#ifdef ERANGE_FILL
1142
        *ip = NC_FILL_UINT64;
1143
        return NC_ERANGE;
1144
#else
1145
        err = NC_ERANGE;
1146
#endif
1147
    }
1148
#endif
1149
1150
1151
0
    *ip = (ulonglong) xx;
1152
0
#endif
1153
0
    return err;
1154
0
}
1155
1156
static int
1157
ncx_get_ushort_float(const void *xp, float *ip)
1158
0
{
1159
0
  ix_ushort xx = 0;
1160
0
  get_ix_ushort(xp, &xx);
1161
0
  *ip = (float)xx;
1162
0
  return NC_NOERR;
1163
0
}
1164
1165
static int
1166
ncx_get_ushort_double(const void *xp, double *ip)
1167
0
{
1168
0
  ix_ushort xx = 0;
1169
0
  get_ix_ushort(xp, &xx);
1170
0
  *ip = (double)xx;
1171
0
  return NC_NOERR;
1172
0
}
1173
1174
1175
static int
1176
ncx_put_ushort_schar(void *xp, const schar *ip, void *fillp)
1177
0
{
1178
0
    int err=NC_NOERR;
1179
0
    uchar *cp;
1180
0
    if (*ip < 0) {
1181
0
#ifdef ERANGE_FILL
1182
0
        if (fillp != NULL) memcpy(xp, fillp, 2);
1183
0
#ifndef WORDS_BIGENDIAN
1184
0
        swapn2b(xp, xp, 1);
1185
0
#endif
1186
0
        return NC_ERANGE;
1187
#else
1188
        err = NC_ERANGE;
1189
#endif
1190
0
    }
1191
1192
0
    cp = (uchar *) xp;
1193
0
    if (*ip & 0x80)
1194
0
        *cp++ = 0xff;
1195
0
    else
1196
0
        *cp++ = 0;
1197
0
    *cp = (uchar)*ip;
1198
1199
0
    return err;
1200
0
}
1201
1202
static int
1203
ncx_put_ushort_uchar(void *xp, const uchar *ip, void *fillp)
1204
0
{
1205
0
  uchar *cp = (uchar *) xp;
1206
0
  *cp++ = 0;
1207
0
  *cp = *ip;
1208
0
  return NC_NOERR;
1209
0
}
1210
1211
static int
1212
ncx_put_ushort_short(void *xp, const short *ip, void *fillp)
1213
0
{
1214
0
    int err=NC_NOERR;
1215
0
    ix_ushort xx = NC_FILL_USHORT;
1216
1217
#if IX_USHORT_MAX < SHORT_MAX
1218
    if (*ip > IX_USHORT_MAX) {
1219
        
1220
#ifdef ERANGE_FILL
1221
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1222
#endif
1223
        err = NC_ERANGE;
1224
    }
1225
#ifdef ERANGE_FILL
1226
    else
1227
#endif
1228
#endif
1229
0
    if (*ip < 0) {
1230
        
1231
0
#ifdef ERANGE_FILL
1232
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1233
0
#endif
1234
0
        err = NC_ERANGE; /* because xp is unsigned */
1235
0
    }
1236
0
#ifdef ERANGE_FILL
1237
0
    else
1238
0
#endif
1239
0
        xx = (ix_ushort)*ip;
1240
1241
0
    put_ix_ushort(xp, &xx);
1242
0
    return err;
1243
0
}
1244
1245
static int
1246
ncx_put_ushort_int(void *xp, const int *ip, void *fillp)
1247
0
{
1248
0
    int err=NC_NOERR;
1249
0
    ix_ushort xx = NC_FILL_USHORT;
1250
1251
0
#if IX_USHORT_MAX < INT_MAX
1252
0
    if (*ip > IX_USHORT_MAX) {
1253
        
1254
0
#ifdef ERANGE_FILL
1255
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1256
0
#endif
1257
0
        err = NC_ERANGE;
1258
0
    }
1259
0
#ifdef ERANGE_FILL
1260
0
    else
1261
0
#endif
1262
0
#endif
1263
0
    if (*ip < 0) {
1264
        
1265
0
#ifdef ERANGE_FILL
1266
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1267
0
#endif
1268
0
        err = NC_ERANGE; /* because xp is unsigned */
1269
0
    }
1270
0
#ifdef ERANGE_FILL
1271
0
    else
1272
0
#endif
1273
0
        xx = (ix_ushort)*ip;
1274
1275
0
    put_ix_ushort(xp, &xx);
1276
0
    return err;
1277
0
}
1278
1279
static int
1280
ncx_put_ushort_long(void *xp, const long *ip, void *fillp)
1281
0
{
1282
0
    int err=NC_NOERR;
1283
0
    ix_ushort xx = NC_FILL_USHORT;
1284
1285
0
#if IX_USHORT_MAX < LONG_MAX
1286
0
    if (*ip > IX_USHORT_MAX) {
1287
        
1288
0
#ifdef ERANGE_FILL
1289
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1290
0
#endif
1291
0
        err = NC_ERANGE;
1292
0
    }
1293
0
#ifdef ERANGE_FILL
1294
0
    else
1295
0
#endif
1296
0
#endif
1297
0
    if (*ip < 0) {
1298
        
1299
0
#ifdef ERANGE_FILL
1300
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1301
0
#endif
1302
0
        err = NC_ERANGE; /* because xp is unsigned */
1303
0
    }
1304
0
#ifdef ERANGE_FILL
1305
0
    else
1306
0
#endif
1307
0
        xx = (ix_ushort)*ip;
1308
1309
0
    put_ix_ushort(xp, &xx);
1310
0
    return err;
1311
0
}
1312
1313
static int
1314
ncx_put_ushort_longlong(void *xp, const longlong *ip, void *fillp)
1315
0
{
1316
0
    int err=NC_NOERR;
1317
0
    ix_ushort xx = NC_FILL_USHORT;
1318
1319
0
#if IX_USHORT_MAX < LONGLONG_MAX
1320
0
    if (*ip > IX_USHORT_MAX) {
1321
        
1322
0
#ifdef ERANGE_FILL
1323
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1324
0
#endif
1325
0
        err = NC_ERANGE;
1326
0
    }
1327
0
#ifdef ERANGE_FILL
1328
0
    else
1329
0
#endif
1330
0
#endif
1331
0
    if (*ip < 0) {
1332
        
1333
0
#ifdef ERANGE_FILL
1334
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1335
0
#endif
1336
0
        err = NC_ERANGE; /* because xp is unsigned */
1337
0
    }
1338
0
#ifdef ERANGE_FILL
1339
0
    else
1340
0
#endif
1341
0
        xx = (ix_ushort)*ip;
1342
1343
0
    put_ix_ushort(xp, &xx);
1344
0
    return err;
1345
0
}
1346
1347
static int
1348
ncx_put_ushort_ushort(void *xp, const ushort *ip, void *fillp)
1349
0
{
1350
0
    int err=NC_NOERR;
1351
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1352
0
    put_ix_ushort(xp, (const ix_ushort *)ip);
1353
#else
1354
    ix_ushort xx = NC_FILL_USHORT;
1355
1356
#if IX_USHORT_MAX < USHORT_MAX
1357
    if (*ip > IX_USHORT_MAX) {
1358
        
1359
#ifdef ERANGE_FILL
1360
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1361
#endif
1362
        err = NC_ERANGE;
1363
    }
1364
#ifdef ERANGE_FILL
1365
    else
1366
#endif
1367
#endif
1368
        xx = (ix_ushort)*ip;
1369
1370
    put_ix_ushort(xp, &xx);
1371
#endif
1372
0
    return err;
1373
0
}
1374
1375
static int
1376
ncx_put_ushort_uint(void *xp, const uint *ip, void *fillp)
1377
0
{
1378
0
    int err=NC_NOERR;
1379
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1380
    put_ix_ushort(xp, (const ix_ushort *)ip);
1381
#else
1382
0
    ix_ushort xx = NC_FILL_USHORT;
1383
1384
0
#if IX_USHORT_MAX < UINT_MAX
1385
0
    if (*ip > IX_USHORT_MAX) {
1386
        
1387
0
#ifdef ERANGE_FILL
1388
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1389
0
#endif
1390
0
        err = NC_ERANGE;
1391
0
    }
1392
0
#ifdef ERANGE_FILL
1393
0
    else
1394
0
#endif
1395
0
#endif
1396
0
        xx = (ix_ushort)*ip;
1397
1398
0
    put_ix_ushort(xp, &xx);
1399
0
#endif
1400
0
    return err;
1401
0
}
1402
1403
static int
1404
ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1405
0
{
1406
0
    int err=NC_NOERR;
1407
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1408
    put_ix_ushort(xp, (const ix_ushort *)ip);
1409
#else
1410
0
    ix_ushort xx = NC_FILL_USHORT;
1411
1412
0
#if IX_USHORT_MAX < ULONGLONG_MAX
1413
0
    if (*ip > IX_USHORT_MAX) {
1414
        
1415
0
#ifdef ERANGE_FILL
1416
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1417
0
#endif
1418
0
        err = NC_ERANGE;
1419
0
    }
1420
0
#ifdef ERANGE_FILL
1421
0
    else
1422
0
#endif
1423
0
#endif
1424
0
        xx = (ix_ushort)*ip;
1425
1426
0
    put_ix_ushort(xp, &xx);
1427
0
#endif
1428
0
    return err;
1429
0
}
1430
1431
static int
1432
ncx_put_ushort_float(void *xp, const float *ip, void *fillp)
1433
0
{
1434
0
    int err=NC_NOERR;
1435
0
    ix_ushort xx = NC_FILL_USHORT;
1436
1437
0
    if (*ip > (double)X_USHORT_MAX || *ip < 0) {
1438
        
1439
0
#ifdef ERANGE_FILL
1440
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1441
0
#endif
1442
0
        err = NC_ERANGE;
1443
0
    }
1444
0
#ifdef ERANGE_FILL
1445
0
    else
1446
0
#endif
1447
0
        xx = (ix_ushort)*ip;
1448
1449
0
    put_ix_ushort(xp, &xx);
1450
0
    return err;
1451
0
}
1452
1453
static int
1454
ncx_put_ushort_double(void *xp, const double *ip, void *fillp)
1455
0
{
1456
0
    int err=NC_NOERR;
1457
0
    ix_ushort xx = NC_FILL_USHORT;
1458
1459
0
    if (*ip > X_USHORT_MAX || *ip < 0) {
1460
        
1461
0
#ifdef ERANGE_FILL
1462
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1463
0
#endif
1464
0
        err = NC_ERANGE;
1465
0
    }
1466
0
#ifdef ERANGE_FILL
1467
0
    else
1468
0
#endif
1469
0
        xx = (ix_ushort)*ip;
1470
1471
0
    put_ix_ushort(xp, &xx);
1472
0
    return err;
1473
0
}
1474
1475
1476
/* external NC_INT ----------------------------------------------------------*/
1477
1478
#if SHORT_MAX == X_INT_MAX
1479
typedef short ix_int;
1480
#define SIZEOF_IX_INT SIZEOF_SHORT
1481
#define IX_INT_MAX SHORT_MAX
1482
#elif INT_MAX  >= X_INT_MAX
1483
typedef int ix_int;
1484
#define SIZEOF_IX_INT SIZEOF_INT
1485
0
#define IX_INT_MAX INT_MAX
1486
#elif LONG_MAX  >= X_INT_MAX
1487
typedef long ix_int;
1488
#define SIZEOF_IX_INT SIZEOF_LONG
1489
#define IX_INT_MAX LONG_MAX
1490
#else
1491
#error "ix_int implementation"
1492
#endif
1493
1494
1495
static void
1496
get_ix_int(const void *xp, ix_int *ip)
1497
0
{
1498
0
  const uchar *cp = (const uchar *) xp;
1499
1500
0
#if INT_MAX  >= X_INT_MAX
1501
0
  *ip = (ix_int)((unsigned)(*cp++) << 24);
1502
#else
1503
  *ip = *cp++ << 24;
1504
#endif
1505
#if SIZEOF_IX_INT > X_SIZEOF_INT
1506
  if (*ip & 0x80000000)
1507
  {
1508
    /* extern is negative */
1509
    *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
1510
  }
1511
#endif
1512
0
  *ip |= (*cp++ << 16);
1513
0
  *ip |= (*cp++ << 8);
1514
0
  *ip |= *cp;
1515
0
}
1516
1517
static void
1518
put_ix_int(void *xp, const ix_int *ip)
1519
0
{
1520
0
  uchar *cp = (uchar *) xp;
1521
1522
0
  *cp++ = (uchar)( (*ip) >> 24);
1523
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
1524
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
1525
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
1526
0
}
1527
1528
#if X_SIZEOF_INT != SIZEOF_INT
1529
static int
1530
ncx_get_int_int(const void *xp, int *ip)
1531
{
1532
    int err=NC_NOERR;
1533
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1534
    get_ix_int(xp, (ix_int *)ip);
1535
#else
1536
    ix_int xx = 0;
1537
    get_ix_int(xp, &xx);
1538
1539
#if IX_INT_MAX > INT_MAX
1540
    if (xx > INT_MAX || xx < INT_MIN) {
1541
#ifdef ERANGE_FILL
1542
        *ip = NC_FILL_INT;
1543
        return NC_ERANGE;
1544
#else
1545
        err = NC_ERANGE;
1546
#endif
1547
    }
1548
#endif
1549
1550
1551
    *ip = (int) xx;
1552
#endif
1553
    return err;
1554
}
1555
1556
#endif
1557
static int
1558
ncx_get_int_schar(const void *xp, schar *ip)
1559
0
{
1560
0
    int err=NC_NOERR;
1561
0
    ix_int xx = 0;
1562
0
    get_ix_int(xp, &xx);
1563
1564
0
#if IX_INT_MAX > SCHAR_MAX
1565
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
1566
0
#ifdef ERANGE_FILL
1567
0
        *ip = NC_FILL_BYTE;
1568
0
        return NC_ERANGE;
1569
#else
1570
        err = NC_ERANGE;
1571
#endif
1572
0
    }
1573
0
#endif
1574
1575
1576
0
    *ip = (schar) xx;
1577
0
    return err;
1578
0
}
1579
1580
static int
1581
ncx_get_int_short(const void *xp, short *ip)
1582
0
{
1583
0
    int err=NC_NOERR;
1584
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1585
    get_ix_int(xp, (ix_int *)ip);
1586
#else
1587
0
    ix_int xx = 0;
1588
0
    get_ix_int(xp, &xx);
1589
1590
0
#if IX_INT_MAX > SHORT_MAX
1591
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
1592
0
#ifdef ERANGE_FILL
1593
0
        *ip = NC_FILL_SHORT;
1594
0
        return NC_ERANGE;
1595
#else
1596
        err = NC_ERANGE;
1597
#endif
1598
0
    }
1599
0
#endif
1600
1601
1602
0
    *ip = (short) xx;
1603
0
#endif
1604
0
    return err;
1605
0
}
1606
1607
static int
1608
ncx_get_int_long(const void *xp, long *ip)
1609
0
{
1610
0
    int err=NC_NOERR;
1611
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1612
    get_ix_int(xp, (ix_int *)ip);
1613
#else
1614
0
    ix_int xx = 0;
1615
0
    get_ix_int(xp, &xx);
1616
1617
#if IX_INT_MAX > LONG_MAX
1618
    if (xx > LONG_MAX || xx < LONG_MIN) {
1619
#ifdef ERANGE_FILL
1620
        *ip = NC_FILL_INT;
1621
        return NC_ERANGE;
1622
#else
1623
        err = NC_ERANGE;
1624
#endif
1625
    }
1626
#endif
1627
1628
1629
0
    *ip = (long) xx;
1630
0
#endif
1631
0
    return err;
1632
0
}
1633
1634
static int
1635
ncx_get_int_longlong(const void *xp, longlong *ip)
1636
0
{
1637
0
    int err=NC_NOERR;
1638
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1639
    get_ix_int(xp, (ix_int *)ip);
1640
#else
1641
0
    ix_int xx = 0;
1642
0
    get_ix_int(xp, &xx);
1643
1644
#if IX_INT_MAX > LONGLONG_MAX
1645
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
1646
#ifdef ERANGE_FILL
1647
        *ip = NC_FILL_INT64;
1648
        return NC_ERANGE;
1649
#else
1650
        err = NC_ERANGE;
1651
#endif
1652
    }
1653
#endif
1654
1655
1656
0
    *ip = (longlong) xx;
1657
0
#endif
1658
0
    return err;
1659
0
}
1660
1661
static int
1662
ncx_get_int_ushort(const void *xp, ushort *ip)
1663
0
{
1664
0
    int err=NC_NOERR;
1665
0
    ix_int xx = 0;
1666
0
    get_ix_int(xp, &xx);
1667
1668
0
#if IX_INT_MAX > USHORT_MAX
1669
0
    if (xx > USHORT_MAX) {
1670
0
#ifdef ERANGE_FILL
1671
0
        *ip = NC_FILL_USHORT;
1672
0
        return NC_ERANGE;
1673
#else
1674
        err = NC_ERANGE;
1675
#endif
1676
0
    }
1677
0
#endif
1678
1679
0
    if (xx < 0) {
1680
0
#ifdef ERANGE_FILL
1681
0
        *ip = NC_FILL_USHORT;
1682
0
        return NC_ERANGE;
1683
#else
1684
        err = NC_ERANGE; /* because ip is unsigned */
1685
#endif
1686
0
    }
1687
0
    *ip = (ushort) xx;
1688
0
    return err;
1689
0
}
1690
1691
static int
1692
ncx_get_int_uchar(const void *xp, uchar *ip)
1693
0
{
1694
0
    int err=NC_NOERR;
1695
0
    ix_int xx = 0;
1696
0
    get_ix_int(xp, &xx);
1697
1698
0
#if IX_INT_MAX > UCHAR_MAX
1699
0
    if (xx > UCHAR_MAX) {
1700
0
#ifdef ERANGE_FILL
1701
0
        *ip = NC_FILL_UBYTE;
1702
0
        return NC_ERANGE;
1703
#else
1704
        err = NC_ERANGE;
1705
#endif
1706
0
    }
1707
0
#endif
1708
1709
0
    if (xx < 0) {
1710
0
#ifdef ERANGE_FILL
1711
0
        *ip = NC_FILL_UBYTE;
1712
0
        return NC_ERANGE;
1713
#else
1714
        err = NC_ERANGE; /* because ip is unsigned */
1715
#endif
1716
0
    }
1717
0
    *ip = (uchar) xx;
1718
0
    return err;
1719
0
}
1720
1721
static int
1722
ncx_get_int_uint(const void *xp, uint *ip)
1723
0
{
1724
0
    int err=NC_NOERR;
1725
0
    ix_int xx = 0;
1726
0
    get_ix_int(xp, &xx);
1727
1728
#if IX_INT_MAX > UINT_MAX
1729
    if (xx > UINT_MAX) {
1730
#ifdef ERANGE_FILL
1731
        *ip = NC_FILL_UINT;
1732
        return NC_ERANGE;
1733
#else
1734
        err = NC_ERANGE;
1735
#endif
1736
    }
1737
#endif
1738
1739
0
    if (xx < 0) {
1740
0
#ifdef ERANGE_FILL
1741
0
        *ip = NC_FILL_UINT;
1742
0
        return NC_ERANGE;
1743
#else
1744
        err = NC_ERANGE; /* because ip is unsigned */
1745
#endif
1746
0
    }
1747
0
    *ip = (uint) xx;
1748
0
    return err;
1749
0
}
1750
1751
static int
1752
ncx_get_int_ulonglong(const void *xp, ulonglong *ip)
1753
0
{
1754
0
    int err=NC_NOERR;
1755
0
    ix_int xx = 0;
1756
0
    get_ix_int(xp, &xx);
1757
1758
#if IX_INT_MAX > ULONGLONG_MAX
1759
    if (xx > ULONGLONG_MAX) {
1760
#ifdef ERANGE_FILL
1761
        *ip = NC_FILL_UINT64;
1762
        return NC_ERANGE;
1763
#else
1764
        err = NC_ERANGE;
1765
#endif
1766
    }
1767
#endif
1768
1769
0
    if (xx < 0) {
1770
0
#ifdef ERANGE_FILL
1771
0
        *ip = NC_FILL_UINT64;
1772
0
        return NC_ERANGE;
1773
#else
1774
        err = NC_ERANGE; /* because ip is unsigned */
1775
#endif
1776
0
    }
1777
0
    *ip = (ulonglong) xx;
1778
0
    return err;
1779
0
}
1780
1781
static int
1782
ncx_get_int_float(const void *xp, float *ip)
1783
0
{
1784
0
  ix_int xx = 0;
1785
0
  get_ix_int(xp, &xx);
1786
0
  *ip = (float)xx;
1787
0
  return NC_NOERR;
1788
0
}
1789
1790
static int
1791
ncx_get_int_double(const void *xp, double *ip)
1792
0
{
1793
0
  ix_int xx = 0;
1794
0
  get_ix_int(xp, &xx);
1795
0
  *ip = (double)xx;
1796
0
  return NC_NOERR;
1797
0
}
1798
1799
1800
static int
1801
ncx_put_int_schar(void *xp, const schar *ip, void *fillp)
1802
0
{
1803
0
  uchar *cp = (uchar *) xp;
1804
0
  if (*ip & 0x80)
1805
0
  {
1806
0
    *cp++ = 0xff;
1807
0
    *cp++ = 0xff;
1808
0
    *cp++ = 0xff;
1809
0
  }
1810
0
  else
1811
0
  {
1812
0
    *cp++ = 0x00;
1813
0
    *cp++ = 0x00;
1814
0
    *cp++ = 0x00;
1815
0
  }
1816
0
  *cp = (uchar)*ip;
1817
0
  return NC_NOERR;
1818
0
}
1819
1820
static int
1821
ncx_put_int_uchar(void *xp, const uchar *ip, void *fillp)
1822
0
{
1823
0
  uchar *cp = (uchar *) xp;
1824
0
  *cp++ = 0x00;
1825
0
  *cp++ = 0x00;
1826
0
  *cp++ = 0x00;
1827
0
  *cp   = *ip;
1828
0
  return NC_NOERR;
1829
0
}
1830
1831
#if X_SIZEOF_INT != SIZEOF_INT
1832
static int
1833
ncx_put_int_int(void *xp, const int *ip, void *fillp)
1834
{
1835
    int err=NC_NOERR;
1836
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1837
    put_ix_int(xp, (const ix_int *)ip);
1838
#else
1839
    ix_int xx = NC_FILL_INT;
1840
1841
#if IX_INT_MAX < INT_MAX
1842
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1843
        
1844
#ifdef ERANGE_FILL
1845
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1846
#endif
1847
        err = NC_ERANGE;
1848
    }
1849
#ifdef ERANGE_FILL
1850
    else
1851
#endif
1852
#endif
1853
        xx = (ix_int)*ip;
1854
1855
    put_ix_int(xp, &xx);
1856
#endif
1857
    return err;
1858
}
1859
1860
#endif
1861
static int
1862
ncx_put_int_short(void *xp, const short *ip, void *fillp)
1863
0
{
1864
0
    int err=NC_NOERR;
1865
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1866
    put_ix_int(xp, (const ix_int *)ip);
1867
#else
1868
0
    ix_int xx = NC_FILL_INT;
1869
1870
#if IX_INT_MAX < SHORT_MAX
1871
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1872
        
1873
#ifdef ERANGE_FILL
1874
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1875
#endif
1876
        err = NC_ERANGE;
1877
    }
1878
#ifdef ERANGE_FILL
1879
    else
1880
#endif
1881
#endif
1882
0
        xx = (ix_int)*ip;
1883
1884
0
    put_ix_int(xp, &xx);
1885
0
#endif
1886
0
    return err;
1887
0
}
1888
1889
static int
1890
ncx_put_int_long(void *xp, const long *ip, void *fillp)
1891
0
{
1892
0
    int err=NC_NOERR;
1893
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1894
    put_ix_int(xp, (const ix_int *)ip);
1895
#else
1896
0
    ix_int xx = NC_FILL_INT;
1897
1898
0
#if IX_INT_MAX < LONG_MAX
1899
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1900
        
1901
0
#ifdef ERANGE_FILL
1902
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1903
0
#endif
1904
0
        err = NC_ERANGE;
1905
0
    }
1906
0
#ifdef ERANGE_FILL
1907
0
    else
1908
0
#endif
1909
0
#endif
1910
0
        xx = (ix_int)*ip;
1911
1912
0
    put_ix_int(xp, &xx);
1913
0
#endif
1914
0
    return err;
1915
0
}
1916
1917
static int
1918
ncx_put_int_longlong(void *xp, const longlong *ip, void *fillp)
1919
0
{
1920
0
    int err=NC_NOERR;
1921
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1922
    put_ix_int(xp, (const ix_int *)ip);
1923
#else
1924
0
    ix_int xx = NC_FILL_INT;
1925
1926
0
#if IX_INT_MAX < LONGLONG_MAX
1927
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1928
        
1929
0
#ifdef ERANGE_FILL
1930
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1931
0
#endif
1932
0
        err = NC_ERANGE;
1933
0
    }
1934
0
#ifdef ERANGE_FILL
1935
0
    else
1936
0
#endif
1937
0
#endif
1938
0
        xx = (ix_int)*ip;
1939
1940
0
    put_ix_int(xp, &xx);
1941
0
#endif
1942
0
    return err;
1943
0
}
1944
1945
static int
1946
ncx_put_int_ushort(void *xp, const ushort *ip, void *fillp)
1947
0
{
1948
0
    int err=NC_NOERR;
1949
0
    ix_int xx = NC_FILL_INT;
1950
1951
#if IX_INT_MAX < USHORT_MAX
1952
    if (*ip > IX_INT_MAX) {
1953
        
1954
#ifdef ERANGE_FILL
1955
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1956
#endif
1957
        err = NC_ERANGE;
1958
    }
1959
#ifdef ERANGE_FILL
1960
    else
1961
#endif
1962
#endif
1963
0
        xx = (ix_int)*ip;
1964
1965
0
    put_ix_int(xp, &xx);
1966
0
    return err;
1967
0
}
1968
1969
static int
1970
ncx_put_int_uint(void *xp, const uint *ip, void *fillp)
1971
0
{
1972
0
    int err=NC_NOERR;
1973
0
    ix_int xx = NC_FILL_INT;
1974
1975
0
#if IX_INT_MAX < UINT_MAX
1976
0
    if (*ip > IX_INT_MAX) {
1977
        
1978
0
#ifdef ERANGE_FILL
1979
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1980
0
#endif
1981
0
        err = NC_ERANGE;
1982
0
    }
1983
0
#ifdef ERANGE_FILL
1984
0
    else
1985
0
#endif
1986
0
#endif
1987
0
        xx = (ix_int)*ip;
1988
1989
0
    put_ix_int(xp, &xx);
1990
0
    return err;
1991
0
}
1992
1993
static int
1994
ncx_put_int_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1995
0
{
1996
0
    int err=NC_NOERR;
1997
0
    ix_int xx = NC_FILL_INT;
1998
1999
0
#if IX_INT_MAX < ULONGLONG_MAX
2000
0
    if (*ip > IX_INT_MAX) {
2001
        
2002
0
#ifdef ERANGE_FILL
2003
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2004
0
#endif
2005
0
        err = NC_ERANGE;
2006
0
    }
2007
0
#ifdef ERANGE_FILL
2008
0
    else
2009
0
#endif
2010
0
#endif
2011
0
        xx = (ix_int)*ip;
2012
2013
0
    put_ix_int(xp, &xx);
2014
0
    return err;
2015
0
}
2016
2017
static int
2018
ncx_put_int_float(void *xp, const float *ip, void *fillp)
2019
0
{
2020
0
    int err=NC_NOERR;
2021
0
    ix_int xx = NC_FILL_INT;
2022
2023
0
    if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
2024
        
2025
0
#ifdef ERANGE_FILL
2026
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2027
0
#endif
2028
0
        err = NC_ERANGE;
2029
0
    }
2030
0
#ifdef ERANGE_FILL
2031
0
    else
2032
0
#endif
2033
0
        xx = (ix_int)*ip;
2034
2035
0
    put_ix_int(xp, &xx);
2036
0
    return err;
2037
0
}
2038
2039
static int
2040
ncx_put_int_double(void *xp, const double *ip, void *fillp)
2041
0
{
2042
0
    int err=NC_NOERR;
2043
0
    ix_int xx = NC_FILL_INT;
2044
2045
0
    if (*ip > X_INT_MAX || *ip < X_INT_MIN) {
2046
        
2047
0
#ifdef ERANGE_FILL
2048
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2049
0
#endif
2050
0
        err = NC_ERANGE;
2051
0
    }
2052
0
#ifdef ERANGE_FILL
2053
0
    else
2054
0
#endif
2055
0
        xx = (ix_int)*ip;
2056
2057
0
    put_ix_int(xp, &xx);
2058
0
    return err;
2059
0
}
2060
2061
2062
2063
/* external NC_UINT ---------------------------------------------------------*/
2064
2065
#if USHORT_MAX == X_UINT_MAX
2066
typedef ushort ix_uint;
2067
#define SIZEOF_IX_UINT SIZEOF_USHORT
2068
#define IX_UINT_MAX USHORT_MAX
2069
#elif UINT_MAX  >= X_UINT_MAX
2070
typedef uint ix_uint;
2071
#define SIZEOF_IX_UINT SIZEOF_UINT
2072
0
#define IX_UINT_MAX UINT_MAX
2073
#elif ULONG_MAX  >= X_UINT_MAX
2074
typedef ulong ix_uint;
2075
#define SIZEOF_IX_UINT SIZEOF_ULONG
2076
#define IX_UINT_MAX ULONG_MAX
2077
#else
2078
#error "ix_uint implementation"
2079
#endif
2080
2081
2082
static void
2083
get_ix_uint(const void *xp, ix_uint *ip)
2084
0
{
2085
0
  const uchar *cp = (const uchar *) xp;
2086
2087
0
  *ip =       (ix_uint)(*cp++) << 24;
2088
0
  *ip = *ip | (ix_uint)(*cp++) << 16;
2089
0
  *ip = *ip | (ix_uint)(*cp++) << 8;
2090
0
  *ip = *ip | (ix_uint)(*cp);
2091
0
}
2092
2093
static void
2094
put_ix_uint(void *xp, const ix_uint *ip)
2095
0
{
2096
0
  uchar *cp = (uchar *) xp;
2097
2098
0
  *cp++ = (uchar)((*ip) >> 24);
2099
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
2100
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
2101
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
2102
0
}
2103
2104
#if X_SIZEOF_UINT != SIZEOF_UINT
2105
static int
2106
ncx_get_uint_uint(const void *xp, uint *ip)
2107
{
2108
    int err=NC_NOERR;
2109
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2110
    get_ix_uint(xp, (ix_uint *)ip);
2111
#else
2112
    ix_uint xx = 0;
2113
    get_ix_uint(xp, &xx);
2114
2115
#if IX_UINT_MAX > UINT_MAX
2116
    if (xx > UINT_MAX) {
2117
#ifdef ERANGE_FILL
2118
        *ip = NC_FILL_UINT;
2119
        return NC_ERANGE;
2120
#else
2121
        err = NC_ERANGE;
2122
#endif
2123
    }
2124
#endif
2125
2126
2127
    *ip = (uint) xx;
2128
#endif
2129
    return err;
2130
}
2131
2132
#endif
2133
2134
static int
2135
ncx_get_uint_schar(const void *xp, schar *ip)
2136
0
{
2137
0
    int err=NC_NOERR;
2138
0
    ix_uint xx = 0;
2139
0
    get_ix_uint(xp, &xx);
2140
2141
0
#if IX_UINT_MAX > SCHAR_MAX
2142
0
    if (xx > SCHAR_MAX) {
2143
0
#ifdef ERANGE_FILL
2144
0
        *ip = NC_FILL_BYTE;
2145
0
        return NC_ERANGE;
2146
#else
2147
        err = NC_ERANGE;
2148
#endif
2149
0
    }
2150
0
#endif
2151
2152
2153
0
    *ip = (schar) xx;
2154
0
    return err;
2155
0
}
2156
2157
static int
2158
ncx_get_uint_short(const void *xp, short *ip)
2159
0
{
2160
0
    int err=NC_NOERR;
2161
0
    ix_uint xx = 0;
2162
0
    get_ix_uint(xp, &xx);
2163
2164
0
#if IX_UINT_MAX > SHORT_MAX
2165
0
    if (xx > SHORT_MAX) {
2166
0
#ifdef ERANGE_FILL
2167
0
        *ip = NC_FILL_SHORT;
2168
0
        return NC_ERANGE;
2169
#else
2170
        err = NC_ERANGE;
2171
#endif
2172
0
    }
2173
0
#endif
2174
2175
2176
0
    *ip = (short) xx;
2177
0
    return err;
2178
0
}
2179
2180
static int
2181
ncx_get_uint_int(const void *xp, int *ip)
2182
0
{
2183
0
    int err=NC_NOERR;
2184
0
    ix_uint xx = 0;
2185
0
    get_ix_uint(xp, &xx);
2186
2187
0
#if IX_UINT_MAX > INT_MAX
2188
0
    if (xx > INT_MAX) {
2189
0
#ifdef ERANGE_FILL
2190
0
        *ip = NC_FILL_INT;
2191
0
        return NC_ERANGE;
2192
#else
2193
        err = NC_ERANGE;
2194
#endif
2195
0
    }
2196
0
#endif
2197
2198
2199
0
    *ip = (int) xx;
2200
0
    return err;
2201
0
}
2202
2203
static int
2204
ncx_get_uint_long(const void *xp, long *ip)
2205
0
{
2206
0
    int err=NC_NOERR;
2207
0
    ix_uint xx = 0;
2208
0
    get_ix_uint(xp, &xx);
2209
2210
#if IX_UINT_MAX > LONG_MAX
2211
    if (xx > LONG_MAX) {
2212
#ifdef ERANGE_FILL
2213
        *ip = NC_FILL_INT;
2214
        return NC_ERANGE;
2215
#else
2216
        err = NC_ERANGE;
2217
#endif
2218
    }
2219
#endif
2220
2221
2222
0
    *ip = (long) xx;
2223
0
    return err;
2224
0
}
2225
2226
static int
2227
ncx_get_uint_longlong(const void *xp, longlong *ip)
2228
0
{
2229
0
    int err=NC_NOERR;
2230
0
    ix_uint xx = 0;
2231
0
    get_ix_uint(xp, &xx);
2232
2233
#if IX_UINT_MAX > LONGLONG_MAX
2234
    if (xx > LONGLONG_MAX) {
2235
#ifdef ERANGE_FILL
2236
        *ip = NC_FILL_INT64;
2237
        return NC_ERANGE;
2238
#else
2239
        err = NC_ERANGE;
2240
#endif
2241
    }
2242
#endif
2243
2244
2245
0
    *ip = (longlong) xx;
2246
0
    return err;
2247
0
}
2248
2249
static int
2250
ncx_get_uint_ushort(const void *xp, ushort *ip)
2251
0
{
2252
0
    int err=NC_NOERR;
2253
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2254
    get_ix_uint(xp, (ix_uint *)ip);
2255
#else
2256
0
    ix_uint xx = 0;
2257
0
    get_ix_uint(xp, &xx);
2258
2259
0
#if IX_UINT_MAX > USHORT_MAX
2260
0
    if (xx > USHORT_MAX) {
2261
0
#ifdef ERANGE_FILL
2262
0
        *ip = NC_FILL_USHORT;
2263
0
        return NC_ERANGE;
2264
#else
2265
        err = NC_ERANGE;
2266
#endif
2267
0
    }
2268
0
#endif
2269
2270
2271
0
    *ip = (ushort) xx;
2272
0
#endif
2273
0
    return err;
2274
0
}
2275
2276
static int
2277
ncx_get_uint_uchar(const void *xp, uchar *ip)
2278
0
{
2279
0
    int err=NC_NOERR;
2280
#if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
2281
    get_ix_uint(xp, (ix_uint *)ip);
2282
#else
2283
0
    ix_uint xx = 0;
2284
0
    get_ix_uint(xp, &xx);
2285
2286
0
#if IX_UINT_MAX > UCHAR_MAX
2287
0
    if (xx > UCHAR_MAX) {
2288
0
#ifdef ERANGE_FILL
2289
0
        *ip = NC_FILL_UBYTE;
2290
0
        return NC_ERANGE;
2291
#else
2292
        err = NC_ERANGE;
2293
#endif
2294
0
    }
2295
0
#endif
2296
2297
2298
0
    *ip = (uchar) xx;
2299
0
#endif
2300
0
    return err;
2301
0
}
2302
2303
static int
2304
ncx_get_uint_ulonglong(const void *xp, ulonglong *ip)
2305
0
{
2306
0
    int err=NC_NOERR;
2307
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2308
    get_ix_uint(xp, (ix_uint *)ip);
2309
#else
2310
0
    ix_uint xx = 0;
2311
0
    get_ix_uint(xp, &xx);
2312
2313
#if IX_UINT_MAX > ULONGLONG_MAX
2314
    if (xx > ULONGLONG_MAX) {
2315
#ifdef ERANGE_FILL
2316
        *ip = NC_FILL_UINT64;
2317
        return NC_ERANGE;
2318
#else
2319
        err = NC_ERANGE;
2320
#endif
2321
    }
2322
#endif
2323
2324
2325
0
    *ip = (ulonglong) xx;
2326
0
#endif
2327
0
    return err;
2328
0
}
2329
2330
static int
2331
ncx_get_uint_float(const void *xp, float *ip)
2332
0
{
2333
0
  ix_uint xx = 0;
2334
0
  get_ix_uint(xp, &xx);
2335
0
  *ip = (float)xx;
2336
0
  return NC_NOERR;
2337
0
}
2338
2339
static int
2340
ncx_get_uint_double(const void *xp, double *ip)
2341
0
{
2342
0
  ix_uint xx = 0;
2343
0
  get_ix_uint(xp, &xx);
2344
0
  *ip = (double)xx;
2345
0
  return NC_NOERR;
2346
0
}
2347
2348
2349
static int
2350
ncx_put_uint_schar(void *xp, const schar *ip, void *fillp)
2351
0
{
2352
0
    uchar *cp;
2353
0
    if (*ip < 0) {
2354
0
#ifdef ERANGE_FILL
2355
0
        if (fillp != NULL) memcpy(xp, fillp, 4);
2356
0
#ifndef WORDS_BIGENDIAN
2357
0
        swapn4b(xp, xp, 1);
2358
0
#endif
2359
0
#endif
2360
0
        return NC_ERANGE;
2361
0
    }
2362
2363
0
    cp = (uchar *) xp;
2364
0
    *cp++ = 0x00;
2365
0
    *cp++ = 0x00;
2366
0
    *cp++ = 0x00;
2367
0
    *cp = (uchar)*ip;
2368
2369
0
    return NC_NOERR;
2370
0
}
2371
2372
static int
2373
ncx_put_uint_uchar(void *xp, const uchar *ip, void *fillp)
2374
0
{
2375
0
  uchar *cp = (uchar *) xp;
2376
0
  *cp++ = 0x00;
2377
0
  *cp++ = 0x00;
2378
0
  *cp++ = 0x00;
2379
0
  *cp   = *ip;
2380
0
  return NC_NOERR;
2381
0
}
2382
2383
#if X_SIZEOF_UINT != SIZEOF_UINT
2384
static int
2385
ncx_put_uint_uint(void *xp, const uint *ip, void *fillp)
2386
{
2387
    int err=NC_NOERR;
2388
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2389
    put_ix_uint(xp, (const ix_uint *)ip);
2390
#else
2391
    ix_uint xx = NC_FILL_UINT;
2392
2393
#if IX_UINT_MAX < UINT_MAX
2394
    if (*ip > IX_UINT_MAX) {
2395
        
2396
#ifdef ERANGE_FILL
2397
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2398
#endif
2399
        err = NC_ERANGE;
2400
    }
2401
#ifdef ERANGE_FILL
2402
    else
2403
#endif
2404
#endif
2405
        xx = (ix_uint)*ip;
2406
2407
    put_ix_uint(xp, &xx);
2408
#endif
2409
    return err;
2410
}
2411
2412
#endif
2413
2414
static int
2415
ncx_put_uint_short(void *xp, const short *ip, void *fillp)
2416
0
{
2417
0
    int err=NC_NOERR;
2418
0
    ix_uint xx = NC_FILL_UINT;
2419
2420
#if IX_UINT_MAX < SHORT_MAX
2421
    if (*ip > IX_UINT_MAX) {
2422
        
2423
#ifdef ERANGE_FILL
2424
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2425
#endif
2426
        err = NC_ERANGE;
2427
    }
2428
#ifdef ERANGE_FILL
2429
    else
2430
#endif
2431
#endif
2432
0
    if (*ip < 0) {
2433
        
2434
0
#ifdef ERANGE_FILL
2435
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2436
0
#endif
2437
0
        err = NC_ERANGE; /* because xp is unsigned */
2438
0
    }
2439
0
#ifdef ERANGE_FILL
2440
0
    else
2441
0
#endif
2442
0
        xx = (ix_uint)*ip;
2443
2444
0
    put_ix_uint(xp, &xx);
2445
0
    return err;
2446
0
}
2447
2448
static int
2449
ncx_put_uint_int(void *xp, const int *ip, void *fillp)
2450
0
{
2451
0
    int err=NC_NOERR;
2452
0
    ix_uint xx = NC_FILL_UINT;
2453
2454
#if IX_UINT_MAX < INT_MAX
2455
    if (*ip > IX_UINT_MAX) {
2456
        
2457
#ifdef ERANGE_FILL
2458
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2459
#endif
2460
        err = NC_ERANGE;
2461
    }
2462
#ifdef ERANGE_FILL
2463
    else
2464
#endif
2465
#endif
2466
0
    if (*ip < 0) {
2467
        
2468
0
#ifdef ERANGE_FILL
2469
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2470
0
#endif
2471
0
        err = NC_ERANGE; /* because xp is unsigned */
2472
0
    }
2473
0
#ifdef ERANGE_FILL
2474
0
    else
2475
0
#endif
2476
0
        xx = (ix_uint)*ip;
2477
2478
0
    put_ix_uint(xp, &xx);
2479
0
    return err;
2480
0
}
2481
2482
static int
2483
ncx_put_uint_long(void *xp, const long *ip, void *fillp)
2484
0
{
2485
0
    int err=NC_NOERR;
2486
0
    ix_uint xx = NC_FILL_UINT;
2487
2488
0
#if IX_UINT_MAX < LONG_MAX
2489
0
    if (*ip > IX_UINT_MAX) {
2490
        
2491
0
#ifdef ERANGE_FILL
2492
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2493
0
#endif
2494
0
        err = NC_ERANGE;
2495
0
    }
2496
0
#ifdef ERANGE_FILL
2497
0
    else
2498
0
#endif
2499
0
#endif
2500
0
    if (*ip < 0) {
2501
        
2502
0
#ifdef ERANGE_FILL
2503
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2504
0
#endif
2505
0
        err = NC_ERANGE; /* because xp is unsigned */
2506
0
    }
2507
0
#ifdef ERANGE_FILL
2508
0
    else
2509
0
#endif
2510
0
        xx = (ix_uint)*ip;
2511
2512
0
    put_ix_uint(xp, &xx);
2513
0
    return err;
2514
0
}
2515
2516
static int
2517
ncx_put_uint_longlong(void *xp, const longlong *ip, void *fillp)
2518
0
{
2519
0
    int err=NC_NOERR;
2520
0
    ix_uint xx = NC_FILL_UINT;
2521
2522
0
#if IX_UINT_MAX < LONGLONG_MAX
2523
0
    if (*ip > IX_UINT_MAX) {
2524
        
2525
0
#ifdef ERANGE_FILL
2526
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2527
0
#endif
2528
0
        err = NC_ERANGE;
2529
0
    }
2530
0
#ifdef ERANGE_FILL
2531
0
    else
2532
0
#endif
2533
0
#endif
2534
0
    if (*ip < 0) {
2535
        
2536
0
#ifdef ERANGE_FILL
2537
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2538
0
#endif
2539
0
        err = NC_ERANGE; /* because xp is unsigned */
2540
0
    }
2541
0
#ifdef ERANGE_FILL
2542
0
    else
2543
0
#endif
2544
0
        xx = (ix_uint)*ip;
2545
2546
0
    put_ix_uint(xp, &xx);
2547
0
    return err;
2548
0
}
2549
2550
static int
2551
ncx_put_uint_ushort(void *xp, const ushort *ip, void *fillp)
2552
0
{
2553
0
    int err=NC_NOERR;
2554
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2555
    put_ix_uint(xp, (const ix_uint *)ip);
2556
#else
2557
0
    ix_uint xx = NC_FILL_UINT;
2558
2559
#if IX_UINT_MAX < USHORT_MAX
2560
    if (*ip > IX_UINT_MAX) {
2561
        
2562
#ifdef ERANGE_FILL
2563
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2564
#endif
2565
        err = NC_ERANGE;
2566
    }
2567
#ifdef ERANGE_FILL
2568
    else
2569
#endif
2570
#endif
2571
0
        xx = (ix_uint)*ip;
2572
2573
0
    put_ix_uint(xp, &xx);
2574
0
#endif
2575
0
    return err;
2576
0
}
2577
2578
static int
2579
ncx_put_uint_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2580
0
{
2581
0
    int err=NC_NOERR;
2582
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2583
    put_ix_uint(xp, (const ix_uint *)ip);
2584
#else
2585
0
    ix_uint xx = NC_FILL_UINT;
2586
2587
0
#if IX_UINT_MAX < ULONGLONG_MAX
2588
0
    if (*ip > IX_UINT_MAX) {
2589
        
2590
0
#ifdef ERANGE_FILL
2591
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2592
0
#endif
2593
0
        err = NC_ERANGE;
2594
0
    }
2595
0
#ifdef ERANGE_FILL
2596
0
    else
2597
0
#endif
2598
0
#endif
2599
0
        xx = (ix_uint)*ip;
2600
2601
0
    put_ix_uint(xp, &xx);
2602
0
#endif
2603
0
    return err;
2604
0
}
2605
2606
static int
2607
ncx_put_uint_float(void *xp, const float *ip, void *fillp)
2608
0
{
2609
0
    int err=NC_NOERR;
2610
0
    ix_uint xx = NC_FILL_UINT;
2611
2612
0
    if (*ip > (double)X_UINT_MAX || *ip < 0) {
2613
        
2614
0
#ifdef ERANGE_FILL
2615
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2616
0
#endif
2617
0
        err = NC_ERANGE;
2618
0
    }
2619
0
#ifdef ERANGE_FILL
2620
0
    else
2621
0
#endif
2622
0
        xx = (ix_uint)*ip;
2623
2624
0
    put_ix_uint(xp, &xx);
2625
0
    return err;
2626
0
}
2627
2628
static int
2629
ncx_put_uint_double(void *xp, const double *ip, void *fillp)
2630
0
{
2631
0
    int err=NC_NOERR;
2632
0
    ix_uint xx = NC_FILL_UINT;
2633
2634
0
    if (*ip > X_UINT_MAX || *ip < 0) {
2635
        
2636
0
#ifdef ERANGE_FILL
2637
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2638
0
#endif
2639
0
        err = NC_ERANGE;
2640
0
    }
2641
0
#ifdef ERANGE_FILL
2642
0
    else
2643
0
#endif
2644
0
        xx = (ix_uint)*ip;
2645
2646
0
    put_ix_uint(xp, &xx);
2647
0
    return err;
2648
0
}
2649
2650
2651
2652
/* external NC_FLOAT --------------------------------------------------------*/
2653
2654
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
2655
2656
inline static void
2657
get_ix_float(const void *xp, float *ip)
2658
0
{
2659
#ifdef WORDS_BIGENDIAN
2660
  (void) memcpy(ip, xp, SIZEOF_FLOAT);
2661
#else
2662
0
  swap4b(ip, xp);
2663
0
#endif
2664
0
}
2665
2666
inline static void
2667
put_ix_float(void *xp, const float *ip)
2668
0
{
2669
#ifdef WORDS_BIGENDIAN
2670
  (void) memcpy(xp, ip, X_SIZEOF_FLOAT);
2671
#else
2672
0
  swap4b(xp, ip);
2673
0
#endif
2674
0
}
2675
2676
#elif defined(vax) && vax != 0
2677
2678
/* What IEEE single precision floating point looks like on a Vax */
2679
struct  ieee_single {
2680
  unsigned int  exp_hi       : 7;
2681
  unsigned int  sign         : 1;
2682
  unsigned int  mant_hi      : 7;
2683
  unsigned int  exp_lo       : 1;
2684
  unsigned int  mant_lo_hi   : 8;
2685
  unsigned int  mant_lo_lo   : 8;
2686
};
2687
2688
/* Vax single precision floating point */
2689
struct  vax_single {
2690
  unsigned int  mantissa1 : 7;
2691
  unsigned int  exp       : 8;
2692
  unsigned int  sign      : 1;
2693
  unsigned int  mantissa2 : 16;
2694
};
2695
2696
#define VAX_SNG_BIAS  0x81
2697
#define IEEE_SNG_BIAS 0x7f
2698
2699
static struct sgl_limits {
2700
  struct vax_single s;
2701
  struct ieee_single ieee;
2702
} max = {
2703
  { 0x7f, 0xff, 0x0, 0xffff },  /* Max Vax */
2704
  { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }   /* Max IEEE */
2705
};
2706
static struct sgl_limits min = {
2707
  { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
2708
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }    /* Min IEEE */
2709
};
2710
2711
static void
2712
get_ix_float(const void *xp, float *ip)
2713
{
2714
    struct vax_single *const vsp = (struct vax_single *) ip;
2715
    const struct ieee_single *const isp =
2716
       (const struct ieee_single *) xp;
2717
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
2718
2719
    switch(exp) {
2720
    case 0 :
2721
      /* ieee subnormal */
2722
      if (isp->mant_hi == min.ieee.mant_hi
2723
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
2724
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
2725
      {
2726
        *vsp = min.s;
2727
      }
2728
      else
2729
      {
2730
        unsigned mantissa = (isp->mant_hi << 16)
2731
           | isp->mant_lo_hi << 8
2732
           | isp->mant_lo_lo;
2733
        unsigned tmp = mantissa >> 20;
2734
        if (tmp >= 4) {
2735
          vsp->exp = 2;
2736
        } else if (tmp >= 2) {
2737
          vsp->exp = 1;
2738
        } else {
2739
          *vsp = min.s;
2740
          break;
2741
        } /* else */
2742
        tmp = mantissa - (1 << (20 + vsp->exp ));
2743
        tmp <<= 3 - vsp->exp;
2744
        vsp->mantissa2 = tmp;
2745
        vsp->mantissa1 = (tmp >> 16);
2746
      }
2747
      break;
2748
    case 0xfe :
2749
    case 0xff :
2750
      *vsp = max.s;
2751
      break;
2752
    default :
2753
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
2754
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
2755
      vsp->mantissa1 = isp->mant_hi;
2756
    }
2757
2758
    vsp->sign = isp->sign;
2759
2760
}
2761
2762
2763
static void
2764
put_ix_float(void *xp, const float *ip)
2765
{
2766
    const struct vax_single *const vsp =
2767
       (const struct vax_single *)ip;
2768
    struct ieee_single *const isp = (struct ieee_single *) xp;
2769
2770
    switch(vsp->exp){
2771
    case 0 :
2772
      /* all vax float with zero exponent map to zero */
2773
      *isp = min.ieee;
2774
      break;
2775
    case 2 :
2776
    case 1 :
2777
    {
2778
      /* These will map to subnormals */
2779
      unsigned mantissa = (vsp->mantissa1 << 16)
2780
           | vsp->mantissa2;
2781
      mantissa >>= 3 - vsp->exp;
2782
      mantissa += (1 << (20 + vsp->exp));
2783
      isp->mant_lo_lo = mantissa;
2784
      isp->mant_lo_hi = mantissa >> 8;
2785
      isp->mant_hi = mantissa >> 16;
2786
      isp->exp_lo = 0;
2787
      isp->exp_hi = 0;
2788
    }
2789
      break;
2790
    case 0xff : /* max.s.exp */
2791
      if (vsp->mantissa2 == max.s.mantissa2 &&
2792
          vsp->mantissa1 == max.s.mantissa1)
2793
      {
2794
        /* map largest vax float to ieee infinity */
2795
        *isp = max.ieee;
2796
        break;
2797
      } /* else, fall thru */
2798
    default :
2799
    {
2800
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
2801
      isp->exp_hi = exp >> 1;
2802
      isp->exp_lo = exp;
2803
      isp->mant_lo_lo = vsp->mantissa2;
2804
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
2805
      isp->mant_hi = vsp->mantissa1;
2806
    }
2807
    }
2808
2809
    isp->sign = vsp->sign;
2810
2811
}
2812
2813
  /* vax */
2814
#elif defined(_CRAY) && !defined(__crayx1)
2815
2816
/*
2817
 * Return the number of bytes until the next "word" boundary
2818
 * N.B. This is based on the very weird YMP address structure,
2819
 * which puts the address within a word in the leftmost 3 bits
2820
 * of the address.
2821
 */
2822
static size_t
2823
word_align(const void *vp)
2824
{
2825
  const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
2826
  return (rem != 0);
2827
}
2828
2829
struct ieee_single_hi {
2830
  unsigned int  sign  : 1;
2831
  unsigned int   exp  : 8;
2832
  unsigned int  mant  :23;
2833
  unsigned int  pad :32;
2834
};
2835
typedef struct ieee_single_hi ieee_single_hi;
2836
2837
struct ieee_single_lo {
2838
  unsigned int  pad :32;
2839
  unsigned int  sign  : 1;
2840
  unsigned int   exp  : 8;
2841
  unsigned int  mant  :23;
2842
};
2843
typedef struct ieee_single_lo ieee_single_lo;
2844
2845
static const int ieee_single_bias = 0x7f;
2846
2847
struct ieee_double {
2848
  unsigned int  sign  : 1;
2849
  unsigned int   exp  :11;
2850
  unsigned int  mant  :52;
2851
};
2852
typedef struct ieee_double ieee_double;
2853
2854
static const int ieee_double_bias = 0x3ff;
2855
2856
#if defined(NO_IEEE_FLOAT)
2857
2858
struct cray_single {
2859
  unsigned int  sign  : 1;
2860
  unsigned int   exp  :15;
2861
  unsigned int  mant  :48;
2862
};
2863
typedef struct cray_single cray_single;
2864
2865
static const int cs_ieis_bias = 0x4000 - 0x7f;
2866
2867
static const int cs_id_bias = 0x4000 - 0x3ff;
2868
2869
2870
static void
2871
get_ix_float(const void *xp, float *ip)
2872
{
2873
2874
  if (word_align(xp) == 0)
2875
  {
2876
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
2877
    cray_single *csp = (cray_single *) ip;
2878
2879
    if (isp->exp == 0)
2880
    {
2881
      /* ieee subnormal */
2882
      *ip = (double)isp->mant;
2883
      if (isp->mant != 0)
2884
      {
2885
        csp->exp -= (ieee_single_bias + 22);
2886
      }
2887
    }
2888
    else
2889
    {
2890
      csp->exp  = isp->exp + cs_ieis_bias + 1;
2891
      csp->mant = isp->mant << (48 - 1 - 23);
2892
      csp->mant |= (1 << (48 - 1));
2893
    }
2894
    csp->sign = isp->sign;
2895
2896
2897
  }
2898
  else
2899
  {
2900
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
2901
    cray_single *csp = (cray_single *) ip;
2902
2903
    if (isp->exp == 0)
2904
    {
2905
      /* ieee subnormal */
2906
      *ip = (double)isp->mant;
2907
      if (isp->mant != 0)
2908
      {
2909
        csp->exp -= (ieee_single_bias + 22);
2910
      }
2911
    }
2912
    else
2913
    {
2914
      csp->exp  = isp->exp + cs_ieis_bias + 1;
2915
      csp->mant = isp->mant << (48 - 1 - 23);
2916
      csp->mant |= (1 << (48 - 1));
2917
    }
2918
    csp->sign = isp->sign;
2919
2920
2921
  }
2922
}
2923
2924
static void
2925
put_ix_float(void *xp, const float *ip)
2926
{
2927
  if (word_align(xp) == 0)
2928
  {
2929
    ieee_single_hi *isp = (ieee_single_hi*)xp;
2930
  const cray_single *csp = (const cray_single *) ip;
2931
  int ieee_exp = csp->exp - cs_ieis_bias -1;
2932
2933
  isp->sign = csp->sign;
2934
2935
  if (ieee_exp >= 0xff)
2936
  {
2937
    /* NC_ERANGE => ieee Inf */
2938
    isp->exp = 0xff;
2939
    isp->mant = 0x0;
2940
  }
2941
  else if (ieee_exp > 0)
2942
  {
2943
    /* normal ieee representation */
2944
    isp->exp  = ieee_exp;
2945
    /* assumes cray rep is in normal form */
2946
    assert(csp->mant & 0x800000000000);
2947
    isp->mant = (((csp->mant << 1) &
2948
        0xffffffffffff) >> (48 - 23));
2949
  }
2950
  else if (ieee_exp > -23)
2951
  {
2952
    /* ieee subnormal, right shift */
2953
    const int rshift = (48 - 23 - ieee_exp);
2954
2955
    isp->mant = csp->mant >> rshift;
2956
2957
#if 0
2958
    if (csp->mant & (1 << (rshift -1)))
2959
    {
2960
      /* round up */
2961
      isp->mant++;
2962
    }
2963
#endif
2964
2965
    isp->exp  = 0;
2966
  }
2967
  else
2968
  {
2969
    /* smaller than ieee can represent */
2970
    isp->exp = 0;
2971
    isp->mant = 0;
2972
  }
2973
2974
  }
2975
  else
2976
  {
2977
    ieee_single_lo *isp = (ieee_single_lo*)xp;
2978
  const cray_single *csp = (const cray_single *) ip;
2979
  int ieee_exp = csp->exp - cs_ieis_bias -1;
2980
2981
  isp->sign = csp->sign;
2982
2983
  if (ieee_exp >= 0xff)
2984
  {
2985
    /* NC_ERANGE => ieee Inf */
2986
    isp->exp = 0xff;
2987
    isp->mant = 0x0;
2988
  }
2989
  else if (ieee_exp > 0)
2990
  {
2991
    /* normal ieee representation */
2992
    isp->exp  = ieee_exp;
2993
    /* assumes cray rep is in normal form */
2994
    assert(csp->mant & 0x800000000000);
2995
    isp->mant = (((csp->mant << 1) &
2996
        0xffffffffffff) >> (48 - 23));
2997
  }
2998
  else if (ieee_exp > -23)
2999
  {
3000
    /* ieee subnormal, right shift */
3001
    const int rshift = (48 - 23 - ieee_exp);
3002
3003
    isp->mant = csp->mant >> rshift;
3004
3005
#if 0
3006
    if (csp->mant & (1 << (rshift -1)))
3007
    {
3008
      /* round up */
3009
      isp->mant++;
3010
    }
3011
#endif
3012
3013
    isp->exp  = 0;
3014
  }
3015
  else
3016
  {
3017
    /* smaller than ieee can represent */
3018
    isp->exp = 0;
3019
    isp->mant = 0;
3020
  }
3021
3022
  }
3023
}
3024
3025
#else
3026
  /* IEEE Cray with only doubles */
3027
static void
3028
get_ix_float(const void *xp, float *ip)
3029
{
3030
3031
  ieee_double *idp = (ieee_double *) ip;
3032
3033
  if (word_align(xp) == 0)
3034
  {
3035
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3036
    if (isp->exp == 0 && isp->mant == 0)
3037
    {
3038
      idp->exp = 0;
3039
      idp->mant = 0;
3040
    }
3041
    else
3042
    {
3043
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3044
      idp->mant = isp->mant << (52 - 23);
3045
    }
3046
    idp->sign = isp->sign;
3047
  }
3048
  else
3049
  {
3050
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3051
    if (isp->exp == 0 && isp->mant == 0)
3052
    {
3053
      idp->exp = 0;
3054
      idp->mant = 0;
3055
    }
3056
    else
3057
    {
3058
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3059
      idp->mant = isp->mant << (52 - 23);
3060
    }
3061
    idp->sign = isp->sign;
3062
  }
3063
}
3064
3065
static void
3066
put_ix_float(void *xp, const float *ip)
3067
{
3068
  const ieee_double *idp = (const ieee_double *) ip;
3069
  if (word_align(xp) == 0)
3070
  {
3071
    ieee_single_hi *isp = (ieee_single_hi*)xp;
3072
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3073
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3074
    else
3075
      isp->exp = 0;
3076
    isp->mant = idp->mant >> (52 - 23);
3077
    isp->sign = idp->sign;
3078
  }
3079
  else
3080
  {
3081
    ieee_single_lo *isp = (ieee_single_lo*)xp;
3082
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3083
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3084
    else
3085
      isp->exp = 0;
3086
    isp->mant = idp->mant >> (52 - 23);
3087
    isp->sign = idp->sign;
3088
  }
3089
}
3090
#endif
3091
3092
#else
3093
#error "ix_float implementation"
3094
#endif
3095
3096
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3097
static int
3098
ncx_get_float_float(const void *xp, float *ip, void *fillp)
3099
{
3100
  /* TODO */
3101
  get_ix_float(xp, ip);
3102
  return NC_NOERR;
3103
}
3104
#endif
3105
3106
0
#define ix_float float
3107
3108
static int
3109
ncx_get_float_schar(const void *xp, schar *ip)
3110
0
{
3111
0
  ix_float xx = 0;
3112
0
  get_ix_float(xp, &xx);
3113
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3114
0
#ifdef ERANGE_FILL
3115
0
            *ip = NC_FILL_BYTE;
3116
0
#endif
3117
0
            return NC_ERANGE;
3118
0
        }
3119
0
  *ip = (schar)xx;
3120
0
  return NC_NOERR;
3121
0
}
3122
3123
static int
3124
ncx_get_float_short(const void *xp, short *ip)
3125
0
{
3126
0
  ix_float xx = 0;
3127
0
  get_ix_float(xp, &xx);
3128
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3129
0
#ifdef ERANGE_FILL
3130
0
            *ip = NC_FILL_SHORT;
3131
0
#endif
3132
0
            return NC_ERANGE;
3133
0
        }
3134
0
  *ip = (short)xx;
3135
0
  return NC_NOERR;
3136
0
}
3137
3138
static int
3139
ncx_get_float_int(const void *xp, int *ip)
3140
0
{
3141
0
  ix_float xx = 0;
3142
0
  get_ix_float(xp, &xx);
3143
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3144
0
#ifdef ERANGE_FILL
3145
0
            *ip = NC_FILL_INT;
3146
0
#endif
3147
0
            return NC_ERANGE;
3148
0
        }
3149
0
  *ip = (int)xx;
3150
0
  return NC_NOERR;
3151
0
}
3152
3153
static int
3154
ncx_get_float_long(const void *xp, long *ip)
3155
0
{
3156
0
  ix_float xx = 0;
3157
0
  get_ix_float(xp, &xx);
3158
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3159
0
#ifdef ERANGE_FILL
3160
0
            *ip = NC_FILL_INT;
3161
0
#endif
3162
0
            return NC_ERANGE;
3163
0
        }
3164
0
  *ip = (long)xx;
3165
0
  return NC_NOERR;
3166
0
}
3167
3168
static int
3169
ncx_get_float_double(const void *xp, double *ip)
3170
0
{
3171
0
  ix_float xx = 0;
3172
0
  get_ix_float(xp, &xx);
3173
0
  *ip = (double)xx;
3174
0
  return NC_NOERR;
3175
0
}
3176
3177
static int
3178
ncx_get_float_longlong(const void *xp, longlong *ip)
3179
0
{
3180
0
  ix_float xx = 0;
3181
0
  get_ix_float(xp, &xx);
3182
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3183
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3184
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3185
0
#ifdef ERANGE_FILL
3186
0
            *ip = NC_FILL_INT64;
3187
0
#endif
3188
0
            return NC_ERANGE;
3189
0
        }
3190
0
  else *ip = (longlong)xx;
3191
0
  return NC_NOERR;
3192
0
}
3193
3194
static int
3195
ncx_get_float_uchar(const void *xp, uchar *ip)
3196
0
{
3197
0
  ix_float xx = 0;
3198
0
  get_ix_float(xp, &xx);
3199
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3200
0
#ifdef ERANGE_FILL
3201
0
            *ip = NC_FILL_UBYTE;
3202
0
#endif
3203
0
            return NC_ERANGE;
3204
0
        }
3205
0
  *ip = (uchar)xx;
3206
0
  return NC_NOERR;
3207
0
}
3208
3209
static int
3210
ncx_get_float_ushort(const void *xp, ushort *ip)
3211
0
{
3212
0
  ix_float xx = 0;
3213
0
  get_ix_float(xp, &xx);
3214
0
  if (xx > (double)USHORT_MAX || xx < 0) {
3215
0
#ifdef ERANGE_FILL
3216
0
            *ip = NC_FILL_USHORT;
3217
0
#endif
3218
0
            return NC_ERANGE;
3219
0
        }
3220
0
  *ip = (ushort)xx;
3221
0
  return NC_NOERR;
3222
0
}
3223
3224
static int
3225
ncx_get_float_uint(const void *xp, uint *ip)
3226
0
{
3227
0
  ix_float xx = 0;
3228
0
  get_ix_float(xp, &xx);
3229
0
  if (xx > (double)UINT_MAX || xx < 0) {
3230
0
#ifdef ERANGE_FILL
3231
0
            *ip = NC_FILL_UINT;
3232
0
#endif
3233
0
            return NC_ERANGE;
3234
0
        }
3235
0
  *ip = (uint)xx;
3236
0
  return NC_NOERR;
3237
0
}
3238
3239
static int
3240
ncx_get_float_ulonglong(const void *xp, ulonglong *ip)
3241
0
{
3242
0
  ix_float xx = 0;
3243
0
  get_ix_float(xp, &xx);
3244
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3245
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3246
0
#ifdef ERANGE_FILL
3247
0
            *ip = NC_FILL_UINT64;
3248
0
#endif
3249
0
            return NC_ERANGE;
3250
0
        }
3251
0
  else *ip = (ulonglong)xx;
3252
0
  return NC_NOERR;
3253
0
}
3254
3255
3256
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3257
static int
3258
ncx_put_float_float(void *xp, const float *ip, void *fillp)
3259
{
3260
    int err=NC_NOERR;
3261
    float *_ip=ip;
3262
#ifdef NO_IEEE_FLOAT
3263
#ifdef ERANGE_FILL
3264
    float tmp;
3265
#endif
3266
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3267
        
3268
#ifdef ERANGE_FILL
3269
            if (fillp != NULL) memcpy(&tmp, fillp, 4);
3270
#endif
3271
#ifdef ERANGE_FILL
3272
        _ip = &tmp;
3273
#endif
3274
        err = NC_ERANGE;
3275
    }
3276
#endif
3277
    put_ix_float(xp, _ip);
3278
    return err;
3279
}
3280
#endif
3281
3282
static int
3283
ncx_put_float_schar(void *xp, const schar *ip, void *fillp)
3284
0
{
3285
0
    int err=NC_NOERR;
3286
0
    ix_float xx = NC_FILL_FLOAT;
3287
3288
    
3289
0
        xx = (ix_float)*ip;
3290
3291
0
    put_ix_float(xp, &xx);
3292
0
    return err;
3293
0
}
3294
3295
static int
3296
ncx_put_float_short(void *xp, const short *ip, void *fillp)
3297
0
{
3298
0
    int err=NC_NOERR;
3299
0
    ix_float xx = NC_FILL_FLOAT;
3300
3301
    
3302
0
        xx = (ix_float)*ip;
3303
3304
0
    put_ix_float(xp, &xx);
3305
0
    return err;
3306
0
}
3307
3308
static int
3309
ncx_put_float_int(void *xp, const int *ip, void *fillp)
3310
0
{
3311
0
    int err=NC_NOERR;
3312
0
    ix_float xx = NC_FILL_FLOAT;
3313
3314
    
3315
0
        xx = (ix_float)*ip;
3316
3317
0
    put_ix_float(xp, &xx);
3318
0
    return err;
3319
0
}
3320
3321
static int
3322
ncx_put_float_long(void *xp, const long *ip, void *fillp)
3323
0
{
3324
0
    int err=NC_NOERR;
3325
0
    ix_float xx = NC_FILL_FLOAT;
3326
3327
    
3328
0
        xx = (ix_float)*ip;
3329
3330
0
    put_ix_float(xp, &xx);
3331
0
    return err;
3332
0
}
3333
3334
static int
3335
ncx_put_float_double(void *xp, const double *ip, void *fillp)
3336
0
{
3337
0
    int err=NC_NOERR;
3338
0
    ix_float xx = NC_FILL_FLOAT;
3339
3340
0
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3341
        
3342
0
#ifdef ERANGE_FILL
3343
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
3344
0
#endif
3345
0
        err = NC_ERANGE;
3346
0
    }
3347
0
#ifdef ERANGE_FILL
3348
0
    else
3349
0
#endif
3350
0
        xx = (ix_float)*ip;
3351
3352
0
    put_ix_float(xp, &xx);
3353
0
    return err;
3354
0
}
3355
3356
static int
3357
ncx_put_float_longlong(void *xp, const longlong *ip, void *fillp)
3358
0
{
3359
0
    int err=NC_NOERR;
3360
0
    ix_float xx = NC_FILL_FLOAT;
3361
3362
    
3363
0
        xx = (ix_float)*ip;
3364
3365
0
    put_ix_float(xp, &xx);
3366
0
    return err;
3367
0
}
3368
3369
static int
3370
ncx_put_float_uchar(void *xp, const uchar *ip, void *fillp)
3371
0
{
3372
0
    int err=NC_NOERR;
3373
0
    ix_float xx = NC_FILL_FLOAT;
3374
3375
    
3376
0
        xx = (ix_float)*ip;
3377
3378
0
    put_ix_float(xp, &xx);
3379
0
    return err;
3380
0
}
3381
3382
static int
3383
ncx_put_float_ushort(void *xp, const ushort *ip, void *fillp)
3384
0
{
3385
0
    int err=NC_NOERR;
3386
0
    ix_float xx = NC_FILL_FLOAT;
3387
3388
    
3389
0
        xx = (ix_float)*ip;
3390
3391
0
    put_ix_float(xp, &xx);
3392
0
    return err;
3393
0
}
3394
3395
static int
3396
ncx_put_float_uint(void *xp, const uint *ip, void *fillp)
3397
0
{
3398
0
    int err=NC_NOERR;
3399
0
    ix_float xx = NC_FILL_FLOAT;
3400
3401
    
3402
0
        xx = (ix_float)*ip;
3403
3404
0
    put_ix_float(xp, &xx);
3405
0
    return err;
3406
0
}
3407
3408
static int
3409
ncx_put_float_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3410
0
{
3411
0
    int err=NC_NOERR;
3412
0
    ix_float xx = NC_FILL_FLOAT;
3413
3414
    
3415
0
        xx = (ix_float)*ip;
3416
3417
0
    put_ix_float(xp, &xx);
3418
0
    return err;
3419
0
}
3420
3421
3422
3423
/* external NC_DOUBLE -------------------------------------------------------*/
3424
3425
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
3426
3427
static void
3428
get_ix_double(const void *xp, double *ip)
3429
0
{
3430
#ifdef WORDS_BIGENDIAN
3431
  (void) memcpy(ip, xp, SIZEOF_DOUBLE);
3432
#else
3433
0
  swap8b(ip, xp);
3434
0
#endif
3435
0
}
3436
3437
static void
3438
put_ix_double(void *xp, const double *ip)
3439
0
{
3440
#ifdef WORDS_BIGENDIAN
3441
  (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
3442
#else
3443
0
  swap8b(xp, ip);
3444
0
#endif
3445
0
}
3446
3447
#elif defined(vax) && vax != 0
3448
3449
/* What IEEE double precision floating point looks like on a Vax */
3450
struct  ieee_double {
3451
  unsigned int  exp_hi   : 7;
3452
  unsigned int  sign     : 1;
3453
  unsigned int  mant_6   : 4;
3454
  unsigned int  exp_lo   : 4;
3455
  unsigned int  mant_5   : 8;
3456
  unsigned int  mant_4   : 8;
3457
3458
  unsigned int  mant_lo  : 32;
3459
};
3460
3461
/* Vax double precision floating point */
3462
struct  vax_double {
3463
  unsigned int  mantissa1 : 7;
3464
  unsigned int  exp       : 8;
3465
  unsigned int  sign      : 1;
3466
  unsigned int  mantissa2 : 16;
3467
  unsigned int  mantissa3 : 16;
3468
  unsigned int  mantissa4 : 16;
3469
};
3470
3471
#define VAX_DBL_BIAS  0x81
3472
#define IEEE_DBL_BIAS 0x3ff
3473
#define MASK(nbits) ((1 << nbits) - 1)
3474
3475
static const struct dbl_limits {
3476
  struct  vax_double d;
3477
  struct  ieee_double ieee;
3478
} dbl_limits[2] = {
3479
  {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
3480
  { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
3481
  {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},   /* Min Vax */
3482
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
3483
};
3484
3485
3486
static void
3487
get_ix_double(const void *xp, double *ip)
3488
{
3489
  struct vax_double *const vdp =
3490
       (struct vax_double *)ip;
3491
  const struct ieee_double *const idp =
3492
       (const struct ieee_double *) xp;
3493
  {
3494
    const struct dbl_limits *lim;
3495
    int ii;
3496
    for (ii = 0, lim = dbl_limits;
3497
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
3498
      ii++, lim++)
3499
    {
3500
      if ((idp->mant_lo == lim->ieee.mant_lo)
3501
        && (idp->mant_4 == lim->ieee.mant_4)
3502
        && (idp->mant_5 == lim->ieee.mant_5)
3503
        && (idp->mant_6 == lim->ieee.mant_6)
3504
        && (idp->exp_lo == lim->ieee.exp_lo)
3505
        && (idp->exp_hi == lim->ieee.exp_hi)
3506
        )
3507
      {
3508
        *vdp = lim->d;
3509
        goto doneit;
3510
      }
3511
    }
3512
  }
3513
  {
3514
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
3515
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
3516
  }
3517
  {
3518
    unsigned mant_hi = ((idp->mant_6 << 16)
3519
         | (idp->mant_5 << 8)
3520
         | idp->mant_4);
3521
    unsigned mant_lo = SWAP4(idp->mant_lo);
3522
    vdp->mantissa1 = (mant_hi >> 13);
3523
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
3524
        | (mant_lo >> 29);
3525
    vdp->mantissa3 = (mant_lo >> 13);
3526
    vdp->mantissa4 = (mant_lo << 3);
3527
  }
3528
  doneit:
3529
    vdp->sign = idp->sign;
3530
3531
}
3532
3533
3534
static void
3535
put_ix_double(void *xp, const double *ip)
3536
{
3537
  const struct vax_double *const vdp =
3538
      (const struct vax_double *)ip;
3539
  struct ieee_double *const idp =
3540
       (struct ieee_double *) xp;
3541
3542
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
3543
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
3544
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
3545
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
3546
    (vdp->exp == dbl_limits[0].d.exp))
3547
  {
3548
    *idp = dbl_limits[0].ieee;
3549
    goto shipit;
3550
  }
3551
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
3552
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
3553
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
3554
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
3555
    (vdp->exp == dbl_limits[1].d.exp))
3556
  {
3557
    *idp = dbl_limits[1].ieee;
3558
    goto shipit;
3559
  }
3560
3561
  {
3562
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
3563
3564
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
3565
      (vdp->mantissa3 << 13) |
3566
      ((vdp->mantissa4 >> 3) & MASK(13));
3567
3568
    unsigned mant_hi = (vdp->mantissa1 << 13)
3569
         | (vdp->mantissa2 >> 3);
3570
3571
    if ((vdp->mantissa4 & 7) > 4)
3572
    {
3573
      /* round up */
3574
      mant_lo++;
3575
      if (mant_lo == 0)
3576
      {
3577
        mant_hi++;
3578
        if (mant_hi > 0xffffff)
3579
        {
3580
          mant_hi = 0;
3581
          exp++;
3582
        }
3583
      }
3584
    }
3585
3586
    idp->mant_lo = SWAP4(mant_lo);
3587
    idp->mant_6 = mant_hi >> 16;
3588
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
3589
    idp->mant_4 = mant_hi;
3590
    idp->exp_hi = exp >> 4;
3591
    idp->exp_lo = exp;
3592
  }
3593
3594
  shipit:
3595
    idp->sign = vdp->sign;
3596
3597
}
3598
3599
  /* vax */
3600
#elif defined(_CRAY) && !defined(__crayx1)
3601
3602
static void
3603
get_ix_double(const void *xp, double *ip)
3604
{
3605
  const ieee_double *idp = (const ieee_double *) xp;
3606
  cray_single *csp = (cray_single *) ip;
3607
3608
  if (idp->exp == 0)
3609
  {
3610
    /* ieee subnormal */
3611
    *ip = (double)idp->mant;
3612
    if (idp->mant != 0)
3613
    {
3614
      csp->exp -= (ieee_double_bias + 51);
3615
    }
3616
  }
3617
  else
3618
  {
3619
    csp->exp  = idp->exp + cs_id_bias + 1;
3620
    csp->mant = idp->mant >> (52 - 48 + 1);
3621
    csp->mant |= (1 << (48 - 1));
3622
  }
3623
  csp->sign = idp->sign;
3624
}
3625
3626
static void
3627
put_ix_double(void *xp, const double *ip)
3628
{
3629
  ieee_double *idp = (ieee_double *) xp;
3630
  const cray_single *csp = (const cray_single *) ip;
3631
3632
  int ieee_exp = csp->exp - cs_id_bias -1;
3633
3634
  idp->sign = csp->sign;
3635
3636
  if (ieee_exp >= 0x7ff)
3637
  {
3638
    /* NC_ERANGE => ieee Inf */
3639
    idp->exp = 0x7ff;
3640
    idp->mant = 0x0;
3641
  }
3642
  else if (ieee_exp > 0)
3643
  {
3644
    /* normal ieee representation */
3645
    idp->exp  = ieee_exp;
3646
    /* assumes cray rep is in normal form */
3647
    assert(csp->mant & 0x800000000000);
3648
    idp->mant = (((csp->mant << 1) &
3649
        0xffffffffffff) << (52 - 48));
3650
  }
3651
  else if (ieee_exp >= (-(52 -48)))
3652
  {
3653
    /* ieee subnormal, left shift */
3654
    const int lshift = (52 - 48) + ieee_exp;
3655
    idp->mant = csp->mant << lshift;
3656
    idp->exp  = 0;
3657
  }
3658
  else if (ieee_exp >= -52)
3659
  {
3660
    /* ieee subnormal, right shift */
3661
    const int rshift = (- (52 - 48) - ieee_exp);
3662
3663
    idp->mant = csp->mant >> rshift;
3664
3665
#if 0
3666
    if (csp->mant & (1 << (rshift -1)))
3667
    {
3668
      /* round up */
3669
      idp->mant++;
3670
    }
3671
#endif
3672
3673
    idp->exp  = 0;
3674
  }
3675
  else
3676
  {
3677
    /* smaller than ieee can represent */
3678
    idp->exp = 0;
3679
    idp->mant = 0;
3680
  }
3681
}
3682
#else
3683
#error "ix_double implementation"
3684
#endif
3685
3686
0
#define ix_double double
3687
3688
static int
3689
ncx_get_double_schar(const void *xp, schar *ip)
3690
0
{
3691
0
  ix_double xx = 0;
3692
0
  get_ix_double(xp, &xx);
3693
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3694
0
#ifdef ERANGE_FILL
3695
0
            *ip = NC_FILL_BYTE;
3696
0
#endif
3697
0
            return NC_ERANGE;
3698
0
        }
3699
0
  *ip = (schar)xx;
3700
0
  return NC_NOERR;
3701
0
}
3702
3703
static int
3704
ncx_get_double_short(const void *xp, short *ip)
3705
0
{
3706
0
  ix_double xx = 0;
3707
0
  get_ix_double(xp, &xx);
3708
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3709
0
#ifdef ERANGE_FILL
3710
0
            *ip = NC_FILL_SHORT;
3711
0
#endif
3712
0
            return NC_ERANGE;
3713
0
        }
3714
0
  *ip = (short)xx;
3715
0
  return NC_NOERR;
3716
0
}
3717
3718
static int
3719
ncx_get_double_int(const void *xp, int *ip)
3720
0
{
3721
0
  ix_double xx = 0;
3722
0
  get_ix_double(xp, &xx);
3723
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3724
0
#ifdef ERANGE_FILL
3725
0
            *ip = NC_FILL_INT;
3726
0
#endif
3727
0
            return NC_ERANGE;
3728
0
        }
3729
0
  *ip = (int)xx;
3730
0
  return NC_NOERR;
3731
0
}
3732
3733
static int
3734
ncx_get_double_long(const void *xp, long *ip)
3735
0
{
3736
0
  ix_double xx = 0;
3737
0
  get_ix_double(xp, &xx);
3738
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3739
0
#ifdef ERANGE_FILL
3740
0
            *ip = NC_FILL_INT;
3741
0
#endif
3742
0
            return NC_ERANGE;
3743
0
        }
3744
0
  *ip = (long)xx;
3745
0
  return NC_NOERR;
3746
0
}
3747
3748
static int
3749
ncx_get_double_longlong(const void *xp, longlong *ip)
3750
0
{
3751
0
  ix_double xx = 0;
3752
0
  get_ix_double(xp, &xx);
3753
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3754
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3755
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3756
0
#ifdef ERANGE_FILL
3757
0
            *ip = NC_FILL_INT64;
3758
0
#endif
3759
0
            return NC_ERANGE;
3760
0
        }
3761
0
  else *ip = (longlong)xx;
3762
0
  return NC_NOERR;
3763
0
}
3764
3765
static int
3766
ncx_get_double_uchar(const void *xp, uchar *ip)
3767
0
{
3768
0
  ix_double xx = 0;
3769
0
  get_ix_double(xp, &xx);
3770
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3771
0
#ifdef ERANGE_FILL
3772
0
            *ip = NC_FILL_UBYTE;
3773
0
#endif
3774
0
            return NC_ERANGE;
3775
0
        }
3776
0
  *ip = (uchar)xx;
3777
0
  return NC_NOERR;
3778
0
}
3779
3780
static int
3781
ncx_get_double_ushort(const void *xp, ushort *ip)
3782
0
{
3783
0
  ix_double xx = 0;
3784
0
  get_ix_double(xp, &xx);
3785
0
  if (xx > (double)USHORT_MAX || xx < 0) {
3786
0
#ifdef ERANGE_FILL
3787
0
            *ip = NC_FILL_USHORT;
3788
0
#endif
3789
0
            return NC_ERANGE;
3790
0
        }
3791
0
  *ip = (ushort)xx;
3792
0
  return NC_NOERR;
3793
0
}
3794
3795
static int
3796
ncx_get_double_uint(const void *xp, uint *ip)
3797
0
{
3798
0
  ix_double xx = 0;
3799
0
  get_ix_double(xp, &xx);
3800
0
  if (xx > (double)UINT_MAX || xx < 0) {
3801
0
#ifdef ERANGE_FILL
3802
0
            *ip = NC_FILL_UINT;
3803
0
#endif
3804
0
            return NC_ERANGE;
3805
0
        }
3806
0
  *ip = (uint)xx;
3807
0
  return NC_NOERR;
3808
0
}
3809
3810
static int
3811
ncx_get_double_ulonglong(const void *xp, ulonglong *ip)
3812
0
{
3813
0
  ix_double xx = 0;
3814
0
  get_ix_double(xp, &xx);
3815
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3816
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3817
0
#ifdef ERANGE_FILL
3818
0
            *ip = NC_FILL_UINT64;
3819
0
#endif
3820
0
            return NC_ERANGE;
3821
0
        }
3822
0
  else *ip = (ulonglong)xx;
3823
0
  return NC_NOERR;
3824
0
}
3825
3826
3827
static int
3828
ncx_get_double_float(const void *xp, float *ip)
3829
0
{
3830
0
    double xx = 0.0;
3831
0
    get_ix_double(xp, &xx);
3832
0
    if (xx > FLT_MAX) {
3833
0
#ifdef ERANGE_FILL
3834
0
        *ip = NC_FILL_FLOAT;
3835
#else
3836
        *ip = FLT_MAX;
3837
#endif
3838
0
        return NC_ERANGE;
3839
0
    }
3840
0
    if (xx < (-FLT_MAX)) {
3841
0
#ifdef ERANGE_FILL
3842
0
        *ip = NC_FILL_FLOAT;
3843
#else
3844
        *ip = (-FLT_MAX);
3845
#endif
3846
0
        return NC_ERANGE;
3847
0
    }
3848
0
    *ip = (float) xx;
3849
0
    return NC_NOERR;
3850
0
}
3851
3852
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
3853
static int
3854
ncx_get_double_double(const void *xp, double *ip, void *fillp)
3855
{
3856
  /* TODO */
3857
  get_ix_double(xp, ip);
3858
  return NC_NOERR;
3859
}
3860
#endif
3861
3862
static int
3863
ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
3864
0
{
3865
0
    int err=NC_NOERR;
3866
0
    ix_double xx = NC_FILL_DOUBLE;
3867
3868
    
3869
0
        xx = (ix_double)*ip;
3870
3871
0
    put_ix_double(xp, &xx);
3872
0
    return err;
3873
0
}
3874
3875
static int
3876
ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
3877
0
{
3878
0
    int err=NC_NOERR;
3879
0
    ix_double xx = NC_FILL_DOUBLE;
3880
3881
    
3882
0
        xx = (ix_double)*ip;
3883
3884
0
    put_ix_double(xp, &xx);
3885
0
    return err;
3886
0
}
3887
3888
static int
3889
ncx_put_double_short(void *xp, const short *ip, void *fillp)
3890
0
{
3891
0
    int err=NC_NOERR;
3892
0
    ix_double xx = NC_FILL_DOUBLE;
3893
3894
    
3895
0
        xx = (ix_double)*ip;
3896
3897
0
    put_ix_double(xp, &xx);
3898
0
    return err;
3899
0
}
3900
3901
static int
3902
ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
3903
0
{
3904
0
    int err=NC_NOERR;
3905
0
    ix_double xx = NC_FILL_DOUBLE;
3906
3907
    
3908
0
        xx = (ix_double)*ip;
3909
3910
0
    put_ix_double(xp, &xx);
3911
0
    return err;
3912
0
}
3913
3914
static int
3915
ncx_put_double_int(void *xp, const int *ip, void *fillp)
3916
0
{
3917
0
    int err=NC_NOERR;
3918
0
    ix_double xx = NC_FILL_DOUBLE;
3919
3920
    
3921
0
        xx = (ix_double)*ip;
3922
3923
0
    put_ix_double(xp, &xx);
3924
0
    return err;
3925
0
}
3926
3927
static int
3928
ncx_put_double_long(void *xp, const long *ip, void *fillp)
3929
0
{
3930
0
    int err=NC_NOERR;
3931
0
    ix_double xx = NC_FILL_DOUBLE;
3932
3933
    
3934
0
        xx = (ix_double)*ip;
3935
3936
0
    put_ix_double(xp, &xx);
3937
0
    return err;
3938
0
}
3939
3940
static int
3941
ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
3942
0
{
3943
0
    int err=NC_NOERR;
3944
0
    ix_double xx = NC_FILL_DOUBLE;
3945
3946
    
3947
0
        xx = (ix_double)*ip;
3948
3949
0
    put_ix_double(xp, &xx);
3950
0
    return err;
3951
0
}
3952
3953
static int
3954
ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
3955
0
{
3956
0
    int err=NC_NOERR;
3957
0
    ix_double xx = NC_FILL_DOUBLE;
3958
3959
    
3960
0
        xx = (ix_double)*ip;
3961
3962
0
    put_ix_double(xp, &xx);
3963
0
    return err;
3964
0
}
3965
3966
static int
3967
ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3968
0
{
3969
0
    int err=NC_NOERR;
3970
0
    ix_double xx = NC_FILL_DOUBLE;
3971
3972
    
3973
0
        xx = (ix_double)*ip;
3974
3975
0
    put_ix_double(xp, &xx);
3976
0
    return err;
3977
0
}
3978
3979
3980
static int
3981
ncx_put_double_float(void *xp, const float *ip, void *fillp)
3982
0
{
3983
0
    int err=NC_NOERR;
3984
0
    double xx = NC_FILL_DOUBLE;
3985
0
#if 1 /* TODO: figure this out (if condition below will never be true)*/
3986
0
    if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
3987
        
3988
0
#ifdef ERANGE_FILL
3989
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
3990
0
#endif
3991
0
        err = NC_ERANGE;
3992
0
    }
3993
0
#ifdef ERANGE_FILL
3994
0
    else
3995
0
#endif
3996
0
#endif
3997
0
        xx = (double) *ip;
3998
3999
0
    put_ix_double(xp, &xx);
4000
0
    return err;
4001
0
}
4002
4003
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4004
static int
4005
ncx_put_double_double(void *xp, const double *ip, void *fillp)
4006
{
4007
    int err=NC_NOERR;
4008
    double *_ip = ip;
4009
#ifdef NO_IEEE_FLOAT
4010
#ifdef ERANGE_FILL
4011
    double tmp=NC_FILL_DOUBLE;
4012
#endif
4013
    if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
4014
        
4015
#ifdef ERANGE_FILL
4016
            if (fillp != NULL) memcpy(&tmp, fillp, 8);
4017
#endif
4018
#ifdef ERANGE_FILL
4019
        _ip = &tmp;
4020
#endif
4021
        err = NC_ERANGE;
4022
    }
4023
#endif
4024
    put_ix_double(xp, _ip);
4025
    return err;
4026
}
4027
#endif
4028
4029
4030
/* external NC_INT64 --------------------------------------------------------*/
4031
4032
#if SHORT_MAX == X_INT64_MAX
4033
typedef short ix_int64;
4034
#define SIZEOF_IX_INT64 SIZEOF_SHORT
4035
#define IX_INT64_MAX SHORT_MAX
4036
#elif LONG_LONG_MAX  >= X_INT64_MAX
4037
typedef longlong ix_int64;
4038
#define SIZEOF_IX_INT64 SIZEOF_LONGLONG
4039
0
#define IX_INT64_MAX LONG_LONG_MAX
4040
#elif LONG_MAX  >= X_INT64_MAX
4041
typedef long ix_int64;
4042
#define SIZEOF_IX_INT64 SIZEOF_LONG
4043
#define IX_INT64_MAX LONG_MAX
4044
#else
4045
#error "ix_int64 implementation"
4046
#endif
4047
4048
4049
static void
4050
get_ix_int64(const void *xp, ix_int64 *ip)
4051
0
{
4052
0
    const uchar *cp = (const uchar *) xp;
4053
4054
0
    *ip  = (ix_int64)((uint64_t)(*cp++) << 56);
4055
0
    *ip |= (ix_int64)((uint64_t)(*cp++) << 48);
4056
0
    *ip |= (ix_int64)((uint64_t)(*cp++) << 40);
4057
0
    *ip |= (ix_int64)((uint64_t)(*cp++) << 32);
4058
0
    *ip |= (ix_int64)((uint64_t)(*cp++) << 24);
4059
0
    *ip |= (ix_int64)((uint64_t)(*cp++) << 16);
4060
0
    *ip |= (ix_int64)((uint64_t)(*cp++) <<  8);
4061
0
    *ip |= (ix_int64)*cp;
4062
0
}
4063
4064
static void
4065
put_ix_int64(void *xp, const ix_int64 *ip)
4066
0
{
4067
0
    uchar *cp = (uchar *) xp;
4068
4069
0
    *cp++ = (uchar)((*ip) >> 56);
4070
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48);
4071
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40);
4072
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32);
4073
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24);
4074
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16);
4075
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >>  8);
4076
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffLL);
4077
0
}
4078
4079
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4080
static int
4081
ncx_get_longlong_longlong(const void *xp, longlong *ip)
4082
{
4083
    int err=NC_NOERR;
4084
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4085
    get_ix_int64(xp, (ix_int64 *)ip);
4086
#else
4087
    ix_int64 xx = 0;
4088
    get_ix_int64(xp, &xx);
4089
4090
#if IX_INT64_MAX > LONGLONG_MAX
4091
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
4092
#ifdef ERANGE_FILL
4093
        *ip = NC_FILL_INT64;
4094
        return NC_ERANGE;
4095
#else
4096
        err = NC_ERANGE;
4097
#endif
4098
    }
4099
#endif
4100
4101
4102
    *ip = (longlong) xx;
4103
#endif
4104
    return err;
4105
}
4106
4107
#endif
4108
static int
4109
ncx_get_longlong_schar(const void *xp, schar *ip)
4110
0
{
4111
0
    int err=NC_NOERR;
4112
0
    ix_int64 xx = 0;
4113
0
    get_ix_int64(xp, &xx);
4114
4115
0
#if IX_INT64_MAX > SCHAR_MAX
4116
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
4117
0
#ifdef ERANGE_FILL
4118
0
        *ip = NC_FILL_BYTE;
4119
0
        return NC_ERANGE;
4120
#else
4121
        err = NC_ERANGE;
4122
#endif
4123
0
    }
4124
0
#endif
4125
4126
4127
0
    *ip = (schar) xx;
4128
0
    return err;
4129
0
}
4130
4131
static int
4132
ncx_get_longlong_short(const void *xp, short *ip)
4133
0
{
4134
0
    int err=NC_NOERR;
4135
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4136
    get_ix_int64(xp, (ix_int64 *)ip);
4137
#else
4138
0
    ix_int64 xx = 0;
4139
0
    get_ix_int64(xp, &xx);
4140
4141
0
#if IX_INT64_MAX > SHORT_MAX
4142
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
4143
0
#ifdef ERANGE_FILL
4144
0
        *ip = NC_FILL_SHORT;
4145
0
        return NC_ERANGE;
4146
#else
4147
        err = NC_ERANGE;
4148
#endif
4149
0
    }
4150
0
#endif
4151
4152
4153
0
    *ip = (short) xx;
4154
0
#endif
4155
0
    return err;
4156
0
}
4157
4158
static int
4159
ncx_get_longlong_int(const void *xp, int *ip)
4160
0
{
4161
0
    int err=NC_NOERR;
4162
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4163
    get_ix_int64(xp, (ix_int64 *)ip);
4164
#else
4165
0
    ix_int64 xx = 0;
4166
0
    get_ix_int64(xp, &xx);
4167
4168
0
#if IX_INT64_MAX > INT_MAX
4169
0
    if (xx > INT_MAX || xx < INT_MIN) {
4170
0
#ifdef ERANGE_FILL
4171
0
        *ip = NC_FILL_INT;
4172
0
        return NC_ERANGE;
4173
#else
4174
        err = NC_ERANGE;
4175
#endif
4176
0
    }
4177
0
#endif
4178
4179
4180
0
    *ip = (int) xx;
4181
0
#endif
4182
0
    return err;
4183
0
}
4184
4185
static int
4186
ncx_get_longlong_long(const void *xp, long *ip)
4187
0
{
4188
0
    int err=NC_NOERR;
4189
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4190
0
    get_ix_int64(xp, (ix_int64 *)ip);
4191
#else
4192
    ix_int64 xx = 0;
4193
    get_ix_int64(xp, &xx);
4194
4195
#if IX_INT64_MAX > LONG_MAX
4196
    if (xx > LONG_MAX || xx < LONG_MIN) {
4197
#ifdef ERANGE_FILL
4198
        *ip = NC_FILL_INT;
4199
        return NC_ERANGE;
4200
#else
4201
        err = NC_ERANGE;
4202
#endif
4203
    }
4204
#endif
4205
4206
4207
    *ip = (long) xx;
4208
#endif
4209
0
    return err;
4210
0
}
4211
4212
static int
4213
ncx_get_longlong_ushort(const void *xp, ushort *ip)
4214
0
{
4215
0
    int err=NC_NOERR;
4216
0
    ix_int64 xx = 0;
4217
0
    get_ix_int64(xp, &xx);
4218
4219
0
#if IX_INT64_MAX > USHORT_MAX
4220
0
    if (xx > USHORT_MAX) {
4221
0
#ifdef ERANGE_FILL
4222
0
        *ip = NC_FILL_USHORT;
4223
0
        return NC_ERANGE;
4224
#else
4225
        err = NC_ERANGE;
4226
#endif
4227
0
    }
4228
0
#endif
4229
4230
0
    if (xx < 0) {
4231
0
#ifdef ERANGE_FILL
4232
0
        *ip = NC_FILL_USHORT;
4233
0
        return NC_ERANGE;
4234
#else
4235
        err = NC_ERANGE; /* because ip is unsigned */
4236
#endif
4237
0
    }
4238
0
    *ip = (ushort) xx;
4239
0
    return err;
4240
0
}
4241
4242
static int
4243
ncx_get_longlong_uchar(const void *xp, uchar *ip)
4244
0
{
4245
0
    int err=NC_NOERR;
4246
0
    ix_int64 xx = 0;
4247
0
    get_ix_int64(xp, &xx);
4248
4249
0
#if IX_INT64_MAX > UCHAR_MAX
4250
0
    if (xx > UCHAR_MAX) {
4251
0
#ifdef ERANGE_FILL
4252
0
        *ip = NC_FILL_UBYTE;
4253
0
        return NC_ERANGE;
4254
#else
4255
        err = NC_ERANGE;
4256
#endif
4257
0
    }
4258
0
#endif
4259
4260
0
    if (xx < 0) {
4261
0
#ifdef ERANGE_FILL
4262
0
        *ip = NC_FILL_UBYTE;
4263
0
        return NC_ERANGE;
4264
#else
4265
        err = NC_ERANGE; /* because ip is unsigned */
4266
#endif
4267
0
    }
4268
0
    *ip = (uchar) xx;
4269
0
    return err;
4270
0
}
4271
4272
static int
4273
ncx_get_longlong_uint(const void *xp, uint *ip)
4274
0
{
4275
0
    int err=NC_NOERR;
4276
0
    ix_int64 xx = 0;
4277
0
    get_ix_int64(xp, &xx);
4278
4279
0
#if IX_INT64_MAX > UINT_MAX
4280
0
    if (xx > UINT_MAX) {
4281
0
#ifdef ERANGE_FILL
4282
0
        *ip = NC_FILL_UINT;
4283
0
        return NC_ERANGE;
4284
#else
4285
        err = NC_ERANGE;
4286
#endif
4287
0
    }
4288
0
#endif
4289
4290
0
    if (xx < 0) {
4291
0
#ifdef ERANGE_FILL
4292
0
        *ip = NC_FILL_UINT;
4293
0
        return NC_ERANGE;
4294
#else
4295
        err = NC_ERANGE; /* because ip is unsigned */
4296
#endif
4297
0
    }
4298
0
    *ip = (uint) xx;
4299
0
    return err;
4300
0
}
4301
4302
static int
4303
ncx_get_longlong_ulonglong(const void *xp, ulonglong *ip)
4304
0
{
4305
0
    int err=NC_NOERR;
4306
0
    ix_int64 xx = 0;
4307
0
    get_ix_int64(xp, &xx);
4308
4309
#if IX_INT64_MAX > ULONGLONG_MAX
4310
    if (xx > ULONGLONG_MAX) {
4311
#ifdef ERANGE_FILL
4312
        *ip = NC_FILL_UINT64;
4313
        return NC_ERANGE;
4314
#else
4315
        err = NC_ERANGE;
4316
#endif
4317
    }
4318
#endif
4319
4320
0
    if (xx < 0) {
4321
0
#ifdef ERANGE_FILL
4322
0
        *ip = NC_FILL_UINT64;
4323
0
        return NC_ERANGE;
4324
#else
4325
        err = NC_ERANGE; /* because ip is unsigned */
4326
#endif
4327
0
    }
4328
0
    *ip = (ulonglong) xx;
4329
0
    return err;
4330
0
}
4331
4332
static int
4333
ncx_get_longlong_float(const void *xp, float *ip)
4334
0
{
4335
0
  ix_int64 xx = 0;
4336
0
  get_ix_int64(xp, &xx);
4337
0
  *ip = (float)xx;
4338
0
  return NC_NOERR;
4339
0
}
4340
4341
static int
4342
ncx_get_longlong_double(const void *xp, double *ip)
4343
0
{
4344
0
  ix_int64 xx = 0;
4345
0
  get_ix_int64(xp, &xx);
4346
0
  *ip = (double)xx;
4347
0
  return NC_NOERR;
4348
0
}
4349
4350
4351
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4352
static int
4353
ncx_put_longlong_longlong(void *xp, const longlong *ip, void *fillp)
4354
{
4355
    int err=NC_NOERR;
4356
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4357
    put_ix_int64(xp, (const ix_int64 *)ip);
4358
#else
4359
    ix_int64 xx = NC_FILL_INT64;
4360
4361
#if IX_INT64_MAX < LONGLONG_MAX
4362
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4363
        
4364
#ifdef ERANGE_FILL
4365
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4366
#endif
4367
        err = NC_ERANGE;
4368
    }
4369
#ifdef ERANGE_FILL
4370
    else
4371
#endif
4372
#endif
4373
        xx = (ix_int64)*ip;
4374
4375
    put_ix_int64(xp, &xx);
4376
#endif
4377
    return err;
4378
}
4379
4380
#endif
4381
static int
4382
ncx_put_longlong_schar(void *xp, const schar *ip, void *fillp)
4383
0
{
4384
0
    int err=NC_NOERR;
4385
0
    ix_int64 xx = NC_FILL_INT64;
4386
4387
#if IX_INT64_MAX < SCHAR_MAX
4388
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4389
        
4390
#ifdef ERANGE_FILL
4391
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4392
#endif
4393
        err = NC_ERANGE;
4394
    }
4395
#ifdef ERANGE_FILL
4396
    else
4397
#endif
4398
#endif
4399
0
        xx = (ix_int64)*ip;
4400
4401
0
    put_ix_int64(xp, &xx);
4402
0
    return err;
4403
0
}
4404
4405
static int
4406
ncx_put_longlong_short(void *xp, const short *ip, void *fillp)
4407
0
{
4408
0
    int err=NC_NOERR;
4409
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4410
    put_ix_int64(xp, (const ix_int64 *)ip);
4411
#else
4412
0
    ix_int64 xx = NC_FILL_INT64;
4413
4414
#if IX_INT64_MAX < SHORT_MAX
4415
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4416
        
4417
#ifdef ERANGE_FILL
4418
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4419
#endif
4420
        err = NC_ERANGE;
4421
    }
4422
#ifdef ERANGE_FILL
4423
    else
4424
#endif
4425
#endif
4426
0
        xx = (ix_int64)*ip;
4427
4428
0
    put_ix_int64(xp, &xx);
4429
0
#endif
4430
0
    return err;
4431
0
}
4432
4433
static int
4434
ncx_put_longlong_int(void *xp, const int *ip, void *fillp)
4435
0
{
4436
0
    int err=NC_NOERR;
4437
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4438
    put_ix_int64(xp, (const ix_int64 *)ip);
4439
#else
4440
0
    ix_int64 xx = NC_FILL_INT64;
4441
4442
#if IX_INT64_MAX < INT_MAX
4443
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4444
        
4445
#ifdef ERANGE_FILL
4446
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4447
#endif
4448
        err = NC_ERANGE;
4449
    }
4450
#ifdef ERANGE_FILL
4451
    else
4452
#endif
4453
#endif
4454
0
        xx = (ix_int64)*ip;
4455
4456
0
    put_ix_int64(xp, &xx);
4457
0
#endif
4458
0
    return err;
4459
0
}
4460
4461
static int
4462
ncx_put_longlong_long(void *xp, const long *ip, void *fillp)
4463
0
{
4464
0
    int err=NC_NOERR;
4465
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4466
0
    put_ix_int64(xp, (const ix_int64 *)ip);
4467
#else
4468
    ix_int64 xx = NC_FILL_INT64;
4469
4470
#if IX_INT64_MAX < LONG_MAX
4471
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4472
        
4473
#ifdef ERANGE_FILL
4474
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4475
#endif
4476
        err = NC_ERANGE;
4477
    }
4478
#ifdef ERANGE_FILL
4479
    else
4480
#endif
4481
#endif
4482
        xx = (ix_int64)*ip;
4483
4484
    put_ix_int64(xp, &xx);
4485
#endif
4486
0
    return err;
4487
0
}
4488
4489
static int
4490
ncx_put_longlong_ushort(void *xp, const ushort *ip, void *fillp)
4491
0
{
4492
0
    int err=NC_NOERR;
4493
0
    ix_int64 xx = NC_FILL_INT64;
4494
4495
#if IX_INT64_MAX < USHORT_MAX
4496
    if (*ip > IX_INT64_MAX) {
4497
        
4498
#ifdef ERANGE_FILL
4499
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4500
#endif
4501
        err = NC_ERANGE;
4502
    }
4503
#ifdef ERANGE_FILL
4504
    else
4505
#endif
4506
#endif
4507
0
        xx = (ix_int64)*ip;
4508
4509
0
    put_ix_int64(xp, &xx);
4510
0
    return err;
4511
0
}
4512
4513
static int
4514
ncx_put_longlong_uchar(void *xp, const uchar *ip, void *fillp)
4515
0
{
4516
0
    int err=NC_NOERR;
4517
0
    ix_int64 xx = NC_FILL_INT64;
4518
4519
#if IX_INT64_MAX < UCHAR_MAX
4520
    if (*ip > IX_INT64_MAX) {
4521
        
4522
#ifdef ERANGE_FILL
4523
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4524
#endif
4525
        err = NC_ERANGE;
4526
    }
4527
#ifdef ERANGE_FILL
4528
    else
4529
#endif
4530
#endif
4531
0
        xx = (ix_int64)*ip;
4532
4533
0
    put_ix_int64(xp, &xx);
4534
0
    return err;
4535
0
}
4536
4537
static int
4538
ncx_put_longlong_uint(void *xp, const uint *ip, void *fillp)
4539
0
{
4540
0
    int err=NC_NOERR;
4541
0
    ix_int64 xx = NC_FILL_INT64;
4542
4543
#if IX_INT64_MAX < UINT_MAX
4544
    if (*ip > IX_INT64_MAX) {
4545
        
4546
#ifdef ERANGE_FILL
4547
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4548
#endif
4549
        err = NC_ERANGE;
4550
    }
4551
#ifdef ERANGE_FILL
4552
    else
4553
#endif
4554
#endif
4555
0
        xx = (ix_int64)*ip;
4556
4557
0
    put_ix_int64(xp, &xx);
4558
0
    return err;
4559
0
}
4560
4561
static int
4562
ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4563
0
{
4564
0
    int err=NC_NOERR;
4565
0
    ix_int64 xx = NC_FILL_INT64;
4566
4567
0
#if IX_INT64_MAX < ULONGLONG_MAX
4568
0
    if (*ip > IX_INT64_MAX) {
4569
        
4570
0
#ifdef ERANGE_FILL
4571
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4572
0
#endif
4573
0
        err = NC_ERANGE;
4574
0
    }
4575
0
#ifdef ERANGE_FILL
4576
0
    else
4577
0
#endif
4578
0
#endif
4579
0
        xx = (ix_int64)*ip;
4580
4581
0
    put_ix_int64(xp, &xx);
4582
0
    return err;
4583
0
}
4584
4585
static int
4586
ncx_put_longlong_float(void *xp, const float *ip, void *fillp)
4587
0
{
4588
0
    int err=NC_NOERR;
4589
0
    ix_int64 xx = NC_FILL_INT64;
4590
4591
0
    if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
4592
        
4593
0
#ifdef ERANGE_FILL
4594
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4595
0
#endif
4596
0
        err = NC_ERANGE;
4597
0
    }
4598
0
#ifdef ERANGE_FILL
4599
0
    else
4600
0
#endif
4601
0
        xx = (ix_int64)*ip;
4602
4603
0
    put_ix_int64(xp, &xx);
4604
0
    return err;
4605
0
}
4606
4607
static int
4608
ncx_put_longlong_double(void *xp, const double *ip, void *fillp)
4609
0
{
4610
0
    int err=NC_NOERR;
4611
0
    ix_int64 xx = NC_FILL_INT64;
4612
4613
0
    if (*ip > X_INT64_MAX || *ip < X_INT64_MIN) {
4614
        
4615
0
#ifdef ERANGE_FILL
4616
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4617
0
#endif
4618
0
        err = NC_ERANGE;
4619
0
    }
4620
0
#ifdef ERANGE_FILL
4621
0
    else
4622
0
#endif
4623
0
        xx = (ix_int64)*ip;
4624
4625
0
    put_ix_int64(xp, &xx);
4626
0
    return err;
4627
0
}
4628
4629
4630
4631
/* external NC_UINT64 -------------------------------------------------------*/
4632
4633
#if USHORT_MAX == X_UINT64_MAX
4634
typedef ushort ix_uint64;
4635
#define SIZEOF_IX_UINT64 SIZEOF_USHORT
4636
#define IX_UINT64_MAX USHORT_MAX
4637
#elif ULONG_LONG_MAX  >= X_UINT64_MAX
4638
typedef ulonglong ix_uint64;
4639
#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
4640
#define IX_UINT64_MAX ULONG_LONG_MAX
4641
#elif ULONG_MAX  >= X_UINT64_MAX
4642
typedef ulong ix_uint64;
4643
#define SIZEOF_IX_UINT64 SIZEOF_ULONG
4644
#define IX_UINT64_MAX ULONG_MAX
4645
#else
4646
#error "ix_uint64 implementation"
4647
#endif
4648
4649
4650
static void
4651
get_ix_uint64(const void *xp, ix_uint64 *ip)
4652
0
{
4653
0
    const uchar *cp = (const uchar *) xp;
4654
4655
0
    *ip  = ((ix_uint64)(*cp++) << 56);
4656
0
    *ip |= ((ix_uint64)(*cp++) << 48);
4657
0
    *ip |= ((ix_uint64)(*cp++) << 40);
4658
0
    *ip |= ((ix_uint64)(*cp++) << 32);
4659
0
    *ip |= ((ix_uint64)(*cp++) << 24);
4660
0
    *ip |= ((ix_uint64)(*cp++) << 16);
4661
0
    *ip |= ((ix_uint64)(*cp++) <<  8);
4662
0
    *ip |=  (ix_uint64)*cp;
4663
0
}
4664
4665
static void
4666
put_ix_uint64(void *xp, const ix_uint64 *ip)
4667
0
{
4668
0
    uchar *cp = (uchar *) xp;
4669
4670
0
    *cp++ = (uchar)((*ip) >> 56);
4671
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48);
4672
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40);
4673
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32);
4674
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24);
4675
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16);
4676
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >>  8);
4677
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffULL);
4678
0
}
4679
4680
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4681
static int
4682
ncx_get_ulonglong_ulonglong(const void *xp, ulonglong *ip)
4683
{
4684
    int err=NC_NOERR;
4685
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4686
    get_ix_uint64(xp, (ix_uint64 *)ip);
4687
#else
4688
    ix_uint64 xx = 0;
4689
    get_ix_uint64(xp, &xx);
4690
4691
#if IX_UINT64_MAX > ULONGLONG_MAX
4692
    if (xx > ULONGLONG_MAX) {
4693
#ifdef ERANGE_FILL
4694
        *ip = NC_FILL_UINT64;
4695
        return NC_ERANGE;
4696
#else
4697
        err = NC_ERANGE;
4698
#endif
4699
    }
4700
#endif
4701
4702
4703
    *ip = (ulonglong) xx;
4704
#endif
4705
    return err;
4706
}
4707
4708
#endif
4709
static int
4710
ncx_get_ulonglong_schar(const void *xp, schar *ip)
4711
0
{
4712
0
    int err=NC_NOERR;
4713
0
    ix_uint64 xx = 0;
4714
0
    get_ix_uint64(xp, &xx);
4715
4716
0
#if IX_UINT64_MAX > SCHAR_MAX
4717
0
    if (xx > SCHAR_MAX) {
4718
0
#ifdef ERANGE_FILL
4719
0
        *ip = NC_FILL_BYTE;
4720
0
        return NC_ERANGE;
4721
#else
4722
        err = NC_ERANGE;
4723
#endif
4724
0
    }
4725
0
#endif
4726
4727
4728
0
    *ip = (schar) xx;
4729
0
    return err;
4730
0
}
4731
4732
static int
4733
ncx_get_ulonglong_short(const void *xp, short *ip)
4734
0
{
4735
0
    int err=NC_NOERR;
4736
0
    ix_uint64 xx = 0;
4737
0
    get_ix_uint64(xp, &xx);
4738
4739
0
#if IX_UINT64_MAX > SHORT_MAX
4740
0
    if (xx > SHORT_MAX) {
4741
0
#ifdef ERANGE_FILL
4742
0
        *ip = NC_FILL_SHORT;
4743
0
        return NC_ERANGE;
4744
#else
4745
        err = NC_ERANGE;
4746
#endif
4747
0
    }
4748
0
#endif
4749
4750
4751
0
    *ip = (short) xx;
4752
0
    return err;
4753
0
}
4754
4755
static int
4756
ncx_get_ulonglong_int(const void *xp, int *ip)
4757
0
{
4758
0
    int err=NC_NOERR;
4759
0
    ix_uint64 xx = 0;
4760
0
    get_ix_uint64(xp, &xx);
4761
4762
0
#if IX_UINT64_MAX > INT_MAX
4763
0
    if (xx > INT_MAX) {
4764
0
#ifdef ERANGE_FILL
4765
0
        *ip = NC_FILL_INT;
4766
0
        return NC_ERANGE;
4767
#else
4768
        err = NC_ERANGE;
4769
#endif
4770
0
    }
4771
0
#endif
4772
4773
4774
0
    *ip = (int) xx;
4775
0
    return err;
4776
0
}
4777
4778
static int
4779
ncx_get_ulonglong_long(const void *xp, long *ip)
4780
0
{
4781
0
    int err=NC_NOERR;
4782
0
    ix_uint64 xx = 0;
4783
0
    get_ix_uint64(xp, &xx);
4784
4785
0
#if IX_UINT64_MAX > LONG_MAX
4786
0
    if (xx > LONG_MAX) {
4787
0
#ifdef ERANGE_FILL
4788
0
        *ip = NC_FILL_INT;
4789
0
        return NC_ERANGE;
4790
#else
4791
        err = NC_ERANGE;
4792
#endif
4793
0
    }
4794
0
#endif
4795
4796
4797
0
    *ip = (long) xx;
4798
0
    return err;
4799
0
}
4800
4801
static int
4802
ncx_get_ulonglong_longlong(const void *xp, longlong *ip)
4803
0
{
4804
0
    int err=NC_NOERR;
4805
0
    ix_uint64 xx = 0;
4806
0
    get_ix_uint64(xp, &xx);
4807
4808
0
#if IX_UINT64_MAX > LONGLONG_MAX
4809
0
    if (xx > LONGLONG_MAX) {
4810
0
#ifdef ERANGE_FILL
4811
0
        *ip = NC_FILL_INT64;
4812
0
        return NC_ERANGE;
4813
#else
4814
        err = NC_ERANGE;
4815
#endif
4816
0
    }
4817
0
#endif
4818
4819
4820
0
    *ip = (longlong) xx;
4821
0
    return err;
4822
0
}
4823
4824
static int
4825
ncx_get_ulonglong_ushort(const void *xp, ushort *ip)
4826
0
{
4827
0
    int err=NC_NOERR;
4828
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
4829
    get_ix_uint64(xp, (ix_uint64 *)ip);
4830
#else
4831
0
    ix_uint64 xx = 0;
4832
0
    get_ix_uint64(xp, &xx);
4833
4834
0
#if IX_UINT64_MAX > USHORT_MAX
4835
0
    if (xx > USHORT_MAX) {
4836
0
#ifdef ERANGE_FILL
4837
0
        *ip = NC_FILL_USHORT;
4838
0
        return NC_ERANGE;
4839
#else
4840
        err = NC_ERANGE;
4841
#endif
4842
0
    }
4843
0
#endif
4844
4845
4846
0
    *ip = (ushort) xx;
4847
0
#endif
4848
0
    return err;
4849
0
}
4850
4851
static int
4852
ncx_get_ulonglong_uchar(const void *xp, uchar *ip)
4853
0
{
4854
0
    int err=NC_NOERR;
4855
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
4856
    get_ix_uint64(xp, (ix_uint64 *)ip);
4857
#else
4858
0
    ix_uint64 xx = 0;
4859
0
    get_ix_uint64(xp, &xx);
4860
4861
0
#if IX_UINT64_MAX > UCHAR_MAX
4862
0
    if (xx > UCHAR_MAX) {
4863
0
#ifdef ERANGE_FILL
4864
0
        *ip = NC_FILL_UBYTE;
4865
0
        return NC_ERANGE;
4866
#else
4867
        err = NC_ERANGE;
4868
#endif
4869
0
    }
4870
0
#endif
4871
4872
4873
0
    *ip = (uchar) xx;
4874
0
#endif
4875
0
    return err;
4876
0
}
4877
4878
static int
4879
ncx_get_ulonglong_uint(const void *xp, uint *ip)
4880
0
{
4881
0
    int err=NC_NOERR;
4882
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
4883
    get_ix_uint64(xp, (ix_uint64 *)ip);
4884
#else
4885
0
    ix_uint64 xx = 0;
4886
0
    get_ix_uint64(xp, &xx);
4887
4888
0
#if IX_UINT64_MAX > UINT_MAX
4889
0
    if (xx > UINT_MAX) {
4890
0
#ifdef ERANGE_FILL
4891
0
        *ip = NC_FILL_UINT;
4892
0
        return NC_ERANGE;
4893
#else
4894
        err = NC_ERANGE;
4895
#endif
4896
0
    }
4897
0
#endif
4898
4899
4900
0
    *ip = (uint) xx;
4901
0
#endif
4902
0
    return err;
4903
0
}
4904
4905
static int
4906
ncx_get_ulonglong_float(const void *xp, float *ip)
4907
0
{
4908
0
  ix_uint64 xx = 0;
4909
0
  get_ix_uint64(xp, &xx);
4910
0
  *ip = (float)xx;
4911
0
  return NC_NOERR;
4912
0
}
4913
4914
static int
4915
ncx_get_ulonglong_double(const void *xp, double *ip)
4916
0
{
4917
0
  ix_uint64 xx = 0;
4918
0
  get_ix_uint64(xp, &xx);
4919
0
  *ip = (double)xx;
4920
0
  return NC_NOERR;
4921
0
}
4922
4923
4924
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4925
static int
4926
ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4927
{
4928
    int err=NC_NOERR;
4929
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4930
    put_ix_uint64(xp, (const ix_uint64 *)ip);
4931
#else
4932
    ix_uint64 xx = NC_FILL_UINT64;
4933
4934
#if IX_UINT64_MAX < ULONGLONG_MAX
4935
    if (*ip > IX_UINT64_MAX) {
4936
        
4937
#ifdef ERANGE_FILL
4938
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4939
#endif
4940
        err = NC_ERANGE;
4941
    }
4942
#ifdef ERANGE_FILL
4943
    else
4944
#endif
4945
#endif
4946
        xx = (ix_uint64)*ip;
4947
4948
    put_ix_uint64(xp, &xx);
4949
#endif
4950
    return err;
4951
}
4952
4953
#endif
4954
static int
4955
ncx_put_ulonglong_schar(void *xp, const schar *ip, void *fillp)
4956
0
{
4957
0
    int err=NC_NOERR;
4958
0
    ix_uint64 xx = NC_FILL_UINT64;
4959
4960
#if IX_UINT64_MAX < SCHAR_MAX
4961
    if (*ip > IX_UINT64_MAX) {
4962
        
4963
#ifdef ERANGE_FILL
4964
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4965
#endif
4966
        err = NC_ERANGE;
4967
    }
4968
#ifdef ERANGE_FILL
4969
    else
4970
#endif
4971
#endif
4972
0
    if (*ip < 0) {
4973
        
4974
0
#ifdef ERANGE_FILL
4975
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4976
0
#endif
4977
0
        err = NC_ERANGE; /* because xp is unsigned */
4978
0
    }
4979
0
#ifdef ERANGE_FILL
4980
0
    else
4981
0
#endif
4982
0
        xx = (ix_uint64)*ip;
4983
4984
0
    put_ix_uint64(xp, &xx);
4985
0
    return err;
4986
0
}
4987
4988
static int
4989
ncx_put_ulonglong_short(void *xp, const short *ip, void *fillp)
4990
0
{
4991
0
    int err=NC_NOERR;
4992
0
    ix_uint64 xx = NC_FILL_UINT64;
4993
4994
#if IX_UINT64_MAX < SHORT_MAX
4995
    if (*ip > IX_UINT64_MAX) {
4996
        
4997
#ifdef ERANGE_FILL
4998
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4999
#endif
5000
        err = NC_ERANGE;
5001
    }
5002
#ifdef ERANGE_FILL
5003
    else
5004
#endif
5005
#endif
5006
0
    if (*ip < 0) {
5007
        
5008
0
#ifdef ERANGE_FILL
5009
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5010
0
#endif
5011
0
        err = NC_ERANGE; /* because xp is unsigned */
5012
0
    }
5013
0
#ifdef ERANGE_FILL
5014
0
    else
5015
0
#endif
5016
0
        xx = (ix_uint64)*ip;
5017
5018
0
    put_ix_uint64(xp, &xx);
5019
0
    return err;
5020
0
}
5021
5022
static int
5023
ncx_put_ulonglong_int(void *xp, const int *ip, void *fillp)
5024
0
{
5025
0
    int err=NC_NOERR;
5026
0
    ix_uint64 xx = NC_FILL_UINT64;
5027
5028
#if IX_UINT64_MAX < INT_MAX
5029
    if (*ip > IX_UINT64_MAX) {
5030
        
5031
#ifdef ERANGE_FILL
5032
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5033
#endif
5034
        err = NC_ERANGE;
5035
    }
5036
#ifdef ERANGE_FILL
5037
    else
5038
#endif
5039
#endif
5040
0
    if (*ip < 0) {
5041
        
5042
0
#ifdef ERANGE_FILL
5043
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5044
0
#endif
5045
0
        err = NC_ERANGE; /* because xp is unsigned */
5046
0
    }
5047
0
#ifdef ERANGE_FILL
5048
0
    else
5049
0
#endif
5050
0
        xx = (ix_uint64)*ip;
5051
5052
0
    put_ix_uint64(xp, &xx);
5053
0
    return err;
5054
0
}
5055
5056
static int
5057
ncx_put_ulonglong_long(void *xp, const long *ip, void *fillp)
5058
0
{
5059
0
    int err=NC_NOERR;
5060
0
    ix_uint64 xx = NC_FILL_UINT64;
5061
5062
#if IX_UINT64_MAX < LONG_MAX
5063
    if (*ip > IX_UINT64_MAX) {
5064
        
5065
#ifdef ERANGE_FILL
5066
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5067
#endif
5068
        err = NC_ERANGE;
5069
    }
5070
#ifdef ERANGE_FILL
5071
    else
5072
#endif
5073
#endif
5074
0
    if (*ip < 0) {
5075
        
5076
0
#ifdef ERANGE_FILL
5077
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5078
0
#endif
5079
0
        err = NC_ERANGE; /* because xp is unsigned */
5080
0
    }
5081
0
#ifdef ERANGE_FILL
5082
0
    else
5083
0
#endif
5084
0
        xx = (ix_uint64)*ip;
5085
5086
0
    put_ix_uint64(xp, &xx);
5087
0
    return err;
5088
0
}
5089
5090
static int
5091
ncx_put_ulonglong_longlong(void *xp, const longlong *ip, void *fillp)
5092
0
{
5093
0
    int err=NC_NOERR;
5094
0
    ix_uint64 xx = NC_FILL_UINT64;
5095
5096
#if IX_UINT64_MAX < LONGLONG_MAX
5097
    if (*ip > IX_UINT64_MAX) {
5098
        
5099
#ifdef ERANGE_FILL
5100
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5101
#endif
5102
        err = NC_ERANGE;
5103
    }
5104
#ifdef ERANGE_FILL
5105
    else
5106
#endif
5107
#endif
5108
0
    if (*ip < 0) {
5109
        
5110
0
#ifdef ERANGE_FILL
5111
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5112
0
#endif
5113
0
        err = NC_ERANGE; /* because xp is unsigned */
5114
0
    }
5115
0
#ifdef ERANGE_FILL
5116
0
    else
5117
0
#endif
5118
0
        xx = (ix_uint64)*ip;
5119
5120
0
    put_ix_uint64(xp, &xx);
5121
0
    return err;
5122
0
}
5123
5124
static int
5125
ncx_put_ulonglong_uchar(void *xp, const uchar *ip, void *fillp)
5126
0
{
5127
0
    int err=NC_NOERR;
5128
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5129
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5130
#else
5131
0
    ix_uint64 xx = NC_FILL_UINT64;
5132
5133
#if IX_UINT64_MAX < UCHAR_MAX
5134
    if (*ip > IX_UINT64_MAX) {
5135
        
5136
#ifdef ERANGE_FILL
5137
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5138
#endif
5139
        err = NC_ERANGE;
5140
    }
5141
#ifdef ERANGE_FILL
5142
    else
5143
#endif
5144
#endif
5145
0
        xx = (ix_uint64)*ip;
5146
5147
0
    put_ix_uint64(xp, &xx);
5148
0
#endif
5149
0
    return err;
5150
0
}
5151
5152
static int
5153
ncx_put_ulonglong_ushort(void *xp, const ushort *ip, void *fillp)
5154
0
{
5155
0
    int err=NC_NOERR;
5156
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5157
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5158
#else
5159
0
    ix_uint64 xx = NC_FILL_UINT64;
5160
5161
#if IX_UINT64_MAX < USHORT_MAX
5162
    if (*ip > IX_UINT64_MAX) {
5163
        
5164
#ifdef ERANGE_FILL
5165
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5166
#endif
5167
        err = NC_ERANGE;
5168
    }
5169
#ifdef ERANGE_FILL
5170
    else
5171
#endif
5172
#endif
5173
0
        xx = (ix_uint64)*ip;
5174
5175
0
    put_ix_uint64(xp, &xx);
5176
0
#endif
5177
0
    return err;
5178
0
}
5179
5180
static int
5181
ncx_put_ulonglong_uint(void *xp, const uint *ip, void *fillp)
5182
0
{
5183
0
    int err=NC_NOERR;
5184
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5185
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5186
#else
5187
0
    ix_uint64 xx = NC_FILL_UINT64;
5188
5189
#if IX_UINT64_MAX < UINT_MAX
5190
    if (*ip > IX_UINT64_MAX) {
5191
        
5192
#ifdef ERANGE_FILL
5193
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5194
#endif
5195
        err = NC_ERANGE;
5196
    }
5197
#ifdef ERANGE_FILL
5198
    else
5199
#endif
5200
#endif
5201
0
        xx = (ix_uint64)*ip;
5202
5203
0
    put_ix_uint64(xp, &xx);
5204
0
#endif
5205
0
    return err;
5206
0
}
5207
5208
static int
5209
ncx_put_ulonglong_float(void *xp, const float *ip, void *fillp)
5210
0
{
5211
0
    int err=NC_NOERR;
5212
0
    ix_uint64 xx = NC_FILL_UINT64;
5213
5214
0
    if (*ip > (double)X_UINT64_MAX || *ip < 0) {
5215
        
5216
0
#ifdef ERANGE_FILL
5217
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5218
0
#endif
5219
0
        err = NC_ERANGE;
5220
0
    }
5221
0
#ifdef ERANGE_FILL
5222
0
    else
5223
0
#endif
5224
0
        xx = (ix_uint64)*ip;
5225
5226
0
    put_ix_uint64(xp, &xx);
5227
0
    return err;
5228
0
}
5229
5230
static int
5231
ncx_put_ulonglong_double(void *xp, const double *ip, void *fillp)
5232
0
{
5233
0
    int err=NC_NOERR;
5234
0
    ix_uint64 xx = NC_FILL_UINT64;
5235
5236
0
    if (*ip > X_UINT64_MAX || *ip < 0) {
5237
        
5238
0
#ifdef ERANGE_FILL
5239
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5240
0
#endif
5241
0
        err = NC_ERANGE;
5242
0
    }
5243
0
#ifdef ERANGE_FILL
5244
0
    else
5245
0
#endif
5246
0
        xx = (ix_uint64)*ip;
5247
5248
0
    put_ix_uint64(xp, &xx);
5249
0
    return err;
5250
0
}
5251
5252
5253
5254
/* x_size_t */
5255
5256
#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
5257
#error "x_size_t implementation"
5258
/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
5259
#endif
5260
5261
int
5262
ncx_put_size_t(void **xpp, const size_t *ulp)
5263
0
{
5264
  /* similar to put_ix_int() */
5265
0
  uchar *cp = (uchar *) *xpp;
5266
0
  assert(*ulp <= X_SIZE_MAX);
5267
5268
0
  *cp++ = (uchar)((*ulp) >> 24);
5269
0
  *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
5270
0
  *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
5271
0
  *cp   = (uchar)((*ulp) & 0x000000ff);
5272
5273
0
  *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
5274
0
  return NC_NOERR;
5275
0
}
5276
5277
int
5278
ncx_get_size_t(const void **xpp,  size_t *ulp)
5279
1.17M
{
5280
  /* similar to get_ix_int */
5281
1.17M
  const uchar *cp = (const uchar *) *xpp;
5282
5283
1.17M
  *ulp  = (unsigned)(*cp++) << 24;
5284
1.17M
  *ulp |= (*cp++ << 16);
5285
1.17M
  *ulp |= (*cp++ << 8);
5286
1.17M
  *ulp |= *cp;
5287
5288
1.17M
  *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
5289
1.17M
  return NC_NOERR;
5290
1.17M
}
5291
5292
/* x_off_t */
5293
5294
int
5295
ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
5296
0
{
5297
  /* similar to put_ix_int() */
5298
0
  uchar *cp = (uchar *) *xpp;
5299
5300
  /* No negative offsets stored in netcdf */
5301
0
  if (*lp < 0) {
5302
    /* Assume this is an overflow of a 32-bit int... */
5303
0
    return NC_ERANGE;
5304
0
  }
5305
5306
0
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5307
5308
0
  if (sizeof_off_t == 4) {
5309
0
    *cp++ = (uchar) ((*lp)               >> 24);
5310
0
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5311
0
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5312
0
    *cp   = (uchar)( (*lp) & 0x000000ff);
5313
0
  } else {
5314
#if SIZEOF_OFF_T == 4
5315
/* Write a 64-bit offset on a system with only a 32-bit offset */
5316
    *cp++ = (uchar)0;
5317
    *cp++ = (uchar)0;
5318
    *cp++ = (uchar)0;
5319
    *cp++ = (uchar)0;
5320
5321
    *cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
5322
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5323
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5324
    *cp   = (uchar)( (*lp) & 0x000000ff);
5325
#else
5326
0
    *cp++ = (uchar) ((*lp)                          >> 56);
5327
0
    *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48);
5328
0
    *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40);
5329
0
    *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32);
5330
0
    *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24);
5331
0
    *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16);
5332
0
    *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >>  8);
5333
0
    *cp   = (uchar)( (*lp) & 0x00000000000000ffLL);
5334
0
#endif
5335
0
  }
5336
0
  *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
5337
0
  return NC_NOERR;
5338
0
}
5339
5340
int
5341
ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
5342
131k
{
5343
  /* similar to get_ix_int() */
5344
131k
  const uchar *cp = (const uchar *) *xpp;
5345
131k
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5346
5347
131k
  if (sizeof_off_t == 4) {
5348
0
    *lp =  (off_t)(*cp++ << 24);
5349
0
    *lp |= (off_t)(*cp++ << 16);
5350
0
    *lp |= (off_t)(*cp++ <<  8);
5351
0
    *lp |= (off_t)*cp;
5352
131k
  } else {
5353
#if SIZEOF_OFF_T == 4
5354
/* Read a 64-bit offset on a system with only a 32-bit offset */
5355
/* If the offset overflows, set an error code and return */
5356
    *lp =  ((off_t)(*cp++) << 24);
5357
    *lp |= ((off_t)(*cp++) << 16);
5358
    *lp |= ((off_t)(*cp++) <<  8);
5359
    *lp |= ((off_t)(*cp++));
5360
/*
5361
 * lp now contains the upper 32-bits of the 64-bit offset.  if lp is
5362
 * not zero, then the dataset is larger than can be represented
5363
 * on this system.  Set an error code and return.
5364
 */
5365
    if (*lp != 0) {
5366
      return NC_ERANGE;
5367
    }
5368
5369
    *lp  = ((off_t)(*cp++) << 24);
5370
    *lp |= ((off_t)(*cp++) << 16);
5371
    *lp |= ((off_t)(*cp++) <<  8);
5372
    *lp |=  (off_t)*cp;
5373
5374
    if (*lp < 0) {
5375
      /*
5376
       * If this fails, then the offset is >2^31, but less
5377
       * than 2^32 which is not allowed, but is not caught
5378
       * by the previous check
5379
       */
5380
      return NC_ERANGE;
5381
    }
5382
#else
5383
131k
    *lp =  ((off_t)(*cp++) << 56);
5384
131k
    *lp |= ((off_t)(*cp++) << 48);
5385
131k
    *lp |= ((off_t)(*cp++) << 40);
5386
131k
    *lp |= ((off_t)(*cp++) << 32);
5387
131k
    *lp |= ((off_t)(*cp++) << 24);
5388
131k
    *lp |= ((off_t)(*cp++) << 16);
5389
131k
    *lp |= ((off_t)(*cp++) <<  8);
5390
131k
    *lp |=  (off_t)*cp;
5391
131k
#endif
5392
131k
  }
5393
131k
  *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
5394
131k
  return NC_NOERR;
5395
131k
}
5396
5397
/*----< ncx_get_uint32() >------------------------------------------*/
5398
int
5399
ncx_get_uint32(const void **xpp, uint *ip)
5400
369k
{
5401
#ifdef WORDS_BIGENDIAN
5402
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5403
     * some system, such as HPUX */
5404
    (void) memcpy(ip, *xpp, SIZEOF_UINT);
5405
#else
5406
369k
    const uchar *cp = (const uchar *) *xpp;
5407
5408
369k
    *ip = (uint)(*cp++ << 24);
5409
369k
    *ip = (uint)(*ip | (uint)(*cp++ << 16));
5410
369k
    *ip = (uint)(*ip | (uint)(*cp++ <<  8));
5411
369k
    *ip = (uint)(*ip | *cp);
5412
369k
#endif
5413
    /* advance *xpp 4 bytes */
5414
369k
    *xpp = (void *)((const char *)(*xpp) + 4);
5415
5416
369k
    return NC_NOERR;
5417
369k
}
5418
5419
/*----< ncx_get_uint64() >------------------------------------------*/
5420
int
5421
ncx_get_uint64(const void **xpp, unsigned long long *ullp)
5422
287k
{
5423
#ifdef WORDS_BIGENDIAN
5424
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5425
     * some system, such as HPUX */
5426
    (void) memcpy(ullp, *xpp, SIZEOF_UINT64);
5427
#else
5428
287k
    const uchar *cp = (const uchar *) *xpp;
5429
5430
    /* below is the same as calling swap8b(ullp, *xpp) */
5431
287k
    *ullp = (unsigned long long)(*cp++) << 56;
5432
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48);
5433
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40);
5434
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32);
5435
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24);
5436
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16);
5437
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) <<  8);
5438
287k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp));
5439
287k
#endif
5440
    /* advance *xpp 8 bytes */
5441
287k
    *xpp = (void *)((const char *)(*xpp) + 8);
5442
5443
287k
    return NC_NOERR;
5444
287k
}
5445
5446
/*---< ncx_put_uint32() >-------------------------------------------*/
5447
/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
5448
 * form and advance *xpp 4 bytes
5449
 */
5450
int
5451
ncx_put_uint32(void **xpp, const unsigned int ip)
5452
0
{
5453
#ifdef WORDS_BIGENDIAN
5454
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5455
     * some system, such as HPUX */
5456
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
5457
#else
5458
    /* bitwise shifts below are to produce an integer in Big Endian */
5459
0
    uchar *cp = (uchar *) *xpp;
5460
0
    *cp++ = (uchar)((ip & 0xff000000) >> 24);
5461
0
    *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
5462
0
    *cp++ = (uchar)((ip & 0x0000ff00) >>  8);
5463
0
    *cp   = (uchar)( ip & 0x000000ff);
5464
0
#endif
5465
    /* advance *xpp 4 bytes */
5466
0
    *xpp  = (void *)((char *)(*xpp) + 4);
5467
5468
0
    return NC_NOERR;
5469
0
}
5470
5471
/*---< ncx_put_uint64() >-------------------------------------------*/
5472
/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
5473
 * form and advance *xpp 8 bytes
5474
 */
5475
int
5476
ncx_put_uint64(void **xpp, const unsigned long long ip)
5477
0
{
5478
#ifdef WORDS_BIGENDIAN
5479
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5480
     * some system, such as HPUX */
5481
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
5482
#else
5483
0
    uchar *cp = (uchar *) *xpp;
5484
    /* below is the same as calling swap8b(*xpp, &ip) */
5485
0
    *cp++ = (uchar) (ip                         >> 56);
5486
0
    *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48);
5487
0
    *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40);
5488
0
    *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32);
5489
0
    *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24);
5490
0
    *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16);
5491
0
    *cp++ = (uchar)((ip & 0x000000000000ff00LL) >>  8);
5492
0
    *cp   = (uchar) (ip & 0x00000000000000ffLL);
5493
0
#endif
5494
    /* advance *xpp 8 bytes */
5495
0
    *xpp  = (void *)((char *)(*xpp) + 8);
5496
5497
0
    return NC_NOERR;
5498
0
}
5499
5500
5501
/*
5502
 * Aggregate numeric conversion functions.
5503
 */
5504
5505
5506
5507
/* schar ---------------------------------------------------------------------*/
5508
5509
int
5510
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5511
97
{
5512
97
    (void) memcpy(tp, *xpp, (size_t)nelems);
5513
97
  *xpp = (void *)((char *)(*xpp) + nelems);
5514
97
  return NC_NOERR;
5515
5516
97
}
5517
int
5518
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5519
0
{
5520
0
    int status = NC_NOERR;
5521
0
    schar *xp = (schar *)(*xpp);
5522
5523
0
    while (nelems-- != 0) {
5524
        
5525
0
        if (*xp < 0) {
5526
0
#ifdef ERANGE_FILL
5527
0
            *tp = NC_FILL_UBYTE;
5528
0
#endif
5529
0
            status = NC_ERANGE; /* because tp is unsigned */
5530
            
5531
0
#ifdef ERANGE_FILL
5532
0
            xp++; tp++; continue;
5533
0
#endif
5534
0
        }
5535
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5536
0
    }
5537
5538
0
    *xpp = (const void *)xp;
5539
0
    return status;
5540
0
}
5541
5542
int
5543
ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5544
0
{
5545
0
    int status = NC_NOERR;
5546
0
    schar *xp = (schar *)(*xpp);
5547
5548
0
    while (nelems-- != 0) {
5549
        
5550
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5551
0
    }
5552
5553
0
    *xpp = (const void *)xp;
5554
0
    return status;
5555
0
}
5556
5557
int
5558
ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5559
0
{
5560
0
    int status = NC_NOERR;
5561
0
    schar *xp = (schar *)(*xpp);
5562
5563
0
    while (nelems-- != 0) {
5564
        
5565
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5566
0
    }
5567
5568
0
    *xpp = (const void *)xp;
5569
0
    return status;
5570
0
}
5571
5572
int
5573
ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5574
0
{
5575
0
    int status = NC_NOERR;
5576
0
    schar *xp = (schar *)(*xpp);
5577
5578
0
    while (nelems-- != 0) {
5579
        
5580
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5581
0
    }
5582
5583
0
    *xpp = (const void *)xp;
5584
0
    return status;
5585
0
}
5586
5587
int
5588
ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5589
0
{
5590
0
    int status = NC_NOERR;
5591
0
    schar *xp = (schar *)(*xpp);
5592
5593
0
    while (nelems-- != 0) {
5594
        
5595
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5596
0
    }
5597
5598
0
    *xpp = (const void *)xp;
5599
0
    return status;
5600
0
}
5601
5602
int
5603
ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5604
0
{
5605
0
    int status = NC_NOERR;
5606
0
    schar *xp = (schar *)(*xpp);
5607
5608
0
    while (nelems-- != 0) {
5609
        
5610
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5611
0
    }
5612
5613
0
    *xpp = (const void *)xp;
5614
0
    return status;
5615
0
}
5616
5617
int
5618
ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5619
0
{
5620
0
    int status = NC_NOERR;
5621
0
    schar *xp = (schar *)(*xpp);
5622
5623
0
    while (nelems-- != 0) {
5624
        
5625
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5626
0
    }
5627
5628
0
    *xpp = (const void *)xp;
5629
0
    return status;
5630
0
}
5631
5632
int
5633
ncx_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5634
0
{
5635
0
    int status = NC_NOERR;
5636
0
    schar *xp = (schar *)(*xpp);
5637
5638
0
    while (nelems-- != 0) {
5639
        
5640
0
        if (*xp < 0) {
5641
0
#ifdef ERANGE_FILL
5642
0
            *tp = NC_FILL_USHORT;
5643
0
#endif
5644
0
            status = NC_ERANGE; /* because tp is unsigned */
5645
            
5646
0
#ifdef ERANGE_FILL
5647
0
            xp++; tp++; continue;
5648
0
#endif
5649
0
        }
5650
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5651
0
    }
5652
5653
0
    *xpp = (const void *)xp;
5654
0
    return status;
5655
0
}
5656
5657
int
5658
ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5659
0
{
5660
0
    int status = NC_NOERR;
5661
0
    schar *xp = (schar *)(*xpp);
5662
5663
0
    while (nelems-- != 0) {
5664
        
5665
0
        if (*xp < 0) {
5666
0
#ifdef ERANGE_FILL
5667
0
            *tp = NC_FILL_UINT;
5668
0
#endif
5669
0
            status = NC_ERANGE; /* because tp is unsigned */
5670
            
5671
0
#ifdef ERANGE_FILL
5672
0
            xp++; tp++; continue;
5673
0
#endif
5674
0
        }
5675
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5676
0
    }
5677
5678
0
    *xpp = (const void *)xp;
5679
0
    return status;
5680
0
}
5681
5682
int
5683
ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5684
0
{
5685
0
    int status = NC_NOERR;
5686
0
    schar *xp = (schar *)(*xpp);
5687
5688
0
    while (nelems-- != 0) {
5689
        
5690
0
        if (*xp < 0) {
5691
0
#ifdef ERANGE_FILL
5692
0
            *tp = NC_FILL_UINT64;
5693
0
#endif
5694
0
            status = NC_ERANGE; /* because tp is unsigned */
5695
            
5696
0
#ifdef ERANGE_FILL
5697
0
            xp++; tp++; continue;
5698
0
#endif
5699
0
        }
5700
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5701
0
    }
5702
5703
0
    *xpp = (const void *)xp;
5704
0
    return status;
5705
0
}
5706
5707
5708
int
5709
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5710
0
{
5711
0
    size_t rndup = nelems % X_ALIGN;
5712
5713
0
  if (rndup)
5714
0
    rndup = X_ALIGN - rndup;
5715
5716
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
5717
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
5718
5719
0
  return NC_NOERR;
5720
5721
0
}
5722
int
5723
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5724
0
{
5725
0
    int status = NC_NOERR;
5726
0
    size_t rndup = nelems % X_ALIGN;
5727
0
    schar *xp = (schar *) *xpp;
5728
5729
0
    if (rndup)
5730
0
        rndup = X_ALIGN - rndup;
5731
5732
0
    while (nelems-- != 0) {
5733
        
5734
0
        if (*xp < 0) {
5735
0
#ifdef ERANGE_FILL
5736
0
            *tp = NC_FILL_UBYTE;
5737
0
#endif
5738
0
            status = NC_ERANGE; /* because tp is unsigned */
5739
            
5740
0
#ifdef ERANGE_FILL
5741
0
            xp++; tp++; continue;
5742
0
#endif
5743
0
        }
5744
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5745
0
    }
5746
5747
0
    *xpp = (void *)(xp + rndup);
5748
0
    return status;
5749
0
}
5750
5751
int
5752
ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5753
0
{
5754
0
    int status = NC_NOERR;
5755
0
    size_t rndup = nelems % X_ALIGN;
5756
0
    schar *xp = (schar *) *xpp;
5757
5758
0
    if (rndup)
5759
0
        rndup = X_ALIGN - rndup;
5760
5761
0
    while (nelems-- != 0) {
5762
        
5763
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5764
0
    }
5765
5766
0
    *xpp = (void *)(xp + rndup);
5767
0
    return status;
5768
0
}
5769
5770
int
5771
ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5772
0
{
5773
0
    int status = NC_NOERR;
5774
0
    size_t rndup = nelems % X_ALIGN;
5775
0
    schar *xp = (schar *) *xpp;
5776
5777
0
    if (rndup)
5778
0
        rndup = X_ALIGN - rndup;
5779
5780
0
    while (nelems-- != 0) {
5781
        
5782
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5783
0
    }
5784
5785
0
    *xpp = (void *)(xp + rndup);
5786
0
    return status;
5787
0
}
5788
5789
int
5790
ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5791
0
{
5792
0
    int status = NC_NOERR;
5793
0
    size_t rndup = nelems % X_ALIGN;
5794
0
    schar *xp = (schar *) *xpp;
5795
5796
0
    if (rndup)
5797
0
        rndup = X_ALIGN - rndup;
5798
5799
0
    while (nelems-- != 0) {
5800
        
5801
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5802
0
    }
5803
5804
0
    *xpp = (void *)(xp + rndup);
5805
0
    return status;
5806
0
}
5807
5808
int
5809
ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5810
0
{
5811
0
    int status = NC_NOERR;
5812
0
    size_t rndup = nelems % X_ALIGN;
5813
0
    schar *xp = (schar *) *xpp;
5814
5815
0
    if (rndup)
5816
0
        rndup = X_ALIGN - rndup;
5817
5818
0
    while (nelems-- != 0) {
5819
        
5820
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5821
0
    }
5822
5823
0
    *xpp = (void *)(xp + rndup);
5824
0
    return status;
5825
0
}
5826
5827
int
5828
ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5829
0
{
5830
0
    int status = NC_NOERR;
5831
0
    size_t rndup = nelems % X_ALIGN;
5832
0
    schar *xp = (schar *) *xpp;
5833
5834
0
    if (rndup)
5835
0
        rndup = X_ALIGN - rndup;
5836
5837
0
    while (nelems-- != 0) {
5838
        
5839
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5840
0
    }
5841
5842
0
    *xpp = (void *)(xp + rndup);
5843
0
    return status;
5844
0
}
5845
5846
int
5847
ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5848
0
{
5849
0
    int status = NC_NOERR;
5850
0
    size_t rndup = nelems % X_ALIGN;
5851
0
    schar *xp = (schar *) *xpp;
5852
5853
0
    if (rndup)
5854
0
        rndup = X_ALIGN - rndup;
5855
5856
0
    while (nelems-- != 0) {
5857
        
5858
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5859
0
    }
5860
5861
0
    *xpp = (void *)(xp + rndup);
5862
0
    return status;
5863
0
}
5864
5865
int
5866
ncx_pad_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5867
0
{
5868
0
    int status = NC_NOERR;
5869
0
    size_t rndup = nelems % X_ALIGN;
5870
0
    schar *xp = (schar *) *xpp;
5871
5872
0
    if (rndup)
5873
0
        rndup = X_ALIGN - rndup;
5874
5875
0
    while (nelems-- != 0) {
5876
        
5877
0
        if (*xp < 0) {
5878
0
#ifdef ERANGE_FILL
5879
0
            *tp = NC_FILL_USHORT;
5880
0
#endif
5881
0
            status = NC_ERANGE; /* because tp is unsigned */
5882
            
5883
0
#ifdef ERANGE_FILL
5884
0
            xp++; tp++; continue;
5885
0
#endif
5886
0
        }
5887
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5888
0
    }
5889
5890
0
    *xpp = (void *)(xp + rndup);
5891
0
    return status;
5892
0
}
5893
5894
int
5895
ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5896
0
{
5897
0
    int status = NC_NOERR;
5898
0
    size_t rndup = nelems % X_ALIGN;
5899
0
    schar *xp = (schar *) *xpp;
5900
5901
0
    if (rndup)
5902
0
        rndup = X_ALIGN - rndup;
5903
5904
0
    while (nelems-- != 0) {
5905
        
5906
0
        if (*xp < 0) {
5907
0
#ifdef ERANGE_FILL
5908
0
            *tp = NC_FILL_UINT;
5909
0
#endif
5910
0
            status = NC_ERANGE; /* because tp is unsigned */
5911
            
5912
0
#ifdef ERANGE_FILL
5913
0
            xp++; tp++; continue;
5914
0
#endif
5915
0
        }
5916
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5917
0
    }
5918
5919
0
    *xpp = (void *)(xp + rndup);
5920
0
    return status;
5921
0
}
5922
5923
int
5924
ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5925
0
{
5926
0
    int status = NC_NOERR;
5927
0
    size_t rndup = nelems % X_ALIGN;
5928
0
    schar *xp = (schar *) *xpp;
5929
5930
0
    if (rndup)
5931
0
        rndup = X_ALIGN - rndup;
5932
5933
0
    while (nelems-- != 0) {
5934
        
5935
0
        if (*xp < 0) {
5936
0
#ifdef ERANGE_FILL
5937
0
            *tp = NC_FILL_UINT64;
5938
0
#endif
5939
0
            status = NC_ERANGE; /* because tp is unsigned */
5940
            
5941
0
#ifdef ERANGE_FILL
5942
0
            xp++; tp++; continue;
5943
0
#endif
5944
0
        }
5945
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5946
0
    }
5947
5948
0
    *xpp = (void *)(xp + rndup);
5949
0
    return status;
5950
0
}
5951
5952
5953
int
5954
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
5955
0
{
5956
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
5957
0
  *xpp = (void *)((char *)(*xpp) + nelems);
5958
5959
0
  return NC_NOERR;
5960
5961
0
}
5962
int
5963
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
5964
0
{
5965
0
    int status = NC_NOERR;
5966
0
    schar *xp = (schar *) *xpp;
5967
5968
0
    while (nelems-- != 0) {
5969
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
5970
            
5971
0
#ifdef ERANGE_FILL
5972
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
5973
0
#endif
5974
0
            status = NC_ERANGE;
5975
            
5976
0
#ifdef ERANGE_FILL
5977
0
            xp++; tp++; continue;
5978
0
#endif
5979
0
        }
5980
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
5981
0
    }
5982
5983
0
    *xpp = (void *)xp;
5984
0
    return status;
5985
0
}
5986
5987
int
5988
ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
5989
0
{
5990
0
    int status = NC_NOERR;
5991
0
    schar *xp = (schar *) *xpp;
5992
5993
0
    while (nelems-- != 0) {
5994
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
5995
            
5996
0
#ifdef ERANGE_FILL
5997
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
5998
0
#endif
5999
0
            status = NC_ERANGE;
6000
            
6001
0
#ifdef ERANGE_FILL
6002
0
            xp++; tp++; continue;
6003
0
#endif
6004
0
        }
6005
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6006
0
    }
6007
6008
0
    *xpp = (void *)xp;
6009
0
    return status;
6010
0
}
6011
6012
int
6013
ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6014
0
{
6015
0
    int status = NC_NOERR;
6016
0
    schar *xp = (schar *) *xpp;
6017
6018
0
    while (nelems-- != 0) {
6019
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6020
            
6021
0
#ifdef ERANGE_FILL
6022
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6023
0
#endif
6024
0
            status = NC_ERANGE;
6025
            
6026
0
#ifdef ERANGE_FILL
6027
0
            xp++; tp++; continue;
6028
0
#endif
6029
0
        }
6030
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6031
0
    }
6032
6033
0
    *xpp = (void *)xp;
6034
0
    return status;
6035
0
}
6036
6037
int
6038
ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6039
0
{
6040
0
    int status = NC_NOERR;
6041
0
    schar *xp = (schar *) *xpp;
6042
6043
0
    while (nelems-- != 0) {
6044
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6045
            
6046
0
#ifdef ERANGE_FILL
6047
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6048
0
#endif
6049
0
            status = NC_ERANGE;
6050
            
6051
0
#ifdef ERANGE_FILL
6052
0
            xp++; tp++; continue;
6053
0
#endif
6054
0
        }
6055
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6056
0
    }
6057
6058
0
    *xpp = (void *)xp;
6059
0
    return status;
6060
0
}
6061
6062
int
6063
ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6064
0
{
6065
0
    int status = NC_NOERR;
6066
0
    schar *xp = (schar *) *xpp;
6067
6068
0
    while (nelems-- != 0) {
6069
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6070
            
6071
0
#ifdef ERANGE_FILL
6072
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6073
0
#endif
6074
0
            status = NC_ERANGE;
6075
            
6076
0
#ifdef ERANGE_FILL
6077
0
            xp++; tp++; continue;
6078
0
#endif
6079
0
        }
6080
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6081
0
    }
6082
6083
0
    *xpp = (void *)xp;
6084
0
    return status;
6085
0
}
6086
6087
int
6088
ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6089
0
{
6090
0
    int status = NC_NOERR;
6091
0
    schar *xp = (schar *) *xpp;
6092
6093
0
    while (nelems-- != 0) {
6094
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6095
            
6096
0
#ifdef ERANGE_FILL
6097
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6098
0
#endif
6099
0
            status = NC_ERANGE;
6100
            
6101
0
#ifdef ERANGE_FILL
6102
0
            xp++; tp++; continue;
6103
0
#endif
6104
0
        }
6105
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6106
0
    }
6107
6108
0
    *xpp = (void *)xp;
6109
0
    return status;
6110
0
}
6111
6112
int
6113
ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6114
0
{
6115
0
    int status = NC_NOERR;
6116
0
    schar *xp = (schar *) *xpp;
6117
6118
0
    while (nelems-- != 0) {
6119
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6120
            
6121
0
#ifdef ERANGE_FILL
6122
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6123
0
#endif
6124
0
            status = NC_ERANGE;
6125
            
6126
0
#ifdef ERANGE_FILL
6127
0
            xp++; tp++; continue;
6128
0
#endif
6129
0
        }
6130
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6131
0
    }
6132
6133
0
    *xpp = (void *)xp;
6134
0
    return status;
6135
0
}
6136
6137
int
6138
ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6139
0
{
6140
0
    int status = NC_NOERR;
6141
0
    schar *xp = (schar *) *xpp;
6142
6143
0
    while (nelems-- != 0) {
6144
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6145
            
6146
0
#ifdef ERANGE_FILL
6147
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6148
0
#endif
6149
0
            status = NC_ERANGE;
6150
            
6151
0
#ifdef ERANGE_FILL
6152
0
            xp++; tp++; continue;
6153
0
#endif
6154
0
        }
6155
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6156
0
    }
6157
6158
0
    *xpp = (void *)xp;
6159
0
    return status;
6160
0
}
6161
6162
int
6163
ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6164
0
{
6165
0
    int status = NC_NOERR;
6166
0
    schar *xp = (schar *) *xpp;
6167
6168
0
    while (nelems-- != 0) {
6169
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6170
            
6171
0
#ifdef ERANGE_FILL
6172
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6173
0
#endif
6174
0
            status = NC_ERANGE;
6175
            
6176
0
#ifdef ERANGE_FILL
6177
0
            xp++; tp++; continue;
6178
0
#endif
6179
0
        }
6180
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6181
0
    }
6182
6183
0
    *xpp = (void *)xp;
6184
0
    return status;
6185
0
}
6186
6187
int
6188
ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6189
0
{
6190
0
    int status = NC_NOERR;
6191
0
    schar *xp = (schar *) *xpp;
6192
6193
0
    while (nelems-- != 0) {
6194
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6195
            
6196
0
#ifdef ERANGE_FILL
6197
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6198
0
#endif
6199
0
            status = NC_ERANGE;
6200
            
6201
0
#ifdef ERANGE_FILL
6202
0
            xp++; tp++; continue;
6203
0
#endif
6204
0
        }
6205
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6206
0
    }
6207
6208
0
    *xpp = (void *)xp;
6209
0
    return status;
6210
0
}
6211
6212
6213
int
6214
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6215
0
{
6216
0
    size_t rndup = nelems % X_ALIGN;
6217
6218
0
  if (rndup)
6219
0
    rndup = X_ALIGN - rndup;
6220
6221
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
6222
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6223
6224
0
  if (rndup)
6225
0
  {
6226
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
6227
0
    *xpp = (void *)((char *)(*xpp) + rndup);
6228
0
  }
6229
6230
0
  return NC_NOERR;
6231
6232
0
}
6233
int
6234
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6235
0
{
6236
0
    int status = NC_NOERR;
6237
0
    size_t rndup = nelems % X_ALIGN;
6238
0
    schar *xp = (schar *) *xpp;
6239
6240
0
    if (rndup) rndup = X_ALIGN - rndup;
6241
6242
0
    while (nelems-- != 0) {
6243
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
6244
            
6245
0
#ifdef ERANGE_FILL
6246
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6247
0
#endif
6248
0
            status = NC_ERANGE;
6249
            
6250
0
#ifdef ERANGE_FILL
6251
0
            xp++; tp++; continue;
6252
0
#endif
6253
0
        }
6254
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6255
0
    }
6256
6257
6258
0
    if (rndup) {
6259
0
        (void) memcpy(xp, nada, (size_t)rndup);
6260
0
        xp += rndup;
6261
0
    }
6262
6263
0
    *xpp = (void *)xp;
6264
0
    return status;
6265
0
}
6266
6267
int
6268
ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6269
0
{
6270
0
    int status = NC_NOERR;
6271
0
    size_t rndup = nelems % X_ALIGN;
6272
0
    schar *xp = (schar *) *xpp;
6273
6274
0
    if (rndup) rndup = X_ALIGN - rndup;
6275
6276
0
    while (nelems-- != 0) {
6277
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6278
            
6279
0
#ifdef ERANGE_FILL
6280
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6281
0
#endif
6282
0
            status = NC_ERANGE;
6283
            
6284
0
#ifdef ERANGE_FILL
6285
0
            xp++; tp++; continue;
6286
0
#endif
6287
0
        }
6288
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6289
0
    }
6290
6291
6292
0
    if (rndup) {
6293
0
        (void) memcpy(xp, nada, (size_t)rndup);
6294
0
        xp += rndup;
6295
0
    }
6296
6297
0
    *xpp = (void *)xp;
6298
0
    return status;
6299
0
}
6300
6301
int
6302
ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6303
0
{
6304
0
    int status = NC_NOERR;
6305
0
    size_t rndup = nelems % X_ALIGN;
6306
0
    schar *xp = (schar *) *xpp;
6307
6308
0
    if (rndup) rndup = X_ALIGN - rndup;
6309
6310
0
    while (nelems-- != 0) {
6311
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6312
            
6313
0
#ifdef ERANGE_FILL
6314
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6315
0
#endif
6316
0
            status = NC_ERANGE;
6317
            
6318
0
#ifdef ERANGE_FILL
6319
0
            xp++; tp++; continue;
6320
0
#endif
6321
0
        }
6322
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6323
0
    }
6324
6325
6326
0
    if (rndup) {
6327
0
        (void) memcpy(xp, nada, (size_t)rndup);
6328
0
        xp += rndup;
6329
0
    }
6330
6331
0
    *xpp = (void *)xp;
6332
0
    return status;
6333
0
}
6334
6335
int
6336
ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6337
0
{
6338
0
    int status = NC_NOERR;
6339
0
    size_t rndup = nelems % X_ALIGN;
6340
0
    schar *xp = (schar *) *xpp;
6341
6342
0
    if (rndup) rndup = X_ALIGN - rndup;
6343
6344
0
    while (nelems-- != 0) {
6345
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6346
            
6347
0
#ifdef ERANGE_FILL
6348
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6349
0
#endif
6350
0
            status = NC_ERANGE;
6351
            
6352
0
#ifdef ERANGE_FILL
6353
0
            xp++; tp++; continue;
6354
0
#endif
6355
0
        }
6356
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6357
0
    }
6358
6359
6360
0
    if (rndup) {
6361
0
        (void) memcpy(xp, nada, (size_t)rndup);
6362
0
        xp += rndup;
6363
0
    }
6364
6365
0
    *xpp = (void *)xp;
6366
0
    return status;
6367
0
}
6368
6369
int
6370
ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6371
0
{
6372
0
    int status = NC_NOERR;
6373
0
    size_t rndup = nelems % X_ALIGN;
6374
0
    schar *xp = (schar *) *xpp;
6375
6376
0
    if (rndup) rndup = X_ALIGN - rndup;
6377
6378
0
    while (nelems-- != 0) {
6379
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6380
            
6381
0
#ifdef ERANGE_FILL
6382
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6383
0
#endif
6384
0
            status = NC_ERANGE;
6385
            
6386
0
#ifdef ERANGE_FILL
6387
0
            xp++; tp++; continue;
6388
0
#endif
6389
0
        }
6390
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6391
0
    }
6392
6393
6394
0
    if (rndup) {
6395
0
        (void) memcpy(xp, nada, (size_t)rndup);
6396
0
        xp += rndup;
6397
0
    }
6398
6399
0
    *xpp = (void *)xp;
6400
0
    return status;
6401
0
}
6402
6403
int
6404
ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6405
0
{
6406
0
    int status = NC_NOERR;
6407
0
    size_t rndup = nelems % X_ALIGN;
6408
0
    schar *xp = (schar *) *xpp;
6409
6410
0
    if (rndup) rndup = X_ALIGN - rndup;
6411
6412
0
    while (nelems-- != 0) {
6413
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6414
            
6415
0
#ifdef ERANGE_FILL
6416
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6417
0
#endif
6418
0
            status = NC_ERANGE;
6419
            
6420
0
#ifdef ERANGE_FILL
6421
0
            xp++; tp++; continue;
6422
0
#endif
6423
0
        }
6424
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6425
0
    }
6426
6427
6428
0
    if (rndup) {
6429
0
        (void) memcpy(xp, nada, (size_t)rndup);
6430
0
        xp += rndup;
6431
0
    }
6432
6433
0
    *xpp = (void *)xp;
6434
0
    return status;
6435
0
}
6436
6437
int
6438
ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6439
0
{
6440
0
    int status = NC_NOERR;
6441
0
    size_t rndup = nelems % X_ALIGN;
6442
0
    schar *xp = (schar *) *xpp;
6443
6444
0
    if (rndup) rndup = X_ALIGN - rndup;
6445
6446
0
    while (nelems-- != 0) {
6447
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6448
            
6449
0
#ifdef ERANGE_FILL
6450
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6451
0
#endif
6452
0
            status = NC_ERANGE;
6453
            
6454
0
#ifdef ERANGE_FILL
6455
0
            xp++; tp++; continue;
6456
0
#endif
6457
0
        }
6458
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6459
0
    }
6460
6461
6462
0
    if (rndup) {
6463
0
        (void) memcpy(xp, nada, (size_t)rndup);
6464
0
        xp += rndup;
6465
0
    }
6466
6467
0
    *xpp = (void *)xp;
6468
0
    return status;
6469
0
}
6470
6471
int
6472
ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6473
0
{
6474
0
    int status = NC_NOERR;
6475
0
    size_t rndup = nelems % X_ALIGN;
6476
0
    schar *xp = (schar *) *xpp;
6477
6478
0
    if (rndup) rndup = X_ALIGN - rndup;
6479
6480
0
    while (nelems-- != 0) {
6481
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6482
            
6483
0
#ifdef ERANGE_FILL
6484
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6485
0
#endif
6486
0
            status = NC_ERANGE;
6487
            
6488
0
#ifdef ERANGE_FILL
6489
0
            xp++; tp++; continue;
6490
0
#endif
6491
0
        }
6492
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6493
0
    }
6494
6495
6496
0
    if (rndup) {
6497
0
        (void) memcpy(xp, nada, (size_t)rndup);
6498
0
        xp += rndup;
6499
0
    }
6500
6501
0
    *xpp = (void *)xp;
6502
0
    return status;
6503
0
}
6504
6505
int
6506
ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6507
0
{
6508
0
    int status = NC_NOERR;
6509
0
    size_t rndup = nelems % X_ALIGN;
6510
0
    schar *xp = (schar *) *xpp;
6511
6512
0
    if (rndup) rndup = X_ALIGN - rndup;
6513
6514
0
    while (nelems-- != 0) {
6515
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6516
            
6517
0
#ifdef ERANGE_FILL
6518
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6519
0
#endif
6520
0
            status = NC_ERANGE;
6521
            
6522
0
#ifdef ERANGE_FILL
6523
0
            xp++; tp++; continue;
6524
0
#endif
6525
0
        }
6526
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6527
0
    }
6528
6529
6530
0
    if (rndup) {
6531
0
        (void) memcpy(xp, nada, (size_t)rndup);
6532
0
        xp += rndup;
6533
0
    }
6534
6535
0
    *xpp = (void *)xp;
6536
0
    return status;
6537
0
}
6538
6539
int
6540
ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6541
0
{
6542
0
    int status = NC_NOERR;
6543
0
    size_t rndup = nelems % X_ALIGN;
6544
0
    schar *xp = (schar *) *xpp;
6545
6546
0
    if (rndup) rndup = X_ALIGN - rndup;
6547
6548
0
    while (nelems-- != 0) {
6549
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6550
            
6551
0
#ifdef ERANGE_FILL
6552
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6553
0
#endif
6554
0
            status = NC_ERANGE;
6555
            
6556
0
#ifdef ERANGE_FILL
6557
0
            xp++; tp++; continue;
6558
0
#endif
6559
0
        }
6560
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6561
0
    }
6562
6563
6564
0
    if (rndup) {
6565
0
        (void) memcpy(xp, nada, (size_t)rndup);
6566
0
        xp += rndup;
6567
0
    }
6568
6569
0
    *xpp = (void *)xp;
6570
0
    return status;
6571
0
}
6572
6573
6574
6575
/* uchar ---------------------------------------------------------------------*/
6576
int
6577
ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6578
0
{
6579
0
    int status = NC_NOERR;
6580
0
    uchar *xp = (uchar *)(*xpp);
6581
6582
0
    while (nelems-- != 0) {
6583
0
        if (*xp > SCHAR_MAX) {
6584
0
            *tp = NC_FILL_BYTE;
6585
0
            status = NC_ERANGE;
6586
            
6587
0
#ifdef ERANGE_FILL
6588
0
            xp++; tp++; continue;
6589
0
#endif
6590
0
        }
6591
0
  *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6592
0
    }
6593
6594
0
    *xpp = (const void *)xp;
6595
0
    return status;
6596
0
}
6597
int
6598
ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6599
0
{
6600
0
    (void) memcpy(tp, *xpp, (size_t)nelems);
6601
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6602
0
  return NC_NOERR;
6603
6604
0
}
6605
int
6606
ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6607
0
{
6608
0
    int status = NC_NOERR;
6609
0
    uchar *xp = (uchar *)(*xpp);
6610
6611
0
    while (nelems-- != 0) {
6612
        
6613
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6614
0
    }
6615
6616
0
    *xpp = (const void *)xp;
6617
0
    return status;
6618
0
}
6619
6620
int
6621
ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6622
0
{
6623
0
    int status = NC_NOERR;
6624
0
    uchar *xp = (uchar *)(*xpp);
6625
6626
0
    while (nelems-- != 0) {
6627
        
6628
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6629
0
    }
6630
6631
0
    *xpp = (const void *)xp;
6632
0
    return status;
6633
0
}
6634
6635
int
6636
ncx_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6637
0
{
6638
0
    int status = NC_NOERR;
6639
0
    uchar *xp = (uchar *)(*xpp);
6640
6641
0
    while (nelems-- != 0) {
6642
        
6643
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6644
0
    }
6645
6646
0
    *xpp = (const void *)xp;
6647
0
    return status;
6648
0
}
6649
6650
int
6651
ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6652
0
{
6653
0
    int status = NC_NOERR;
6654
0
    uchar *xp = (uchar *)(*xpp);
6655
6656
0
    while (nelems-- != 0) {
6657
        
6658
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6659
0
    }
6660
6661
0
    *xpp = (const void *)xp;
6662
0
    return status;
6663
0
}
6664
6665
int
6666
ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6667
0
{
6668
0
    int status = NC_NOERR;
6669
0
    uchar *xp = (uchar *)(*xpp);
6670
6671
0
    while (nelems-- != 0) {
6672
        
6673
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6674
0
    }
6675
6676
0
    *xpp = (const void *)xp;
6677
0
    return status;
6678
0
}
6679
6680
int
6681
ncx_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6682
0
{
6683
0
    int status = NC_NOERR;
6684
0
    uchar *xp = (uchar *)(*xpp);
6685
6686
0
    while (nelems-- != 0) {
6687
        
6688
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6689
0
    }
6690
6691
0
    *xpp = (const void *)xp;
6692
0
    return status;
6693
0
}
6694
6695
int
6696
ncx_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6697
0
{
6698
0
    int status = NC_NOERR;
6699
0
    uchar *xp = (uchar *)(*xpp);
6700
6701
0
    while (nelems-- != 0) {
6702
        
6703
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6704
0
    }
6705
6706
0
    *xpp = (const void *)xp;
6707
0
    return status;
6708
0
}
6709
6710
int
6711
ncx_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6712
0
{
6713
0
    int status = NC_NOERR;
6714
0
    uchar *xp = (uchar *)(*xpp);
6715
6716
0
    while (nelems-- != 0) {
6717
        
6718
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6719
0
    }
6720
6721
0
    *xpp = (const void *)xp;
6722
0
    return status;
6723
0
}
6724
6725
int
6726
ncx_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6727
0
{
6728
0
    int status = NC_NOERR;
6729
0
    uchar *xp = (uchar *)(*xpp);
6730
6731
0
    while (nelems-- != 0) {
6732
        
6733
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6734
0
    }
6735
6736
0
    *xpp = (const void *)xp;
6737
0
    return status;
6738
0
}
6739
6740
6741
int
6742
ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6743
0
{
6744
0
    int status = NC_NOERR;
6745
0
    size_t rndup = nelems % X_ALIGN;
6746
0
    uchar *xp = (uchar *) *xpp;
6747
6748
0
    if (rndup) rndup = X_ALIGN - rndup;
6749
6750
0
    while (nelems-- != 0) {
6751
0
        if (*xp > SCHAR_MAX) {
6752
0
            *tp = NC_FILL_BYTE;
6753
0
            status = NC_ERANGE;
6754
            
6755
0
#ifdef ERANGE_FILL
6756
0
            xp++; tp++; continue;
6757
0
#endif
6758
0
        }
6759
0
        *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6760
0
    }
6761
6762
0
    *xpp = (void *)(xp + rndup);
6763
0
    return status;
6764
0
}
6765
int
6766
ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6767
0
{
6768
0
    size_t rndup = nelems % X_ALIGN;
6769
6770
0
  if (rndup)
6771
0
    rndup = X_ALIGN - rndup;
6772
6773
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
6774
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
6775
6776
0
  return NC_NOERR;
6777
6778
0
}
6779
int
6780
ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6781
0
{
6782
0
    int status = NC_NOERR;
6783
0
    size_t rndup = nelems % X_ALIGN;
6784
0
    uchar *xp = (uchar *) *xpp;
6785
6786
0
    if (rndup)
6787
0
        rndup = X_ALIGN - rndup;
6788
6789
0
    while (nelems-- != 0) {
6790
        
6791
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6792
0
    }
6793
6794
0
    *xpp = (void *)(xp + rndup);
6795
0
    return status;
6796
0
}
6797
6798
int
6799
ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6800
0
{
6801
0
    int status = NC_NOERR;
6802
0
    size_t rndup = nelems % X_ALIGN;
6803
0
    uchar *xp = (uchar *) *xpp;
6804
6805
0
    if (rndup)
6806
0
        rndup = X_ALIGN - rndup;
6807
6808
0
    while (nelems-- != 0) {
6809
        
6810
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6811
0
    }
6812
6813
0
    *xpp = (void *)(xp + rndup);
6814
0
    return status;
6815
0
}
6816
6817
int
6818
ncx_pad_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6819
0
{
6820
0
    int status = NC_NOERR;
6821
0
    size_t rndup = nelems % X_ALIGN;
6822
0
    uchar *xp = (uchar *) *xpp;
6823
6824
0
    if (rndup)
6825
0
        rndup = X_ALIGN - rndup;
6826
6827
0
    while (nelems-- != 0) {
6828
        
6829
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6830
0
    }
6831
6832
0
    *xpp = (void *)(xp + rndup);
6833
0
    return status;
6834
0
}
6835
6836
int
6837
ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6838
0
{
6839
0
    int status = NC_NOERR;
6840
0
    size_t rndup = nelems % X_ALIGN;
6841
0
    uchar *xp = (uchar *) *xpp;
6842
6843
0
    if (rndup)
6844
0
        rndup = X_ALIGN - rndup;
6845
6846
0
    while (nelems-- != 0) {
6847
        
6848
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6849
0
    }
6850
6851
0
    *xpp = (void *)(xp + rndup);
6852
0
    return status;
6853
0
}
6854
6855
int
6856
ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6857
0
{
6858
0
    int status = NC_NOERR;
6859
0
    size_t rndup = nelems % X_ALIGN;
6860
0
    uchar *xp = (uchar *) *xpp;
6861
6862
0
    if (rndup)
6863
0
        rndup = X_ALIGN - rndup;
6864
6865
0
    while (nelems-- != 0) {
6866
        
6867
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6868
0
    }
6869
6870
0
    *xpp = (void *)(xp + rndup);
6871
0
    return status;
6872
0
}
6873
6874
int
6875
ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6876
0
{
6877
0
    int status = NC_NOERR;
6878
0
    size_t rndup = nelems % X_ALIGN;
6879
0
    uchar *xp = (uchar *) *xpp;
6880
6881
0
    if (rndup)
6882
0
        rndup = X_ALIGN - rndup;
6883
6884
0
    while (nelems-- != 0) {
6885
        
6886
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6887
0
    }
6888
6889
0
    *xpp = (void *)(xp + rndup);
6890
0
    return status;
6891
0
}
6892
6893
int
6894
ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6895
0
{
6896
0
    int status = NC_NOERR;
6897
0
    size_t rndup = nelems % X_ALIGN;
6898
0
    uchar *xp = (uchar *) *xpp;
6899
6900
0
    if (rndup)
6901
0
        rndup = X_ALIGN - rndup;
6902
6903
0
    while (nelems-- != 0) {
6904
        
6905
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6906
0
    }
6907
6908
0
    *xpp = (void *)(xp + rndup);
6909
0
    return status;
6910
0
}
6911
6912
int
6913
ncx_pad_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6914
0
{
6915
0
    int status = NC_NOERR;
6916
0
    size_t rndup = nelems % X_ALIGN;
6917
0
    uchar *xp = (uchar *) *xpp;
6918
6919
0
    if (rndup)
6920
0
        rndup = X_ALIGN - rndup;
6921
6922
0
    while (nelems-- != 0) {
6923
        
6924
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6925
0
    }
6926
6927
0
    *xpp = (void *)(xp + rndup);
6928
0
    return status;
6929
0
}
6930
6931
int
6932
ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6933
0
{
6934
0
    int status = NC_NOERR;
6935
0
    size_t rndup = nelems % X_ALIGN;
6936
0
    uchar *xp = (uchar *) *xpp;
6937
6938
0
    if (rndup)
6939
0
        rndup = X_ALIGN - rndup;
6940
6941
0
    while (nelems-- != 0) {
6942
        
6943
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6944
0
    }
6945
6946
0
    *xpp = (void *)(xp + rndup);
6947
0
    return status;
6948
0
}
6949
6950
6951
int
6952
ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6953
0
{
6954
0
    int status = NC_NOERR;
6955
0
    uchar *xp = (uchar *) *xpp;
6956
6957
0
    while (nelems-- != 0) {
6958
0
        if (*tp < 0) {
6959
            
6960
0
#ifdef ERANGE_FILL
6961
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6962
0
#endif
6963
0
            status = NC_ERANGE;
6964
            
6965
0
#ifdef ERANGE_FILL
6966
0
            xp++; tp++; continue;
6967
0
#endif
6968
0
        }
6969
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
6970
0
    }
6971
6972
0
    *xpp = (void *)xp;
6973
0
    return status;
6974
0
}
6975
int
6976
ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6977
0
{
6978
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
6979
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6980
6981
0
  return NC_NOERR;
6982
6983
0
}
6984
int
6985
ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6986
0
{
6987
0
    int status = NC_NOERR;
6988
0
    uchar *xp = (uchar *) *xpp;
6989
6990
0
    while (nelems-- != 0) {
6991
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
6992
            
6993
0
#ifdef ERANGE_FILL
6994
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6995
0
#endif
6996
0
            status = NC_ERANGE;
6997
            
6998
0
#ifdef ERANGE_FILL
6999
0
            xp++; tp++; continue;
7000
0
#endif
7001
0
        }
7002
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7003
0
    }
7004
7005
0
    *xpp = (void *)xp;
7006
0
    return status;
7007
0
}
7008
7009
int
7010
ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7011
0
{
7012
0
    int status = NC_NOERR;
7013
0
    uchar *xp = (uchar *) *xpp;
7014
7015
0
    while (nelems-- != 0) {
7016
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7017
            
7018
0
#ifdef ERANGE_FILL
7019
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7020
0
#endif
7021
0
            status = NC_ERANGE;
7022
            
7023
0
#ifdef ERANGE_FILL
7024
0
            xp++; tp++; continue;
7025
0
#endif
7026
0
        }
7027
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7028
0
    }
7029
7030
0
    *xpp = (void *)xp;
7031
0
    return status;
7032
0
}
7033
7034
int
7035
ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7036
0
{
7037
0
    int status = NC_NOERR;
7038
0
    uchar *xp = (uchar *) *xpp;
7039
7040
0
    while (nelems-- != 0) {
7041
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7042
            
7043
0
#ifdef ERANGE_FILL
7044
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7045
0
#endif
7046
0
            status = NC_ERANGE;
7047
            
7048
0
#ifdef ERANGE_FILL
7049
0
            xp++; tp++; continue;
7050
0
#endif
7051
0
        }
7052
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7053
0
    }
7054
7055
0
    *xpp = (void *)xp;
7056
0
    return status;
7057
0
}
7058
7059
int
7060
ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7061
0
{
7062
0
    int status = NC_NOERR;
7063
0
    uchar *xp = (uchar *) *xpp;
7064
7065
0
    while (nelems-- != 0) {
7066
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7067
            
7068
0
#ifdef ERANGE_FILL
7069
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7070
0
#endif
7071
0
            status = NC_ERANGE;
7072
            
7073
0
#ifdef ERANGE_FILL
7074
0
            xp++; tp++; continue;
7075
0
#endif
7076
0
        }
7077
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7078
0
    }
7079
7080
0
    *xpp = (void *)xp;
7081
0
    return status;
7082
0
}
7083
7084
int
7085
ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7086
0
{
7087
0
    int status = NC_NOERR;
7088
0
    uchar *xp = (uchar *) *xpp;
7089
7090
0
    while (nelems-- != 0) {
7091
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7092
            
7093
0
#ifdef ERANGE_FILL
7094
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7095
0
#endif
7096
0
            status = NC_ERANGE;
7097
            
7098
0
#ifdef ERANGE_FILL
7099
0
            xp++; tp++; continue;
7100
0
#endif
7101
0
        }
7102
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7103
0
    }
7104
7105
0
    *xpp = (void *)xp;
7106
0
    return status;
7107
0
}
7108
7109
int
7110
ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7111
0
{
7112
0
    int status = NC_NOERR;
7113
0
    uchar *xp = (uchar *) *xpp;
7114
7115
0
    while (nelems-- != 0) {
7116
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7117
            
7118
0
#ifdef ERANGE_FILL
7119
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7120
0
#endif
7121
0
            status = NC_ERANGE;
7122
            
7123
0
#ifdef ERANGE_FILL
7124
0
            xp++; tp++; continue;
7125
0
#endif
7126
0
        }
7127
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7128
0
    }
7129
7130
0
    *xpp = (void *)xp;
7131
0
    return status;
7132
0
}
7133
7134
int
7135
ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7136
0
{
7137
0
    int status = NC_NOERR;
7138
0
    uchar *xp = (uchar *) *xpp;
7139
7140
0
    while (nelems-- != 0) {
7141
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7142
            
7143
0
#ifdef ERANGE_FILL
7144
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7145
0
#endif
7146
0
            status = NC_ERANGE;
7147
            
7148
0
#ifdef ERANGE_FILL
7149
0
            xp++; tp++; continue;
7150
0
#endif
7151
0
        }
7152
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7153
0
    }
7154
7155
0
    *xpp = (void *)xp;
7156
0
    return status;
7157
0
}
7158
7159
int
7160
ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7161
0
{
7162
0
    int status = NC_NOERR;
7163
0
    uchar *xp = (uchar *) *xpp;
7164
7165
0
    while (nelems-- != 0) {
7166
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7167
            
7168
0
#ifdef ERANGE_FILL
7169
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7170
0
#endif
7171
0
            status = NC_ERANGE;
7172
            
7173
0
#ifdef ERANGE_FILL
7174
0
            xp++; tp++; continue;
7175
0
#endif
7176
0
        }
7177
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7178
0
    }
7179
7180
0
    *xpp = (void *)xp;
7181
0
    return status;
7182
0
}
7183
7184
int
7185
ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7186
0
{
7187
0
    int status = NC_NOERR;
7188
0
    uchar *xp = (uchar *) *xpp;
7189
7190
0
    while (nelems-- != 0) {
7191
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7192
            
7193
0
#ifdef ERANGE_FILL
7194
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7195
0
#endif
7196
0
            status = NC_ERANGE;
7197
            
7198
0
#ifdef ERANGE_FILL
7199
0
            xp++; tp++; continue;
7200
0
#endif
7201
0
        }
7202
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7203
0
    }
7204
7205
0
    *xpp = (void *)xp;
7206
0
    return status;
7207
0
}
7208
7209
7210
int
7211
ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7212
0
{
7213
0
    int status = NC_NOERR;
7214
0
    size_t rndup = nelems % X_ALIGN;
7215
0
    uchar *xp = (uchar *) *xpp;
7216
7217
0
    if (rndup) rndup = X_ALIGN - rndup;
7218
7219
0
    while (nelems-- != 0) {
7220
0
        if (*tp < 0) {
7221
            
7222
0
#ifdef ERANGE_FILL
7223
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7224
0
#endif
7225
0
            status = NC_ERANGE;
7226
            
7227
0
#ifdef ERANGE_FILL
7228
0
            xp++; tp++; continue;
7229
0
#endif
7230
0
        }
7231
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7232
0
    }
7233
7234
0
    if (rndup) {
7235
0
        (void) memcpy(xp, nada, (size_t)rndup);
7236
0
        xp += rndup;
7237
0
    }
7238
7239
0
    *xpp = (void *)xp;
7240
0
    return status;
7241
0
}
7242
int
7243
ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7244
0
{
7245
0
    size_t rndup = nelems % X_ALIGN;
7246
7247
0
  if (rndup)
7248
0
    rndup = X_ALIGN - rndup;
7249
7250
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
7251
0
  *xpp = (void *)((char *)(*xpp) + nelems);
7252
7253
0
  if (rndup)
7254
0
  {
7255
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
7256
0
    *xpp = (void *)((char *)(*xpp) + rndup);
7257
0
  }
7258
7259
0
  return NC_NOERR;
7260
7261
0
}
7262
int
7263
ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7264
0
{
7265
0
    int status = NC_NOERR;
7266
0
    size_t rndup = nelems % X_ALIGN;
7267
0
    uchar *xp = (uchar *) *xpp;
7268
7269
0
    if (rndup) rndup = X_ALIGN - rndup;
7270
7271
0
    while (nelems-- != 0) {
7272
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7273
            
7274
0
#ifdef ERANGE_FILL
7275
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7276
0
#endif
7277
0
            status = NC_ERANGE;
7278
            
7279
0
#ifdef ERANGE_FILL
7280
0
            xp++; tp++; continue;
7281
0
#endif
7282
0
        }
7283
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7284
0
    }
7285
7286
7287
0
    if (rndup) {
7288
0
        (void) memcpy(xp, nada, (size_t)rndup);
7289
0
        xp += rndup;
7290
0
    }
7291
7292
0
    *xpp = (void *)xp;
7293
0
    return status;
7294
0
}
7295
7296
int
7297
ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7298
0
{
7299
0
    int status = NC_NOERR;
7300
0
    size_t rndup = nelems % X_ALIGN;
7301
0
    uchar *xp = (uchar *) *xpp;
7302
7303
0
    if (rndup) rndup = X_ALIGN - rndup;
7304
7305
0
    while (nelems-- != 0) {
7306
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7307
            
7308
0
#ifdef ERANGE_FILL
7309
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7310
0
#endif
7311
0
            status = NC_ERANGE;
7312
            
7313
0
#ifdef ERANGE_FILL
7314
0
            xp++; tp++; continue;
7315
0
#endif
7316
0
        }
7317
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7318
0
    }
7319
7320
7321
0
    if (rndup) {
7322
0
        (void) memcpy(xp, nada, (size_t)rndup);
7323
0
        xp += rndup;
7324
0
    }
7325
7326
0
    *xpp = (void *)xp;
7327
0
    return status;
7328
0
}
7329
7330
int
7331
ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7332
0
{
7333
0
    int status = NC_NOERR;
7334
0
    size_t rndup = nelems % X_ALIGN;
7335
0
    uchar *xp = (uchar *) *xpp;
7336
7337
0
    if (rndup) rndup = X_ALIGN - rndup;
7338
7339
0
    while (nelems-- != 0) {
7340
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7341
            
7342
0
#ifdef ERANGE_FILL
7343
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7344
0
#endif
7345
0
            status = NC_ERANGE;
7346
            
7347
0
#ifdef ERANGE_FILL
7348
0
            xp++; tp++; continue;
7349
0
#endif
7350
0
        }
7351
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7352
0
    }
7353
7354
7355
0
    if (rndup) {
7356
0
        (void) memcpy(xp, nada, (size_t)rndup);
7357
0
        xp += rndup;
7358
0
    }
7359
7360
0
    *xpp = (void *)xp;
7361
0
    return status;
7362
0
}
7363
7364
int
7365
ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7366
0
{
7367
0
    int status = NC_NOERR;
7368
0
    size_t rndup = nelems % X_ALIGN;
7369
0
    uchar *xp = (uchar *) *xpp;
7370
7371
0
    if (rndup) rndup = X_ALIGN - rndup;
7372
7373
0
    while (nelems-- != 0) {
7374
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7375
            
7376
0
#ifdef ERANGE_FILL
7377
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7378
0
#endif
7379
0
            status = NC_ERANGE;
7380
            
7381
0
#ifdef ERANGE_FILL
7382
0
            xp++; tp++; continue;
7383
0
#endif
7384
0
        }
7385
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7386
0
    }
7387
7388
7389
0
    if (rndup) {
7390
0
        (void) memcpy(xp, nada, (size_t)rndup);
7391
0
        xp += rndup;
7392
0
    }
7393
7394
0
    *xpp = (void *)xp;
7395
0
    return status;
7396
0
}
7397
7398
int
7399
ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7400
0
{
7401
0
    int status = NC_NOERR;
7402
0
    size_t rndup = nelems % X_ALIGN;
7403
0
    uchar *xp = (uchar *) *xpp;
7404
7405
0
    if (rndup) rndup = X_ALIGN - rndup;
7406
7407
0
    while (nelems-- != 0) {
7408
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7409
            
7410
0
#ifdef ERANGE_FILL
7411
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7412
0
#endif
7413
0
            status = NC_ERANGE;
7414
            
7415
0
#ifdef ERANGE_FILL
7416
0
            xp++; tp++; continue;
7417
0
#endif
7418
0
        }
7419
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7420
0
    }
7421
7422
7423
0
    if (rndup) {
7424
0
        (void) memcpy(xp, nada, (size_t)rndup);
7425
0
        xp += rndup;
7426
0
    }
7427
7428
0
    *xpp = (void *)xp;
7429
0
    return status;
7430
0
}
7431
7432
int
7433
ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7434
0
{
7435
0
    int status = NC_NOERR;
7436
0
    size_t rndup = nelems % X_ALIGN;
7437
0
    uchar *xp = (uchar *) *xpp;
7438
7439
0
    if (rndup) rndup = X_ALIGN - rndup;
7440
7441
0
    while (nelems-- != 0) {
7442
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7443
            
7444
0
#ifdef ERANGE_FILL
7445
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7446
0
#endif
7447
0
            status = NC_ERANGE;
7448
            
7449
0
#ifdef ERANGE_FILL
7450
0
            xp++; tp++; continue;
7451
0
#endif
7452
0
        }
7453
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7454
0
    }
7455
7456
7457
0
    if (rndup) {
7458
0
        (void) memcpy(xp, nada, (size_t)rndup);
7459
0
        xp += rndup;
7460
0
    }
7461
7462
0
    *xpp = (void *)xp;
7463
0
    return status;
7464
0
}
7465
7466
int
7467
ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7468
0
{
7469
0
    int status = NC_NOERR;
7470
0
    size_t rndup = nelems % X_ALIGN;
7471
0
    uchar *xp = (uchar *) *xpp;
7472
7473
0
    if (rndup) rndup = X_ALIGN - rndup;
7474
7475
0
    while (nelems-- != 0) {
7476
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7477
            
7478
0
#ifdef ERANGE_FILL
7479
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7480
0
#endif
7481
0
            status = NC_ERANGE;
7482
            
7483
0
#ifdef ERANGE_FILL
7484
0
            xp++; tp++; continue;
7485
0
#endif
7486
0
        }
7487
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7488
0
    }
7489
7490
7491
0
    if (rndup) {
7492
0
        (void) memcpy(xp, nada, (size_t)rndup);
7493
0
        xp += rndup;
7494
0
    }
7495
7496
0
    *xpp = (void *)xp;
7497
0
    return status;
7498
0
}
7499
7500
int
7501
ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7502
0
{
7503
0
    int status = NC_NOERR;
7504
0
    size_t rndup = nelems % X_ALIGN;
7505
0
    uchar *xp = (uchar *) *xpp;
7506
7507
0
    if (rndup) rndup = X_ALIGN - rndup;
7508
7509
0
    while (nelems-- != 0) {
7510
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7511
            
7512
0
#ifdef ERANGE_FILL
7513
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7514
0
#endif
7515
0
            status = NC_ERANGE;
7516
            
7517
0
#ifdef ERANGE_FILL
7518
0
            xp++; tp++; continue;
7519
0
#endif
7520
0
        }
7521
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7522
0
    }
7523
7524
7525
0
    if (rndup) {
7526
0
        (void) memcpy(xp, nada, (size_t)rndup);
7527
0
        xp += rndup;
7528
0
    }
7529
7530
0
    *xpp = (void *)xp;
7531
0
    return status;
7532
0
}
7533
7534
int
7535
ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7536
0
{
7537
0
    int status = NC_NOERR;
7538
0
    size_t rndup = nelems % X_ALIGN;
7539
0
    uchar *xp = (uchar *) *xpp;
7540
7541
0
    if (rndup) rndup = X_ALIGN - rndup;
7542
7543
0
    while (nelems-- != 0) {
7544
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7545
            
7546
0
#ifdef ERANGE_FILL
7547
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7548
0
#endif
7549
0
            status = NC_ERANGE;
7550
            
7551
0
#ifdef ERANGE_FILL
7552
0
            xp++; tp++; continue;
7553
0
#endif
7554
0
        }
7555
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7556
0
    }
7557
7558
7559
0
    if (rndup) {
7560
0
        (void) memcpy(xp, nada, (size_t)rndup);
7561
0
        xp += rndup;
7562
0
    }
7563
7564
0
    *xpp = (void *)xp;
7565
0
    return status;
7566
0
}
7567
7568
7569
/* short ---------------------------------------------------------------------*/
7570
7571
#if X_SIZEOF_SHORT == SIZEOF_SHORT
7572
/* optimized version */
7573
int
7574
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7575
0
{
7576
#ifdef WORDS_BIGENDIAN
7577
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
7578
# else
7579
0
  swapn2b(tp, *xpp, nelems);
7580
0
# endif
7581
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
7582
0
  return NC_NOERR;
7583
0
}
7584
#else
7585
int
7586
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7587
{
7588
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7589
7590
 /* basic algorithm is:
7591
  *   - ensure sane alignment of input data
7592
  *   - copy (conversion happens automatically) input data
7593
  *     to output
7594
  *   - update xpp to point at next unconverted input, and tp to point
7595
  *     at next location for converted output
7596
  */
7597
  long i, j, ni;
7598
  short tmp[LOOPCNT];        /* in case input is misaligned */
7599
  short *xp;
7600
  int nrange = 0;         /* number of range errors */
7601
  int realign = 0;        /* "do we need to fix input data alignment?" */
7602
  long cxp = (long) *((char**)xpp);
7603
7604
  realign = (cxp & 7) % SIZEOF_SHORT;
7605
  /* sjl: manually stripmine so we can limit amount of
7606
   * vector work space reserved to LOOPCNT elements. Also
7607
   * makes vectorisation easy */
7608
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7609
    ni=Min(nelems-j,LOOPCNT);
7610
    if (realign) {
7611
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7612
      xp = tmp;
7613
    } else {
7614
      xp = (short *) *xpp;
7615
    }
7616
   /* copy the next block */
7617
#pragma cdir loopcnt=LOOPCNT
7618
#pragma cdir shortloop
7619
    for (i=0; i<ni; i++) {
7620
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
7621
     /* test for range errors (not always needed but do it anyway) */
7622
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7623
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7624
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
7625
    }
7626
   /* update xpp and tp */
7627
    if (realign) xp = (short *) *xpp;
7628
    xp += ni;
7629
    tp += ni;
7630
    *xpp = (void*)xp;
7631
  }
7632
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7633
7634
#else   /* not SX */
7635
  const char *xp = (const char *) *xpp;
7636
  int status = NC_NOERR;
7637
7638
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7639
  {
7640
    const int lstatus = ncx_get_short_short(xp, tp);
7641
    if (status == NC_NOERR) /* report the first encountered error */
7642
      status = lstatus;
7643
  }
7644
7645
  *xpp = (const void *)xp;
7646
  return status;
7647
#endif
7648
}
7649
7650
#endif
7651
int
7652
ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
7653
0
{
7654
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7655
7656
 /* basic algorithm is:
7657
  *   - ensure sane alignment of input data
7658
  *   - copy (conversion happens automatically) input data
7659
  *     to output
7660
  *   - update xpp to point at next unconverted input, and tp to point
7661
  *     at next location for converted output
7662
  */
7663
  long i, j, ni;
7664
  short tmp[LOOPCNT];        /* in case input is misaligned */
7665
  short *xp;
7666
  int nrange = 0;         /* number of range errors */
7667
  int realign = 0;        /* "do we need to fix input data alignment?" */
7668
  long cxp = (long) *((char**)xpp);
7669
7670
  realign = (cxp & 7) % SIZEOF_SHORT;
7671
  /* sjl: manually stripmine so we can limit amount of
7672
   * vector work space reserved to LOOPCNT elements. Also
7673
   * makes vectorisation easy */
7674
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7675
    ni=Min(nelems-j,LOOPCNT);
7676
    if (realign) {
7677
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7678
      xp = tmp;
7679
    } else {
7680
      xp = (short *) *xpp;
7681
    }
7682
   /* copy the next block */
7683
#pragma cdir loopcnt=LOOPCNT
7684
#pragma cdir shortloop
7685
    for (i=0; i<ni; i++) {
7686
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
7687
     /* test for range errors (not always needed but do it anyway) */
7688
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7689
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7690
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
7691
    }
7692
   /* update xpp and tp */
7693
    if (realign) xp = (short *) *xpp;
7694
    xp += ni;
7695
    tp += ni;
7696
    *xpp = (void*)xp;
7697
  }
7698
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7699
7700
#else   /* not SX */
7701
0
  const char *xp = (const char *) *xpp;
7702
0
  int status = NC_NOERR;
7703
7704
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7705
0
  {
7706
0
    const int lstatus = ncx_get_short_schar(xp, tp);
7707
0
    if (status == NC_NOERR) /* report the first encountered error */
7708
0
      status = lstatus;
7709
0
  }
7710
7711
0
  *xpp = (const void *)xp;
7712
0
  return status;
7713
0
#endif
7714
0
}
7715
7716
int
7717
ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
7718
0
{
7719
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7720
7721
 /* basic algorithm is:
7722
  *   - ensure sane alignment of input data
7723
  *   - copy (conversion happens automatically) input data
7724
  *     to output
7725
  *   - update xpp to point at next unconverted input, and tp to point
7726
  *     at next location for converted output
7727
  */
7728
  long i, j, ni;
7729
  short tmp[LOOPCNT];        /* in case input is misaligned */
7730
  short *xp;
7731
  int nrange = 0;         /* number of range errors */
7732
  int realign = 0;        /* "do we need to fix input data alignment?" */
7733
  long cxp = (long) *((char**)xpp);
7734
7735
  realign = (cxp & 7) % SIZEOF_SHORT;
7736
  /* sjl: manually stripmine so we can limit amount of
7737
   * vector work space reserved to LOOPCNT elements. Also
7738
   * makes vectorisation easy */
7739
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7740
    ni=Min(nelems-j,LOOPCNT);
7741
    if (realign) {
7742
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7743
      xp = tmp;
7744
    } else {
7745
      xp = (short *) *xpp;
7746
    }
7747
   /* copy the next block */
7748
#pragma cdir loopcnt=LOOPCNT
7749
#pragma cdir shortloop
7750
    for (i=0; i<ni; i++) {
7751
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
7752
     /* test for range errors (not always needed but do it anyway) */
7753
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7754
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7755
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
7756
    }
7757
   /* update xpp and tp */
7758
    if (realign) xp = (short *) *xpp;
7759
    xp += ni;
7760
    tp += ni;
7761
    *xpp = (void*)xp;
7762
  }
7763
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7764
7765
#else   /* not SX */
7766
0
  const char *xp = (const char *) *xpp;
7767
0
  int status = NC_NOERR;
7768
7769
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7770
0
  {
7771
0
    const int lstatus = ncx_get_short_int(xp, tp);
7772
0
    if (status == NC_NOERR) /* report the first encountered error */
7773
0
      status = lstatus;
7774
0
  }
7775
7776
0
  *xpp = (const void *)xp;
7777
0
  return status;
7778
0
#endif
7779
0
}
7780
7781
int
7782
ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
7783
0
{
7784
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7785
7786
 /* basic algorithm is:
7787
  *   - ensure sane alignment of input data
7788
  *   - copy (conversion happens automatically) input data
7789
  *     to output
7790
  *   - update xpp to point at next unconverted input, and tp to point
7791
  *     at next location for converted output
7792
  */
7793
  long i, j, ni;
7794
  short tmp[LOOPCNT];        /* in case input is misaligned */
7795
  short *xp;
7796
  int nrange = 0;         /* number of range errors */
7797
  int realign = 0;        /* "do we need to fix input data alignment?" */
7798
  long cxp = (long) *((char**)xpp);
7799
7800
  realign = (cxp & 7) % SIZEOF_SHORT;
7801
  /* sjl: manually stripmine so we can limit amount of
7802
   * vector work space reserved to LOOPCNT elements. Also
7803
   * makes vectorisation easy */
7804
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7805
    ni=Min(nelems-j,LOOPCNT);
7806
    if (realign) {
7807
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7808
      xp = tmp;
7809
    } else {
7810
      xp = (short *) *xpp;
7811
    }
7812
   /* copy the next block */
7813
#pragma cdir loopcnt=LOOPCNT
7814
#pragma cdir shortloop
7815
    for (i=0; i<ni; i++) {
7816
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
7817
     /* test for range errors (not always needed but do it anyway) */
7818
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7819
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7820
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
7821
    }
7822
   /* update xpp and tp */
7823
    if (realign) xp = (short *) *xpp;
7824
    xp += ni;
7825
    tp += ni;
7826
    *xpp = (void*)xp;
7827
  }
7828
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7829
7830
#else   /* not SX */
7831
0
  const char *xp = (const char *) *xpp;
7832
0
  int status = NC_NOERR;
7833
7834
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7835
0
  {
7836
0
    const int lstatus = ncx_get_short_long(xp, tp);
7837
0
    if (status == NC_NOERR) /* report the first encountered error */
7838
0
      status = lstatus;
7839
0
  }
7840
7841
0
  *xpp = (const void *)xp;
7842
0
  return status;
7843
0
#endif
7844
0
}
7845
7846
int
7847
ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
7848
0
{
7849
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7850
7851
 /* basic algorithm is:
7852
  *   - ensure sane alignment of input data
7853
  *   - copy (conversion happens automatically) input data
7854
  *     to output
7855
  *   - update xpp to point at next unconverted input, and tp to point
7856
  *     at next location for converted output
7857
  */
7858
  long i, j, ni;
7859
  short tmp[LOOPCNT];        /* in case input is misaligned */
7860
  short *xp;
7861
  int nrange = 0;         /* number of range errors */
7862
  int realign = 0;        /* "do we need to fix input data alignment?" */
7863
  long cxp = (long) *((char**)xpp);
7864
7865
  realign = (cxp & 7) % SIZEOF_SHORT;
7866
  /* sjl: manually stripmine so we can limit amount of
7867
   * vector work space reserved to LOOPCNT elements. Also
7868
   * makes vectorisation easy */
7869
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7870
    ni=Min(nelems-j,LOOPCNT);
7871
    if (realign) {
7872
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7873
      xp = tmp;
7874
    } else {
7875
      xp = (short *) *xpp;
7876
    }
7877
   /* copy the next block */
7878
#pragma cdir loopcnt=LOOPCNT
7879
#pragma cdir shortloop
7880
    for (i=0; i<ni; i++) {
7881
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
7882
     /* test for range errors (not always needed but do it anyway) */
7883
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7884
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7885
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
7886
    }
7887
   /* update xpp and tp */
7888
    if (realign) xp = (short *) *xpp;
7889
    xp += ni;
7890
    tp += ni;
7891
    *xpp = (void*)xp;
7892
  }
7893
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7894
7895
#else   /* not SX */
7896
0
  const char *xp = (const char *) *xpp;
7897
0
  int status = NC_NOERR;
7898
7899
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7900
0
  {
7901
0
    const int lstatus = ncx_get_short_float(xp, tp);
7902
0
    if (status == NC_NOERR) /* report the first encountered error */
7903
0
      status = lstatus;
7904
0
  }
7905
7906
0
  *xpp = (const void *)xp;
7907
0
  return status;
7908
0
#endif
7909
0
}
7910
7911
int
7912
ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
7913
0
{
7914
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7915
7916
 /* basic algorithm is:
7917
  *   - ensure sane alignment of input data
7918
  *   - copy (conversion happens automatically) input data
7919
  *     to output
7920
  *   - update xpp to point at next unconverted input, and tp to point
7921
  *     at next location for converted output
7922
  */
7923
  long i, j, ni;
7924
  short tmp[LOOPCNT];        /* in case input is misaligned */
7925
  short *xp;
7926
  int nrange = 0;         /* number of range errors */
7927
  int realign = 0;        /* "do we need to fix input data alignment?" */
7928
  long cxp = (long) *((char**)xpp);
7929
7930
  realign = (cxp & 7) % SIZEOF_SHORT;
7931
  /* sjl: manually stripmine so we can limit amount of
7932
   * vector work space reserved to LOOPCNT elements. Also
7933
   * makes vectorisation easy */
7934
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7935
    ni=Min(nelems-j,LOOPCNT);
7936
    if (realign) {
7937
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7938
      xp = tmp;
7939
    } else {
7940
      xp = (short *) *xpp;
7941
    }
7942
   /* copy the next block */
7943
#pragma cdir loopcnt=LOOPCNT
7944
#pragma cdir shortloop
7945
    for (i=0; i<ni; i++) {
7946
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
7947
     /* test for range errors (not always needed but do it anyway) */
7948
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7949
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7950
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
7951
    }
7952
   /* update xpp and tp */
7953
    if (realign) xp = (short *) *xpp;
7954
    xp += ni;
7955
    tp += ni;
7956
    *xpp = (void*)xp;
7957
  }
7958
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7959
7960
#else   /* not SX */
7961
0
  const char *xp = (const char *) *xpp;
7962
0
  int status = NC_NOERR;
7963
7964
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7965
0
  {
7966
0
    const int lstatus = ncx_get_short_double(xp, tp);
7967
0
    if (status == NC_NOERR) /* report the first encountered error */
7968
0
      status = lstatus;
7969
0
  }
7970
7971
0
  *xpp = (const void *)xp;
7972
0
  return status;
7973
0
#endif
7974
0
}
7975
7976
int
7977
ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
7978
0
{
7979
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7980
7981
 /* basic algorithm is:
7982
  *   - ensure sane alignment of input data
7983
  *   - copy (conversion happens automatically) input data
7984
  *     to output
7985
  *   - update xpp to point at next unconverted input, and tp to point
7986
  *     at next location for converted output
7987
  */
7988
  long i, j, ni;
7989
  short tmp[LOOPCNT];        /* in case input is misaligned */
7990
  short *xp;
7991
  int nrange = 0;         /* number of range errors */
7992
  int realign = 0;        /* "do we need to fix input data alignment?" */
7993
  long cxp = (long) *((char**)xpp);
7994
7995
  realign = (cxp & 7) % SIZEOF_SHORT;
7996
  /* sjl: manually stripmine so we can limit amount of
7997
   * vector work space reserved to LOOPCNT elements. Also
7998
   * makes vectorisation easy */
7999
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8000
    ni=Min(nelems-j,LOOPCNT);
8001
    if (realign) {
8002
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8003
      xp = tmp;
8004
    } else {
8005
      xp = (short *) *xpp;
8006
    }
8007
   /* copy the next block */
8008
#pragma cdir loopcnt=LOOPCNT
8009
#pragma cdir shortloop
8010
    for (i=0; i<ni; i++) {
8011
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
8012
     /* test for range errors (not always needed but do it anyway) */
8013
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8014
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8015
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
8016
    }
8017
   /* update xpp and tp */
8018
    if (realign) xp = (short *) *xpp;
8019
    xp += ni;
8020
    tp += ni;
8021
    *xpp = (void*)xp;
8022
  }
8023
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8024
8025
#else   /* not SX */
8026
0
  const char *xp = (const char *) *xpp;
8027
0
  int status = NC_NOERR;
8028
8029
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8030
0
  {
8031
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8032
0
    if (status == NC_NOERR) /* report the first encountered error */
8033
0
      status = lstatus;
8034
0
  }
8035
8036
0
  *xpp = (const void *)xp;
8037
0
  return status;
8038
0
#endif
8039
0
}
8040
8041
int
8042
ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8043
0
{
8044
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8045
8046
 /* basic algorithm is:
8047
  *   - ensure sane alignment of input data
8048
  *   - copy (conversion happens automatically) input data
8049
  *     to output
8050
  *   - update xpp to point at next unconverted input, and tp to point
8051
  *     at next location for converted output
8052
  */
8053
  long i, j, ni;
8054
  short tmp[LOOPCNT];        /* in case input is misaligned */
8055
  short *xp;
8056
  int nrange = 0;         /* number of range errors */
8057
  int realign = 0;        /* "do we need to fix input data alignment?" */
8058
  long cxp = (long) *((char**)xpp);
8059
8060
  realign = (cxp & 7) % SIZEOF_SHORT;
8061
  /* sjl: manually stripmine so we can limit amount of
8062
   * vector work space reserved to LOOPCNT elements. Also
8063
   * makes vectorisation easy */
8064
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8065
    ni=Min(nelems-j,LOOPCNT);
8066
    if (realign) {
8067
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8068
      xp = tmp;
8069
    } else {
8070
      xp = (short *) *xpp;
8071
    }
8072
   /* copy the next block */
8073
#pragma cdir loopcnt=LOOPCNT
8074
#pragma cdir shortloop
8075
    for (i=0; i<ni; i++) {
8076
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
8077
     /* test for range errors (not always needed but do it anyway) */
8078
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8079
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8080
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
8081
    }
8082
   /* update xpp and tp */
8083
    if (realign) xp = (short *) *xpp;
8084
    xp += ni;
8085
    tp += ni;
8086
    *xpp = (void*)xp;
8087
  }
8088
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8089
8090
#else   /* not SX */
8091
0
  const char *xp = (const char *) *xpp;
8092
0
  int status = NC_NOERR;
8093
8094
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8095
0
  {
8096
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8097
0
    if (status == NC_NOERR) /* report the first encountered error */
8098
0
      status = lstatus;
8099
0
  }
8100
8101
0
  *xpp = (const void *)xp;
8102
0
  return status;
8103
0
#endif
8104
0
}
8105
8106
int
8107
ncx_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8108
0
{
8109
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8110
8111
 /* basic algorithm is:
8112
  *   - ensure sane alignment of input data
8113
  *   - copy (conversion happens automatically) input data
8114
  *     to output
8115
  *   - update xpp to point at next unconverted input, and tp to point
8116
  *     at next location for converted output
8117
  */
8118
  long i, j, ni;
8119
  short tmp[LOOPCNT];        /* in case input is misaligned */
8120
  short *xp;
8121
  int nrange = 0;         /* number of range errors */
8122
  int realign = 0;        /* "do we need to fix input data alignment?" */
8123
  long cxp = (long) *((char**)xpp);
8124
8125
  realign = (cxp & 7) % SIZEOF_SHORT;
8126
  /* sjl: manually stripmine so we can limit amount of
8127
   * vector work space reserved to LOOPCNT elements. Also
8128
   * makes vectorisation easy */
8129
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8130
    ni=Min(nelems-j,LOOPCNT);
8131
    if (realign) {
8132
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8133
      xp = tmp;
8134
    } else {
8135
      xp = (short *) *xpp;
8136
    }
8137
   /* copy the next block */
8138
#pragma cdir loopcnt=LOOPCNT
8139
#pragma cdir shortloop
8140
    for (i=0; i<ni; i++) {
8141
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
8142
     /* test for range errors (not always needed but do it anyway) */
8143
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8144
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8145
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
8146
    }
8147
   /* update xpp and tp */
8148
    if (realign) xp = (short *) *xpp;
8149
    xp += ni;
8150
    tp += ni;
8151
    *xpp = (void*)xp;
8152
  }
8153
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8154
8155
#else   /* not SX */
8156
0
  const char *xp = (const char *) *xpp;
8157
0
  int status = NC_NOERR;
8158
8159
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8160
0
  {
8161
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8162
0
    if (status == NC_NOERR) /* report the first encountered error */
8163
0
      status = lstatus;
8164
0
  }
8165
8166
0
  *xpp = (const void *)xp;
8167
0
  return status;
8168
0
#endif
8169
0
}
8170
8171
int
8172
ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8173
0
{
8174
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8175
8176
 /* basic algorithm is:
8177
  *   - ensure sane alignment of input data
8178
  *   - copy (conversion happens automatically) input data
8179
  *     to output
8180
  *   - update xpp to point at next unconverted input, and tp to point
8181
  *     at next location for converted output
8182
  */
8183
  long i, j, ni;
8184
  short tmp[LOOPCNT];        /* in case input is misaligned */
8185
  short *xp;
8186
  int nrange = 0;         /* number of range errors */
8187
  int realign = 0;        /* "do we need to fix input data alignment?" */
8188
  long cxp = (long) *((char**)xpp);
8189
8190
  realign = (cxp & 7) % SIZEOF_SHORT;
8191
  /* sjl: manually stripmine so we can limit amount of
8192
   * vector work space reserved to LOOPCNT elements. Also
8193
   * makes vectorisation easy */
8194
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8195
    ni=Min(nelems-j,LOOPCNT);
8196
    if (realign) {
8197
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8198
      xp = tmp;
8199
    } else {
8200
      xp = (short *) *xpp;
8201
    }
8202
   /* copy the next block */
8203
#pragma cdir loopcnt=LOOPCNT
8204
#pragma cdir shortloop
8205
    for (i=0; i<ni; i++) {
8206
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
8207
     /* test for range errors (not always needed but do it anyway) */
8208
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8209
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8210
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
8211
    }
8212
   /* update xpp and tp */
8213
    if (realign) xp = (short *) *xpp;
8214
    xp += ni;
8215
    tp += ni;
8216
    *xpp = (void*)xp;
8217
  }
8218
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8219
8220
#else   /* not SX */
8221
0
  const char *xp = (const char *) *xpp;
8222
0
  int status = NC_NOERR;
8223
8224
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8225
0
  {
8226
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8227
0
    if (status == NC_NOERR) /* report the first encountered error */
8228
0
      status = lstatus;
8229
0
  }
8230
8231
0
  *xpp = (const void *)xp;
8232
0
  return status;
8233
0
#endif
8234
0
}
8235
8236
int
8237
ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8238
0
{
8239
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8240
8241
 /* basic algorithm is:
8242
  *   - ensure sane alignment of input data
8243
  *   - copy (conversion happens automatically) input data
8244
  *     to output
8245
  *   - update xpp to point at next unconverted input, and tp to point
8246
  *     at next location for converted output
8247
  */
8248
  long i, j, ni;
8249
  short tmp[LOOPCNT];        /* in case input is misaligned */
8250
  short *xp;
8251
  int nrange = 0;         /* number of range errors */
8252
  int realign = 0;        /* "do we need to fix input data alignment?" */
8253
  long cxp = (long) *((char**)xpp);
8254
8255
  realign = (cxp & 7) % SIZEOF_SHORT;
8256
  /* sjl: manually stripmine so we can limit amount of
8257
   * vector work space reserved to LOOPCNT elements. Also
8258
   * makes vectorisation easy */
8259
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8260
    ni=Min(nelems-j,LOOPCNT);
8261
    if (realign) {
8262
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8263
      xp = tmp;
8264
    } else {
8265
      xp = (short *) *xpp;
8266
    }
8267
   /* copy the next block */
8268
#pragma cdir loopcnt=LOOPCNT
8269
#pragma cdir shortloop
8270
    for (i=0; i<ni; i++) {
8271
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
8272
     /* test for range errors (not always needed but do it anyway) */
8273
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8274
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8275
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
8276
    }
8277
   /* update xpp and tp */
8278
    if (realign) xp = (short *) *xpp;
8279
    xp += ni;
8280
    tp += ni;
8281
    *xpp = (void*)xp;
8282
  }
8283
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8284
8285
#else   /* not SX */
8286
0
  const char *xp = (const char *) *xpp;
8287
0
  int status = NC_NOERR;
8288
8289
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8290
0
  {
8291
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8292
0
    if (status == NC_NOERR) /* report the first encountered error */
8293
0
      status = lstatus;
8294
0
  }
8295
8296
0
  *xpp = (const void *)xp;
8297
0
  return status;
8298
0
#endif
8299
0
}
8300
8301
8302
int
8303
ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
8304
0
{
8305
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8306
8307
0
  const char *xp = (const char *) *xpp;
8308
0
  int status = NC_NOERR;
8309
8310
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8311
0
  {
8312
0
    const int lstatus = ncx_get_short_schar(xp, tp);
8313
0
    if (status == NC_NOERR) /* report the first encountered error */
8314
0
      status = lstatus;
8315
0
  }
8316
8317
0
  if (rndup != 0)
8318
0
    xp += X_SIZEOF_SHORT;
8319
8320
0
  *xpp = (void *)xp;
8321
0
  return status;
8322
0
}
8323
8324
int
8325
ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8326
0
{
8327
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8328
8329
0
  const char *xp = (const char *) *xpp;
8330
0
  int status = NC_NOERR;
8331
8332
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8333
0
  {
8334
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8335
0
    if (status == NC_NOERR) /* report the first encountered error */
8336
0
      status = lstatus;
8337
0
  }
8338
8339
0
  if (rndup != 0)
8340
0
    xp += X_SIZEOF_SHORT;
8341
8342
0
  *xpp = (void *)xp;
8343
0
  return status;
8344
0
}
8345
8346
int
8347
ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
8348
0
{
8349
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8350
8351
0
  const char *xp = (const char *) *xpp;
8352
0
  int status = NC_NOERR;
8353
8354
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8355
0
  {
8356
0
    const int lstatus = ncx_get_short_short(xp, tp);
8357
0
    if (status == NC_NOERR) /* report the first encountered error */
8358
0
      status = lstatus;
8359
0
  }
8360
8361
0
  if (rndup != 0)
8362
0
    xp += X_SIZEOF_SHORT;
8363
8364
0
  *xpp = (void *)xp;
8365
0
  return status;
8366
0
}
8367
8368
int
8369
ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
8370
0
{
8371
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8372
8373
0
  const char *xp = (const char *) *xpp;
8374
0
  int status = NC_NOERR;
8375
8376
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8377
0
  {
8378
0
    const int lstatus = ncx_get_short_int(xp, tp);
8379
0
    if (status == NC_NOERR) /* report the first encountered error */
8380
0
      status = lstatus;
8381
0
  }
8382
8383
0
  if (rndup != 0)
8384
0
    xp += X_SIZEOF_SHORT;
8385
8386
0
  *xpp = (void *)xp;
8387
0
  return status;
8388
0
}
8389
8390
int
8391
ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
8392
0
{
8393
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8394
8395
0
  const char *xp = (const char *) *xpp;
8396
0
  int status = NC_NOERR;
8397
8398
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8399
0
  {
8400
0
    const int lstatus = ncx_get_short_long(xp, tp);
8401
0
    if (status == NC_NOERR) /* report the first encountered error */
8402
0
      status = lstatus;
8403
0
  }
8404
8405
0
  if (rndup != 0)
8406
0
    xp += X_SIZEOF_SHORT;
8407
8408
0
  *xpp = (void *)xp;
8409
0
  return status;
8410
0
}
8411
8412
int
8413
ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
8414
0
{
8415
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8416
8417
0
  const char *xp = (const char *) *xpp;
8418
0
  int status = NC_NOERR;
8419
8420
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8421
0
  {
8422
0
    const int lstatus = ncx_get_short_float(xp, tp);
8423
0
    if (status == NC_NOERR) /* report the first encountered error */
8424
0
      status = lstatus;
8425
0
  }
8426
8427
0
  if (rndup != 0)
8428
0
    xp += X_SIZEOF_SHORT;
8429
8430
0
  *xpp = (void *)xp;
8431
0
  return status;
8432
0
}
8433
8434
int
8435
ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
8436
0
{
8437
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8438
8439
0
  const char *xp = (const char *) *xpp;
8440
0
  int status = NC_NOERR;
8441
8442
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8443
0
  {
8444
0
    const int lstatus = ncx_get_short_double(xp, tp);
8445
0
    if (status == NC_NOERR) /* report the first encountered error */
8446
0
      status = lstatus;
8447
0
  }
8448
8449
0
  if (rndup != 0)
8450
0
    xp += X_SIZEOF_SHORT;
8451
8452
0
  *xpp = (void *)xp;
8453
0
  return status;
8454
0
}
8455
8456
int
8457
ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8458
0
{
8459
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8460
8461
0
  const char *xp = (const char *) *xpp;
8462
0
  int status = NC_NOERR;
8463
8464
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8465
0
  {
8466
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8467
0
    if (status == NC_NOERR) /* report the first encountered error */
8468
0
      status = lstatus;
8469
0
  }
8470
8471
0
  if (rndup != 0)
8472
0
    xp += X_SIZEOF_SHORT;
8473
8474
0
  *xpp = (void *)xp;
8475
0
  return status;
8476
0
}
8477
8478
int
8479
ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8480
0
{
8481
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8482
8483
0
  const char *xp = (const char *) *xpp;
8484
0
  int status = NC_NOERR;
8485
8486
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8487
0
  {
8488
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8489
0
    if (status == NC_NOERR) /* report the first encountered error */
8490
0
      status = lstatus;
8491
0
  }
8492
8493
0
  if (rndup != 0)
8494
0
    xp += X_SIZEOF_SHORT;
8495
8496
0
  *xpp = (void *)xp;
8497
0
  return status;
8498
0
}
8499
8500
int
8501
ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8502
0
{
8503
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8504
8505
0
  const char *xp = (const char *) *xpp;
8506
0
  int status = NC_NOERR;
8507
8508
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8509
0
  {
8510
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8511
0
    if (status == NC_NOERR) /* report the first encountered error */
8512
0
      status = lstatus;
8513
0
  }
8514
8515
0
  if (rndup != 0)
8516
0
    xp += X_SIZEOF_SHORT;
8517
8518
0
  *xpp = (void *)xp;
8519
0
  return status;
8520
0
}
8521
8522
int
8523
ncx_pad_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8524
0
{
8525
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8526
8527
0
  const char *xp = (const char *) *xpp;
8528
0
  int status = NC_NOERR;
8529
8530
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8531
0
  {
8532
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8533
0
    if (status == NC_NOERR) /* report the first encountered error */
8534
0
      status = lstatus;
8535
0
  }
8536
8537
0
  if (rndup != 0)
8538
0
    xp += X_SIZEOF_SHORT;
8539
8540
0
  *xpp = (void *)xp;
8541
0
  return status;
8542
0
}
8543
8544
8545
#if X_SIZEOF_SHORT == SIZEOF_SHORT
8546
/* optimized version */
8547
int
8548
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8549
0
{
8550
#ifdef WORDS_BIGENDIAN
8551
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
8552
# else
8553
0
  swapn2b(*xpp, tp, nelems);
8554
0
# endif
8555
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
8556
0
  return NC_NOERR;
8557
0
}
8558
#else
8559
int
8560
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8561
{
8562
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8563
8564
 /* basic algorithm is:
8565
  *   - ensure sane alignment of output data
8566
  *   - copy (conversion happens automatically) input data
8567
  *     to output
8568
  *   - update tp to point at next unconverted input, and xpp to point
8569
  *     at next location for converted output
8570
  */
8571
  long i, j, ni;
8572
  short tmp[LOOPCNT];        /* in case input is misaligned */
8573
  short *xp;
8574
  int nrange = 0;         /* number of range errors */
8575
  int realign = 0;        /* "do we need to fix input data alignment?" */
8576
  long cxp = (long) *((char**)xpp);
8577
8578
  realign = (cxp & 7) % SIZEOF_SHORT;
8579
  /* sjl: manually stripmine so we can limit amount of
8580
   * vector work space reserved to LOOPCNT elements. Also
8581
   * makes vectorisation easy */
8582
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8583
    ni=Min(nelems-j,LOOPCNT);
8584
    if (realign) {
8585
      xp = tmp;
8586
    } else {
8587
      xp = (short *) *xpp;
8588
    }
8589
   /* copy the next block */
8590
#pragma cdir loopcnt=LOOPCNT
8591
#pragma cdir shortloop
8592
    for (i=0; i<ni; i++) {
8593
      /* the normal case: */
8594
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8595
     /* test for range errors (not always needed but do it anyway) */
8596
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8597
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8598
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8599
    }
8600
   /* copy workspace back if necessary */
8601
    if (realign) {
8602
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8603
      xp = (short *) *xpp;
8604
    }
8605
   /* update xpp and tp */
8606
    xp += ni;
8607
    tp += ni;
8608
    *xpp = (void*)xp;
8609
  }
8610
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8611
8612
#else   /* not SX */
8613
8614
  char *xp = (char *) *xpp;
8615
  int status = NC_NOERR;
8616
8617
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8618
  {
8619
    int lstatus = ncx_put_short_short(xp, tp, fillp);
8620
    if (status == NC_NOERR) /* report the first encountered error */
8621
      status = lstatus;
8622
  }
8623
8624
  *xpp = (void *)xp;
8625
  return status;
8626
#endif
8627
}
8628
8629
#endif
8630
int
8631
ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
8632
0
{
8633
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8634
8635
 /* basic algorithm is:
8636
  *   - ensure sane alignment of output data
8637
  *   - copy (conversion happens automatically) input data
8638
  *     to output
8639
  *   - update tp to point at next unconverted input, and xpp to point
8640
  *     at next location for converted output
8641
  */
8642
  long i, j, ni;
8643
  short tmp[LOOPCNT];        /* in case input is misaligned */
8644
  short *xp;
8645
  int nrange = 0;         /* number of range errors */
8646
  int realign = 0;        /* "do we need to fix input data alignment?" */
8647
  long cxp = (long) *((char**)xpp);
8648
8649
  realign = (cxp & 7) % SIZEOF_SHORT;
8650
  /* sjl: manually stripmine so we can limit amount of
8651
   * vector work space reserved to LOOPCNT elements. Also
8652
   * makes vectorisation easy */
8653
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8654
    ni=Min(nelems-j,LOOPCNT);
8655
    if (realign) {
8656
      xp = tmp;
8657
    } else {
8658
      xp = (short *) *xpp;
8659
    }
8660
   /* copy the next block */
8661
#pragma cdir loopcnt=LOOPCNT
8662
#pragma cdir shortloop
8663
    for (i=0; i<ni; i++) {
8664
      /* the normal case: */
8665
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8666
     /* test for range errors (not always needed but do it anyway) */
8667
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8668
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8669
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8670
    }
8671
   /* copy workspace back if necessary */
8672
    if (realign) {
8673
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8674
      xp = (short *) *xpp;
8675
    }
8676
   /* update xpp and tp */
8677
    xp += ni;
8678
    tp += ni;
8679
    *xpp = (void*)xp;
8680
  }
8681
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8682
8683
#else   /* not SX */
8684
8685
0
  char *xp = (char *) *xpp;
8686
0
  int status = NC_NOERR;
8687
8688
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8689
0
  {
8690
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
8691
0
    if (status == NC_NOERR) /* report the first encountered error */
8692
0
      status = lstatus;
8693
0
  }
8694
8695
0
  *xpp = (void *)xp;
8696
0
  return status;
8697
0
#endif
8698
0
}
8699
8700
int
8701
ncx_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
8702
0
{
8703
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8704
8705
 /* basic algorithm is:
8706
  *   - ensure sane alignment of output data
8707
  *   - copy (conversion happens automatically) input data
8708
  *     to output
8709
  *   - update tp to point at next unconverted input, and xpp to point
8710
  *     at next location for converted output
8711
  */
8712
  long i, j, ni;
8713
  short tmp[LOOPCNT];        /* in case input is misaligned */
8714
  short *xp;
8715
  int nrange = 0;         /* number of range errors */
8716
  int realign = 0;        /* "do we need to fix input data alignment?" */
8717
  long cxp = (long) *((char**)xpp);
8718
8719
  realign = (cxp & 7) % SIZEOF_SHORT;
8720
  /* sjl: manually stripmine so we can limit amount of
8721
   * vector work space reserved to LOOPCNT elements. Also
8722
   * makes vectorisation easy */
8723
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8724
    ni=Min(nelems-j,LOOPCNT);
8725
    if (realign) {
8726
      xp = tmp;
8727
    } else {
8728
      xp = (short *) *xpp;
8729
    }
8730
   /* copy the next block */
8731
#pragma cdir loopcnt=LOOPCNT
8732
#pragma cdir shortloop
8733
    for (i=0; i<ni; i++) {
8734
      /* the normal case: */
8735
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8736
     /* test for range errors (not always needed but do it anyway) */
8737
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8738
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8739
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8740
    }
8741
   /* copy workspace back if necessary */
8742
    if (realign) {
8743
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8744
      xp = (short *) *xpp;
8745
    }
8746
   /* update xpp and tp */
8747
    xp += ni;
8748
    tp += ni;
8749
    *xpp = (void*)xp;
8750
  }
8751
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8752
8753
#else   /* not SX */
8754
8755
0
  char *xp = (char *) *xpp;
8756
0
  int status = NC_NOERR;
8757
8758
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8759
0
  {
8760
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
8761
0
    if (status == NC_NOERR) /* report the first encountered error */
8762
0
      status = lstatus;
8763
0
  }
8764
8765
0
  *xpp = (void *)xp;
8766
0
  return status;
8767
0
#endif
8768
0
}
8769
8770
int
8771
ncx_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
8772
0
{
8773
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8774
8775
 /* basic algorithm is:
8776
  *   - ensure sane alignment of output data
8777
  *   - copy (conversion happens automatically) input data
8778
  *     to output
8779
  *   - update tp to point at next unconverted input, and xpp to point
8780
  *     at next location for converted output
8781
  */
8782
  long i, j, ni;
8783
  short tmp[LOOPCNT];        /* in case input is misaligned */
8784
  short *xp;
8785
  int nrange = 0;         /* number of range errors */
8786
  int realign = 0;        /* "do we need to fix input data alignment?" */
8787
  long cxp = (long) *((char**)xpp);
8788
8789
  realign = (cxp & 7) % SIZEOF_SHORT;
8790
  /* sjl: manually stripmine so we can limit amount of
8791
   * vector work space reserved to LOOPCNT elements. Also
8792
   * makes vectorisation easy */
8793
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8794
    ni=Min(nelems-j,LOOPCNT);
8795
    if (realign) {
8796
      xp = tmp;
8797
    } else {
8798
      xp = (short *) *xpp;
8799
    }
8800
   /* copy the next block */
8801
#pragma cdir loopcnt=LOOPCNT
8802
#pragma cdir shortloop
8803
    for (i=0; i<ni; i++) {
8804
      /* the normal case: */
8805
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8806
     /* test for range errors (not always needed but do it anyway) */
8807
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8808
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8809
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8810
    }
8811
   /* copy workspace back if necessary */
8812
    if (realign) {
8813
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8814
      xp = (short *) *xpp;
8815
    }
8816
   /* update xpp and tp */
8817
    xp += ni;
8818
    tp += ni;
8819
    *xpp = (void*)xp;
8820
  }
8821
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8822
8823
#else   /* not SX */
8824
8825
0
  char *xp = (char *) *xpp;
8826
0
  int status = NC_NOERR;
8827
8828
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8829
0
  {
8830
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
8831
0
    if (status == NC_NOERR) /* report the first encountered error */
8832
0
      status = lstatus;
8833
0
  }
8834
8835
0
  *xpp = (void *)xp;
8836
0
  return status;
8837
0
#endif
8838
0
}
8839
8840
int
8841
ncx_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
8842
0
{
8843
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8844
8845
 /* basic algorithm is:
8846
  *   - ensure sane alignment of output data
8847
  *   - copy (conversion happens automatically) input data
8848
  *     to output
8849
  *   - update tp to point at next unconverted input, and xpp to point
8850
  *     at next location for converted output
8851
  */
8852
  long i, j, ni;
8853
  short tmp[LOOPCNT];        /* in case input is misaligned */
8854
  short *xp;
8855
  int nrange = 0;         /* number of range errors */
8856
  int realign = 0;        /* "do we need to fix input data alignment?" */
8857
  long cxp = (long) *((char**)xpp);
8858
8859
  realign = (cxp & 7) % SIZEOF_SHORT;
8860
  /* sjl: manually stripmine so we can limit amount of
8861
   * vector work space reserved to LOOPCNT elements. Also
8862
   * makes vectorisation easy */
8863
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8864
    ni=Min(nelems-j,LOOPCNT);
8865
    if (realign) {
8866
      xp = tmp;
8867
    } else {
8868
      xp = (short *) *xpp;
8869
    }
8870
   /* copy the next block */
8871
#pragma cdir loopcnt=LOOPCNT
8872
#pragma cdir shortloop
8873
    for (i=0; i<ni; i++) {
8874
      /* the normal case: */
8875
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8876
     /* test for range errors (not always needed but do it anyway) */
8877
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8878
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8879
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8880
    }
8881
   /* copy workspace back if necessary */
8882
    if (realign) {
8883
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8884
      xp = (short *) *xpp;
8885
    }
8886
   /* update xpp and tp */
8887
    xp += ni;
8888
    tp += ni;
8889
    *xpp = (void*)xp;
8890
  }
8891
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8892
8893
#else   /* not SX */
8894
8895
0
  char *xp = (char *) *xpp;
8896
0
  int status = NC_NOERR;
8897
8898
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8899
0
  {
8900
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
8901
0
    if (status == NC_NOERR) /* report the first encountered error */
8902
0
      status = lstatus;
8903
0
  }
8904
8905
0
  *xpp = (void *)xp;
8906
0
  return status;
8907
0
#endif
8908
0
}
8909
8910
int
8911
ncx_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
8912
0
{
8913
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8914
8915
 /* basic algorithm is:
8916
  *   - ensure sane alignment of output data
8917
  *   - copy (conversion happens automatically) input data
8918
  *     to output
8919
  *   - update tp to point at next unconverted input, and xpp to point
8920
  *     at next location for converted output
8921
  */
8922
  long i, j, ni;
8923
  short tmp[LOOPCNT];        /* in case input is misaligned */
8924
  short *xp;
8925
  int nrange = 0;         /* number of range errors */
8926
  int realign = 0;        /* "do we need to fix input data alignment?" */
8927
  long cxp = (long) *((char**)xpp);
8928
8929
  realign = (cxp & 7) % SIZEOF_SHORT;
8930
  /* sjl: manually stripmine so we can limit amount of
8931
   * vector work space reserved to LOOPCNT elements. Also
8932
   * makes vectorisation easy */
8933
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8934
    ni=Min(nelems-j,LOOPCNT);
8935
    if (realign) {
8936
      xp = tmp;
8937
    } else {
8938
      xp = (short *) *xpp;
8939
    }
8940
   /* copy the next block */
8941
#pragma cdir loopcnt=LOOPCNT
8942
#pragma cdir shortloop
8943
    for (i=0; i<ni; i++) {
8944
      /* the normal case: */
8945
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8946
     /* test for range errors (not always needed but do it anyway) */
8947
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8948
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8949
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8950
    }
8951
   /* copy workspace back if necessary */
8952
    if (realign) {
8953
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8954
      xp = (short *) *xpp;
8955
    }
8956
   /* update xpp and tp */
8957
    xp += ni;
8958
    tp += ni;
8959
    *xpp = (void*)xp;
8960
  }
8961
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8962
8963
#else   /* not SX */
8964
8965
0
  char *xp = (char *) *xpp;
8966
0
  int status = NC_NOERR;
8967
8968
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8969
0
  {
8970
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
8971
0
    if (status == NC_NOERR) /* report the first encountered error */
8972
0
      status = lstatus;
8973
0
  }
8974
8975
0
  *xpp = (void *)xp;
8976
0
  return status;
8977
0
#endif
8978
0
}
8979
8980
int
8981
ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
8982
0
{
8983
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8984
8985
 /* basic algorithm is:
8986
  *   - ensure sane alignment of output data
8987
  *   - copy (conversion happens automatically) input data
8988
  *     to output
8989
  *   - update tp to point at next unconverted input, and xpp to point
8990
  *     at next location for converted output
8991
  */
8992
  long i, j, ni;
8993
  short tmp[LOOPCNT];        /* in case input is misaligned */
8994
  short *xp;
8995
  int nrange = 0;         /* number of range errors */
8996
  int realign = 0;        /* "do we need to fix input data alignment?" */
8997
  long cxp = (long) *((char**)xpp);
8998
8999
  realign = (cxp & 7) % SIZEOF_SHORT;
9000
  /* sjl: manually stripmine so we can limit amount of
9001
   * vector work space reserved to LOOPCNT elements. Also
9002
   * makes vectorisation easy */
9003
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9004
    ni=Min(nelems-j,LOOPCNT);
9005
    if (realign) {
9006
      xp = tmp;
9007
    } else {
9008
      xp = (short *) *xpp;
9009
    }
9010
   /* copy the next block */
9011
#pragma cdir loopcnt=LOOPCNT
9012
#pragma cdir shortloop
9013
    for (i=0; i<ni; i++) {
9014
      /* the normal case: */
9015
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9016
     /* test for range errors (not always needed but do it anyway) */
9017
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9018
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9019
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9020
    }
9021
   /* copy workspace back if necessary */
9022
    if (realign) {
9023
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9024
      xp = (short *) *xpp;
9025
    }
9026
   /* update xpp and tp */
9027
    xp += ni;
9028
    tp += ni;
9029
    *xpp = (void*)xp;
9030
  }
9031
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9032
9033
#else   /* not SX */
9034
9035
0
  char *xp = (char *) *xpp;
9036
0
  int status = NC_NOERR;
9037
9038
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9039
0
  {
9040
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9041
0
    if (status == NC_NOERR) /* report the first encountered error */
9042
0
      status = lstatus;
9043
0
  }
9044
9045
0
  *xpp = (void *)xp;
9046
0
  return status;
9047
0
#endif
9048
0
}
9049
9050
int
9051
ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9052
0
{
9053
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9054
9055
 /* basic algorithm is:
9056
  *   - ensure sane alignment of output data
9057
  *   - copy (conversion happens automatically) input data
9058
  *     to output
9059
  *   - update tp to point at next unconverted input, and xpp to point
9060
  *     at next location for converted output
9061
  */
9062
  long i, j, ni;
9063
  short tmp[LOOPCNT];        /* in case input is misaligned */
9064
  short *xp;
9065
  int nrange = 0;         /* number of range errors */
9066
  int realign = 0;        /* "do we need to fix input data alignment?" */
9067
  long cxp = (long) *((char**)xpp);
9068
9069
  realign = (cxp & 7) % SIZEOF_SHORT;
9070
  /* sjl: manually stripmine so we can limit amount of
9071
   * vector work space reserved to LOOPCNT elements. Also
9072
   * makes vectorisation easy */
9073
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9074
    ni=Min(nelems-j,LOOPCNT);
9075
    if (realign) {
9076
      xp = tmp;
9077
    } else {
9078
      xp = (short *) *xpp;
9079
    }
9080
   /* copy the next block */
9081
#pragma cdir loopcnt=LOOPCNT
9082
#pragma cdir shortloop
9083
    for (i=0; i<ni; i++) {
9084
      /* the normal case: */
9085
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9086
     /* test for range errors (not always needed but do it anyway) */
9087
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9088
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9089
      nrange += tp[i] > X_SHORT_MAX ;
9090
    }
9091
   /* copy workspace back if necessary */
9092
    if (realign) {
9093
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9094
      xp = (short *) *xpp;
9095
    }
9096
   /* update xpp and tp */
9097
    xp += ni;
9098
    tp += ni;
9099
    *xpp = (void*)xp;
9100
  }
9101
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9102
9103
#else   /* not SX */
9104
9105
0
  char *xp = (char *) *xpp;
9106
0
  int status = NC_NOERR;
9107
9108
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9109
0
  {
9110
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9111
0
    if (status == NC_NOERR) /* report the first encountered error */
9112
0
      status = lstatus;
9113
0
  }
9114
9115
0
  *xpp = (void *)xp;
9116
0
  return status;
9117
0
#endif
9118
0
}
9119
9120
int
9121
ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9122
0
{
9123
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9124
9125
 /* basic algorithm is:
9126
  *   - ensure sane alignment of output data
9127
  *   - copy (conversion happens automatically) input data
9128
  *     to output
9129
  *   - update tp to point at next unconverted input, and xpp to point
9130
  *     at next location for converted output
9131
  */
9132
  long i, j, ni;
9133
  short tmp[LOOPCNT];        /* in case input is misaligned */
9134
  short *xp;
9135
  int nrange = 0;         /* number of range errors */
9136
  int realign = 0;        /* "do we need to fix input data alignment?" */
9137
  long cxp = (long) *((char**)xpp);
9138
9139
  realign = (cxp & 7) % SIZEOF_SHORT;
9140
  /* sjl: manually stripmine so we can limit amount of
9141
   * vector work space reserved to LOOPCNT elements. Also
9142
   * makes vectorisation easy */
9143
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9144
    ni=Min(nelems-j,LOOPCNT);
9145
    if (realign) {
9146
      xp = tmp;
9147
    } else {
9148
      xp = (short *) *xpp;
9149
    }
9150
   /* copy the next block */
9151
#pragma cdir loopcnt=LOOPCNT
9152
#pragma cdir shortloop
9153
    for (i=0; i<ni; i++) {
9154
      /* the normal case: */
9155
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9156
     /* test for range errors (not always needed but do it anyway) */
9157
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9158
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9159
      nrange += tp[i] > X_SHORT_MAX ;
9160
    }
9161
   /* copy workspace back if necessary */
9162
    if (realign) {
9163
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9164
      xp = (short *) *xpp;
9165
    }
9166
   /* update xpp and tp */
9167
    xp += ni;
9168
    tp += ni;
9169
    *xpp = (void*)xp;
9170
  }
9171
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9172
9173
#else   /* not SX */
9174
9175
0
  char *xp = (char *) *xpp;
9176
0
  int status = NC_NOERR;
9177
9178
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9179
0
  {
9180
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9181
0
    if (status == NC_NOERR) /* report the first encountered error */
9182
0
      status = lstatus;
9183
0
  }
9184
9185
0
  *xpp = (void *)xp;
9186
0
  return status;
9187
0
#endif
9188
0
}
9189
9190
int
9191
ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9192
0
{
9193
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9194
9195
 /* basic algorithm is:
9196
  *   - ensure sane alignment of output data
9197
  *   - copy (conversion happens automatically) input data
9198
  *     to output
9199
  *   - update tp to point at next unconverted input, and xpp to point
9200
  *     at next location for converted output
9201
  */
9202
  long i, j, ni;
9203
  short tmp[LOOPCNT];        /* in case input is misaligned */
9204
  short *xp;
9205
  int nrange = 0;         /* number of range errors */
9206
  int realign = 0;        /* "do we need to fix input data alignment?" */
9207
  long cxp = (long) *((char**)xpp);
9208
9209
  realign = (cxp & 7) % SIZEOF_SHORT;
9210
  /* sjl: manually stripmine so we can limit amount of
9211
   * vector work space reserved to LOOPCNT elements. Also
9212
   * makes vectorisation easy */
9213
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9214
    ni=Min(nelems-j,LOOPCNT);
9215
    if (realign) {
9216
      xp = tmp;
9217
    } else {
9218
      xp = (short *) *xpp;
9219
    }
9220
   /* copy the next block */
9221
#pragma cdir loopcnt=LOOPCNT
9222
#pragma cdir shortloop
9223
    for (i=0; i<ni; i++) {
9224
      /* the normal case: */
9225
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9226
     /* test for range errors (not always needed but do it anyway) */
9227
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9228
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9229
      nrange += tp[i] > X_SHORT_MAX ;
9230
    }
9231
   /* copy workspace back if necessary */
9232
    if (realign) {
9233
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9234
      xp = (short *) *xpp;
9235
    }
9236
   /* update xpp and tp */
9237
    xp += ni;
9238
    tp += ni;
9239
    *xpp = (void*)xp;
9240
  }
9241
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9242
9243
#else   /* not SX */
9244
9245
0
  char *xp = (char *) *xpp;
9246
0
  int status = NC_NOERR;
9247
9248
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9249
0
  {
9250
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9251
0
    if (status == NC_NOERR) /* report the first encountered error */
9252
0
      status = lstatus;
9253
0
  }
9254
9255
0
  *xpp = (void *)xp;
9256
0
  return status;
9257
0
#endif
9258
0
}
9259
9260
int
9261
ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9262
0
{
9263
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9264
9265
 /* basic algorithm is:
9266
  *   - ensure sane alignment of output data
9267
  *   - copy (conversion happens automatically) input data
9268
  *     to output
9269
  *   - update tp to point at next unconverted input, and xpp to point
9270
  *     at next location for converted output
9271
  */
9272
  long i, j, ni;
9273
  short tmp[LOOPCNT];        /* in case input is misaligned */
9274
  short *xp;
9275
  int nrange = 0;         /* number of range errors */
9276
  int realign = 0;        /* "do we need to fix input data alignment?" */
9277
  long cxp = (long) *((char**)xpp);
9278
9279
  realign = (cxp & 7) % SIZEOF_SHORT;
9280
  /* sjl: manually stripmine so we can limit amount of
9281
   * vector work space reserved to LOOPCNT elements. Also
9282
   * makes vectorisation easy */
9283
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9284
    ni=Min(nelems-j,LOOPCNT);
9285
    if (realign) {
9286
      xp = tmp;
9287
    } else {
9288
      xp = (short *) *xpp;
9289
    }
9290
   /* copy the next block */
9291
#pragma cdir loopcnt=LOOPCNT
9292
#pragma cdir shortloop
9293
    for (i=0; i<ni; i++) {
9294
      /* the normal case: */
9295
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9296
     /* test for range errors (not always needed but do it anyway) */
9297
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9298
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9299
      nrange += tp[i] > X_SHORT_MAX ;
9300
    }
9301
   /* copy workspace back if necessary */
9302
    if (realign) {
9303
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9304
      xp = (short *) *xpp;
9305
    }
9306
   /* update xpp and tp */
9307
    xp += ni;
9308
    tp += ni;
9309
    *xpp = (void*)xp;
9310
  }
9311
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9312
9313
#else   /* not SX */
9314
9315
0
  char *xp = (char *) *xpp;
9316
0
  int status = NC_NOERR;
9317
9318
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9319
0
  {
9320
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9321
0
    if (status == NC_NOERR) /* report the first encountered error */
9322
0
      status = lstatus;
9323
0
  }
9324
9325
0
  *xpp = (void *)xp;
9326
0
  return status;
9327
0
#endif
9328
0
}
9329
9330
9331
int
9332
ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
9333
0
{
9334
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9335
9336
0
  char *xp = (char *) *xpp;
9337
0
  int status = NC_NOERR;
9338
9339
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9340
0
  {
9341
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
9342
0
    if (status == NC_NOERR) /* report the first encountered error */
9343
0
      status = lstatus;
9344
0
  }
9345
9346
0
  if (rndup != 0)
9347
0
  {
9348
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9349
0
    xp += X_SIZEOF_SHORT;
9350
0
  }
9351
9352
0
  *xpp = (void *)xp;
9353
0
  return status;
9354
0
}
9355
9356
int
9357
ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9358
0
{
9359
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9360
9361
0
  char *xp = (char *) *xpp;
9362
0
  int status = NC_NOERR;
9363
9364
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9365
0
  {
9366
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9367
0
    if (status == NC_NOERR) /* report the first encountered error */
9368
0
      status = lstatus;
9369
0
  }
9370
9371
0
  if (rndup != 0)
9372
0
  {
9373
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9374
0
    xp += X_SIZEOF_SHORT;
9375
0
  }
9376
9377
0
  *xpp = (void *)xp;
9378
0
  return status;
9379
0
}
9380
9381
int
9382
ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
9383
0
{
9384
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9385
9386
0
  char *xp = (char *) *xpp;
9387
0
  int status = NC_NOERR;
9388
9389
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9390
0
  {
9391
0
    int lstatus = ncx_put_short_short(xp, tp, fillp);
9392
0
    if (status == NC_NOERR) /* report the first encountered error */
9393
0
      status = lstatus;
9394
0
  }
9395
9396
0
  if (rndup != 0)
9397
0
  {
9398
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9399
0
    xp += X_SIZEOF_SHORT;
9400
0
  }
9401
9402
0
  *xpp = (void *)xp;
9403
0
  return status;
9404
0
}
9405
9406
int
9407
ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
9408
0
{
9409
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9410
9411
0
  char *xp = (char *) *xpp;
9412
0
  int status = NC_NOERR;
9413
9414
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9415
0
  {
9416
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
9417
0
    if (status == NC_NOERR) /* report the first encountered error */
9418
0
      status = lstatus;
9419
0
  }
9420
9421
0
  if (rndup != 0)
9422
0
  {
9423
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9424
0
    xp += X_SIZEOF_SHORT;
9425
0
  }
9426
9427
0
  *xpp = (void *)xp;
9428
0
  return status;
9429
0
}
9430
9431
int
9432
ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
9433
0
{
9434
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9435
9436
0
  char *xp = (char *) *xpp;
9437
0
  int status = NC_NOERR;
9438
9439
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9440
0
  {
9441
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
9442
0
    if (status == NC_NOERR) /* report the first encountered error */
9443
0
      status = lstatus;
9444
0
  }
9445
9446
0
  if (rndup != 0)
9447
0
  {
9448
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9449
0
    xp += X_SIZEOF_SHORT;
9450
0
  }
9451
9452
0
  *xpp = (void *)xp;
9453
0
  return status;
9454
0
}
9455
9456
int
9457
ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9458
0
{
9459
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9460
9461
0
  char *xp = (char *) *xpp;
9462
0
  int status = NC_NOERR;
9463
9464
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9465
0
  {
9466
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
9467
0
    if (status == NC_NOERR) /* report the first encountered error */
9468
0
      status = lstatus;
9469
0
  }
9470
9471
0
  if (rndup != 0)
9472
0
  {
9473
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9474
0
    xp += X_SIZEOF_SHORT;
9475
0
  }
9476
9477
0
  *xpp = (void *)xp;
9478
0
  return status;
9479
0
}
9480
9481
int
9482
ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9483
0
{
9484
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9485
9486
0
  char *xp = (char *) *xpp;
9487
0
  int status = NC_NOERR;
9488
9489
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9490
0
  {
9491
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
9492
0
    if (status == NC_NOERR) /* report the first encountered error */
9493
0
      status = lstatus;
9494
0
  }
9495
9496
0
  if (rndup != 0)
9497
0
  {
9498
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9499
0
    xp += X_SIZEOF_SHORT;
9500
0
  }
9501
9502
0
  *xpp = (void *)xp;
9503
0
  return status;
9504
0
}
9505
9506
int
9507
ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9508
0
{
9509
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9510
9511
0
  char *xp = (char *) *xpp;
9512
0
  int status = NC_NOERR;
9513
9514
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9515
0
  {
9516
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9517
0
    if (status == NC_NOERR) /* report the first encountered error */
9518
0
      status = lstatus;
9519
0
  }
9520
9521
0
  if (rndup != 0)
9522
0
  {
9523
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9524
0
    xp += X_SIZEOF_SHORT;
9525
0
  }
9526
9527
0
  *xpp = (void *)xp;
9528
0
  return status;
9529
0
}
9530
9531
int
9532
ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9533
0
{
9534
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9535
9536
0
  char *xp = (char *) *xpp;
9537
0
  int status = NC_NOERR;
9538
9539
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9540
0
  {
9541
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9542
0
    if (status == NC_NOERR) /* report the first encountered error */
9543
0
      status = lstatus;
9544
0
  }
9545
9546
0
  if (rndup != 0)
9547
0
  {
9548
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9549
0
    xp += X_SIZEOF_SHORT;
9550
0
  }
9551
9552
0
  *xpp = (void *)xp;
9553
0
  return status;
9554
0
}
9555
9556
int
9557
ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9558
0
{
9559
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9560
9561
0
  char *xp = (char *) *xpp;
9562
0
  int status = NC_NOERR;
9563
9564
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9565
0
  {
9566
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9567
0
    if (status == NC_NOERR) /* report the first encountered error */
9568
0
      status = lstatus;
9569
0
  }
9570
9571
0
  if (rndup != 0)
9572
0
  {
9573
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9574
0
    xp += X_SIZEOF_SHORT;
9575
0
  }
9576
9577
0
  *xpp = (void *)xp;
9578
0
  return status;
9579
0
}
9580
9581
int
9582
ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9583
0
{
9584
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9585
9586
0
  char *xp = (char *) *xpp;
9587
0
  int status = NC_NOERR;
9588
9589
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9590
0
  {
9591
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9592
0
    if (status == NC_NOERR) /* report the first encountered error */
9593
0
      status = lstatus;
9594
0
  }
9595
9596
0
  if (rndup != 0)
9597
0
  {
9598
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9599
0
    xp += X_SIZEOF_SHORT;
9600
0
  }
9601
9602
0
  *xpp = (void *)xp;
9603
0
  return status;
9604
0
}
9605
9606
9607
9608
/* ushort --------------------------------------------------------------------*/
9609
9610
#if X_SIZEOF_USHORT == SIZEOF_USHORT
9611
/* optimized version */
9612
int
9613
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
9614
0
{
9615
#ifdef WORDS_BIGENDIAN
9616
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
9617
# else
9618
0
  swapn2b(tp, *xpp, nelems);
9619
0
# endif
9620
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
9621
0
  return NC_NOERR;
9622
0
}
9623
#else
9624
int
9625
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
9626
{
9627
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9628
9629
 /* basic algorithm is:
9630
  *   - ensure sane alignment of input data
9631
  *   - copy (conversion happens automatically) input data
9632
  *     to output
9633
  *   - update xpp to point at next unconverted input, and tp to point
9634
  *     at next location for converted output
9635
  */
9636
  long i, j, ni;
9637
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9638
  ushort *xp;
9639
  int nrange = 0;         /* number of range errors */
9640
  int realign = 0;        /* "do we need to fix input data alignment?" */
9641
  long cxp = (long) *((char**)xpp);
9642
9643
  realign = (cxp & 7) % SIZEOF_USHORT;
9644
  /* sjl: manually stripmine so we can limit amount of
9645
   * vector work space reserved to LOOPCNT elements. Also
9646
   * makes vectorisation easy */
9647
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9648
    ni=Min(nelems-j,LOOPCNT);
9649
    if (realign) {
9650
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9651
      xp = tmp;
9652
    } else {
9653
      xp = (ushort *) *xpp;
9654
    }
9655
   /* copy the next block */
9656
#pragma cdir loopcnt=LOOPCNT
9657
#pragma cdir shortloop
9658
    for (i=0; i<ni; i++) {
9659
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
9660
     /* test for range errors (not always needed but do it anyway) */
9661
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9662
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9663
      nrange += xp[i] > USHORT_MAX ;
9664
    }
9665
   /* update xpp and tp */
9666
    if (realign) xp = (ushort *) *xpp;
9667
    xp += ni;
9668
    tp += ni;
9669
    *xpp = (void*)xp;
9670
  }
9671
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9672
9673
#else   /* not SX */
9674
  const char *xp = (const char *) *xpp;
9675
  int status = NC_NOERR;
9676
9677
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9678
  {
9679
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
9680
    if (status == NC_NOERR) /* report the first encountered error */
9681
      status = lstatus;
9682
  }
9683
9684
  *xpp = (const void *)xp;
9685
  return status;
9686
#endif
9687
}
9688
9689
#endif
9690
int
9691
ncx_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
9692
0
{
9693
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9694
9695
 /* basic algorithm is:
9696
  *   - ensure sane alignment of input data
9697
  *   - copy (conversion happens automatically) input data
9698
  *     to output
9699
  *   - update xpp to point at next unconverted input, and tp to point
9700
  *     at next location for converted output
9701
  */
9702
  long i, j, ni;
9703
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9704
  ushort *xp;
9705
  int nrange = 0;         /* number of range errors */
9706
  int realign = 0;        /* "do we need to fix input data alignment?" */
9707
  long cxp = (long) *((char**)xpp);
9708
9709
  realign = (cxp & 7) % SIZEOF_USHORT;
9710
  /* sjl: manually stripmine so we can limit amount of
9711
   * vector work space reserved to LOOPCNT elements. Also
9712
   * makes vectorisation easy */
9713
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9714
    ni=Min(nelems-j,LOOPCNT);
9715
    if (realign) {
9716
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9717
      xp = tmp;
9718
    } else {
9719
      xp = (ushort *) *xpp;
9720
    }
9721
   /* copy the next block */
9722
#pragma cdir loopcnt=LOOPCNT
9723
#pragma cdir shortloop
9724
    for (i=0; i<ni; i++) {
9725
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
9726
     /* test for range errors (not always needed but do it anyway) */
9727
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9728
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9729
      nrange += xp[i] > SCHAR_MAX ;
9730
    }
9731
   /* update xpp and tp */
9732
    if (realign) xp = (ushort *) *xpp;
9733
    xp += ni;
9734
    tp += ni;
9735
    *xpp = (void*)xp;
9736
  }
9737
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9738
9739
#else   /* not SX */
9740
0
  const char *xp = (const char *) *xpp;
9741
0
  int status = NC_NOERR;
9742
9743
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9744
0
  {
9745
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
9746
0
    if (status == NC_NOERR) /* report the first encountered error */
9747
0
      status = lstatus;
9748
0
  }
9749
9750
0
  *xpp = (const void *)xp;
9751
0
  return status;
9752
0
#endif
9753
0
}
9754
9755
int
9756
ncx_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
9757
0
{
9758
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9759
9760
 /* basic algorithm is:
9761
  *   - ensure sane alignment of input data
9762
  *   - copy (conversion happens automatically) input data
9763
  *     to output
9764
  *   - update xpp to point at next unconverted input, and tp to point
9765
  *     at next location for converted output
9766
  */
9767
  long i, j, ni;
9768
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9769
  ushort *xp;
9770
  int nrange = 0;         /* number of range errors */
9771
  int realign = 0;        /* "do we need to fix input data alignment?" */
9772
  long cxp = (long) *((char**)xpp);
9773
9774
  realign = (cxp & 7) % SIZEOF_USHORT;
9775
  /* sjl: manually stripmine so we can limit amount of
9776
   * vector work space reserved to LOOPCNT elements. Also
9777
   * makes vectorisation easy */
9778
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9779
    ni=Min(nelems-j,LOOPCNT);
9780
    if (realign) {
9781
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9782
      xp = tmp;
9783
    } else {
9784
      xp = (ushort *) *xpp;
9785
    }
9786
   /* copy the next block */
9787
#pragma cdir loopcnt=LOOPCNT
9788
#pragma cdir shortloop
9789
    for (i=0; i<ni; i++) {
9790
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
9791
     /* test for range errors (not always needed but do it anyway) */
9792
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9793
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9794
      nrange += xp[i] > SHORT_MAX ;
9795
    }
9796
   /* update xpp and tp */
9797
    if (realign) xp = (ushort *) *xpp;
9798
    xp += ni;
9799
    tp += ni;
9800
    *xpp = (void*)xp;
9801
  }
9802
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9803
9804
#else   /* not SX */
9805
0
  const char *xp = (const char *) *xpp;
9806
0
  int status = NC_NOERR;
9807
9808
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9809
0
  {
9810
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
9811
0
    if (status == NC_NOERR) /* report the first encountered error */
9812
0
      status = lstatus;
9813
0
  }
9814
9815
0
  *xpp = (const void *)xp;
9816
0
  return status;
9817
0
#endif
9818
0
}
9819
9820
int
9821
ncx_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
9822
0
{
9823
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9824
9825
 /* basic algorithm is:
9826
  *   - ensure sane alignment of input data
9827
  *   - copy (conversion happens automatically) input data
9828
  *     to output
9829
  *   - update xpp to point at next unconverted input, and tp to point
9830
  *     at next location for converted output
9831
  */
9832
  long i, j, ni;
9833
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9834
  ushort *xp;
9835
  int nrange = 0;         /* number of range errors */
9836
  int realign = 0;        /* "do we need to fix input data alignment?" */
9837
  long cxp = (long) *((char**)xpp);
9838
9839
  realign = (cxp & 7) % SIZEOF_USHORT;
9840
  /* sjl: manually stripmine so we can limit amount of
9841
   * vector work space reserved to LOOPCNT elements. Also
9842
   * makes vectorisation easy */
9843
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9844
    ni=Min(nelems-j,LOOPCNT);
9845
    if (realign) {
9846
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9847
      xp = tmp;
9848
    } else {
9849
      xp = (ushort *) *xpp;
9850
    }
9851
   /* copy the next block */
9852
#pragma cdir loopcnt=LOOPCNT
9853
#pragma cdir shortloop
9854
    for (i=0; i<ni; i++) {
9855
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
9856
     /* test for range errors (not always needed but do it anyway) */
9857
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9858
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9859
      nrange += xp[i] > INT_MAX ;
9860
    }
9861
   /* update xpp and tp */
9862
    if (realign) xp = (ushort *) *xpp;
9863
    xp += ni;
9864
    tp += ni;
9865
    *xpp = (void*)xp;
9866
  }
9867
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9868
9869
#else   /* not SX */
9870
0
  const char *xp = (const char *) *xpp;
9871
0
  int status = NC_NOERR;
9872
9873
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9874
0
  {
9875
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
9876
0
    if (status == NC_NOERR) /* report the first encountered error */
9877
0
      status = lstatus;
9878
0
  }
9879
9880
0
  *xpp = (const void *)xp;
9881
0
  return status;
9882
0
#endif
9883
0
}
9884
9885
int
9886
ncx_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
9887
0
{
9888
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9889
9890
 /* basic algorithm is:
9891
  *   - ensure sane alignment of input data
9892
  *   - copy (conversion happens automatically) input data
9893
  *     to output
9894
  *   - update xpp to point at next unconverted input, and tp to point
9895
  *     at next location for converted output
9896
  */
9897
  long i, j, ni;
9898
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9899
  ushort *xp;
9900
  int nrange = 0;         /* number of range errors */
9901
  int realign = 0;        /* "do we need to fix input data alignment?" */
9902
  long cxp = (long) *((char**)xpp);
9903
9904
  realign = (cxp & 7) % SIZEOF_USHORT;
9905
  /* sjl: manually stripmine so we can limit amount of
9906
   * vector work space reserved to LOOPCNT elements. Also
9907
   * makes vectorisation easy */
9908
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9909
    ni=Min(nelems-j,LOOPCNT);
9910
    if (realign) {
9911
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9912
      xp = tmp;
9913
    } else {
9914
      xp = (ushort *) *xpp;
9915
    }
9916
   /* copy the next block */
9917
#pragma cdir loopcnt=LOOPCNT
9918
#pragma cdir shortloop
9919
    for (i=0; i<ni; i++) {
9920
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
9921
     /* test for range errors (not always needed but do it anyway) */
9922
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9923
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9924
      nrange += xp[i] > LONG_MAX ;
9925
    }
9926
   /* update xpp and tp */
9927
    if (realign) xp = (ushort *) *xpp;
9928
    xp += ni;
9929
    tp += ni;
9930
    *xpp = (void*)xp;
9931
  }
9932
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9933
9934
#else   /* not SX */
9935
0
  const char *xp = (const char *) *xpp;
9936
0
  int status = NC_NOERR;
9937
9938
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9939
0
  {
9940
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
9941
0
    if (status == NC_NOERR) /* report the first encountered error */
9942
0
      status = lstatus;
9943
0
  }
9944
9945
0
  *xpp = (const void *)xp;
9946
0
  return status;
9947
0
#endif
9948
0
}
9949
9950
int
9951
ncx_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
9952
0
{
9953
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9954
9955
 /* basic algorithm is:
9956
  *   - ensure sane alignment of input data
9957
  *   - copy (conversion happens automatically) input data
9958
  *     to output
9959
  *   - update xpp to point at next unconverted input, and tp to point
9960
  *     at next location for converted output
9961
  */
9962
  long i, j, ni;
9963
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9964
  ushort *xp;
9965
  int nrange = 0;         /* number of range errors */
9966
  int realign = 0;        /* "do we need to fix input data alignment?" */
9967
  long cxp = (long) *((char**)xpp);
9968
9969
  realign = (cxp & 7) % SIZEOF_USHORT;
9970
  /* sjl: manually stripmine so we can limit amount of
9971
   * vector work space reserved to LOOPCNT elements. Also
9972
   * makes vectorisation easy */
9973
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9974
    ni=Min(nelems-j,LOOPCNT);
9975
    if (realign) {
9976
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9977
      xp = tmp;
9978
    } else {
9979
      xp = (ushort *) *xpp;
9980
    }
9981
   /* copy the next block */
9982
#pragma cdir loopcnt=LOOPCNT
9983
#pragma cdir shortloop
9984
    for (i=0; i<ni; i++) {
9985
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
9986
     /* test for range errors (not always needed but do it anyway) */
9987
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9988
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9989
      nrange += xp[i] > FLOAT_MAX ;
9990
    }
9991
   /* update xpp and tp */
9992
    if (realign) xp = (ushort *) *xpp;
9993
    xp += ni;
9994
    tp += ni;
9995
    *xpp = (void*)xp;
9996
  }
9997
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9998
9999
#else   /* not SX */
10000
0
  const char *xp = (const char *) *xpp;
10001
0
  int status = NC_NOERR;
10002
10003
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10004
0
  {
10005
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10006
0
    if (status == NC_NOERR) /* report the first encountered error */
10007
0
      status = lstatus;
10008
0
  }
10009
10010
0
  *xpp = (const void *)xp;
10011
0
  return status;
10012
0
#endif
10013
0
}
10014
10015
int
10016
ncx_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10017
0
{
10018
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10019
10020
 /* basic algorithm is:
10021
  *   - ensure sane alignment of input data
10022
  *   - copy (conversion happens automatically) input data
10023
  *     to output
10024
  *   - update xpp to point at next unconverted input, and tp to point
10025
  *     at next location for converted output
10026
  */
10027
  long i, j, ni;
10028
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10029
  ushort *xp;
10030
  int nrange = 0;         /* number of range errors */
10031
  int realign = 0;        /* "do we need to fix input data alignment?" */
10032
  long cxp = (long) *((char**)xpp);
10033
10034
  realign = (cxp & 7) % SIZEOF_USHORT;
10035
  /* sjl: manually stripmine so we can limit amount of
10036
   * vector work space reserved to LOOPCNT elements. Also
10037
   * makes vectorisation easy */
10038
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10039
    ni=Min(nelems-j,LOOPCNT);
10040
    if (realign) {
10041
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10042
      xp = tmp;
10043
    } else {
10044
      xp = (ushort *) *xpp;
10045
    }
10046
   /* copy the next block */
10047
#pragma cdir loopcnt=LOOPCNT
10048
#pragma cdir shortloop
10049
    for (i=0; i<ni; i++) {
10050
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
10051
     /* test for range errors (not always needed but do it anyway) */
10052
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10053
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10054
      nrange += xp[i] > DOUBLE_MAX ;
10055
    }
10056
   /* update xpp and tp */
10057
    if (realign) xp = (ushort *) *xpp;
10058
    xp += ni;
10059
    tp += ni;
10060
    *xpp = (void*)xp;
10061
  }
10062
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10063
10064
#else   /* not SX */
10065
0
  const char *xp = (const char *) *xpp;
10066
0
  int status = NC_NOERR;
10067
10068
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10069
0
  {
10070
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10071
0
    if (status == NC_NOERR) /* report the first encountered error */
10072
0
      status = lstatus;
10073
0
  }
10074
10075
0
  *xpp = (const void *)xp;
10076
0
  return status;
10077
0
#endif
10078
0
}
10079
10080
int
10081
ncx_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10082
0
{
10083
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10084
10085
 /* basic algorithm is:
10086
  *   - ensure sane alignment of input data
10087
  *   - copy (conversion happens automatically) input data
10088
  *     to output
10089
  *   - update xpp to point at next unconverted input, and tp to point
10090
  *     at next location for converted output
10091
  */
10092
  long i, j, ni;
10093
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10094
  ushort *xp;
10095
  int nrange = 0;         /* number of range errors */
10096
  int realign = 0;        /* "do we need to fix input data alignment?" */
10097
  long cxp = (long) *((char**)xpp);
10098
10099
  realign = (cxp & 7) % SIZEOF_USHORT;
10100
  /* sjl: manually stripmine so we can limit amount of
10101
   * vector work space reserved to LOOPCNT elements. Also
10102
   * makes vectorisation easy */
10103
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10104
    ni=Min(nelems-j,LOOPCNT);
10105
    if (realign) {
10106
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10107
      xp = tmp;
10108
    } else {
10109
      xp = (ushort *) *xpp;
10110
    }
10111
   /* copy the next block */
10112
#pragma cdir loopcnt=LOOPCNT
10113
#pragma cdir shortloop
10114
    for (i=0; i<ni; i++) {
10115
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
10116
     /* test for range errors (not always needed but do it anyway) */
10117
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10118
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10119
      nrange += xp[i] > LONGLONG_MAX ;
10120
    }
10121
   /* update xpp and tp */
10122
    if (realign) xp = (ushort *) *xpp;
10123
    xp += ni;
10124
    tp += ni;
10125
    *xpp = (void*)xp;
10126
  }
10127
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10128
10129
#else   /* not SX */
10130
0
  const char *xp = (const char *) *xpp;
10131
0
  int status = NC_NOERR;
10132
10133
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10134
0
  {
10135
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10136
0
    if (status == NC_NOERR) /* report the first encountered error */
10137
0
      status = lstatus;
10138
0
  }
10139
10140
0
  *xpp = (const void *)xp;
10141
0
  return status;
10142
0
#endif
10143
0
}
10144
10145
int
10146
ncx_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10147
0
{
10148
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10149
10150
 /* basic algorithm is:
10151
  *   - ensure sane alignment of input data
10152
  *   - copy (conversion happens automatically) input data
10153
  *     to output
10154
  *   - update xpp to point at next unconverted input, and tp to point
10155
  *     at next location for converted output
10156
  */
10157
  long i, j, ni;
10158
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10159
  ushort *xp;
10160
  int nrange = 0;         /* number of range errors */
10161
  int realign = 0;        /* "do we need to fix input data alignment?" */
10162
  long cxp = (long) *((char**)xpp);
10163
10164
  realign = (cxp & 7) % SIZEOF_USHORT;
10165
  /* sjl: manually stripmine so we can limit amount of
10166
   * vector work space reserved to LOOPCNT elements. Also
10167
   * makes vectorisation easy */
10168
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10169
    ni=Min(nelems-j,LOOPCNT);
10170
    if (realign) {
10171
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10172
      xp = tmp;
10173
    } else {
10174
      xp = (ushort *) *xpp;
10175
    }
10176
   /* copy the next block */
10177
#pragma cdir loopcnt=LOOPCNT
10178
#pragma cdir shortloop
10179
    for (i=0; i<ni; i++) {
10180
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
10181
     /* test for range errors (not always needed but do it anyway) */
10182
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10183
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10184
      nrange += xp[i] > UCHAR_MAX ;
10185
    }
10186
   /* update xpp and tp */
10187
    if (realign) xp = (ushort *) *xpp;
10188
    xp += ni;
10189
    tp += ni;
10190
    *xpp = (void*)xp;
10191
  }
10192
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10193
10194
#else   /* not SX */
10195
0
  const char *xp = (const char *) *xpp;
10196
0
  int status = NC_NOERR;
10197
10198
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10199
0
  {
10200
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10201
0
    if (status == NC_NOERR) /* report the first encountered error */
10202
0
      status = lstatus;
10203
0
  }
10204
10205
0
  *xpp = (const void *)xp;
10206
0
  return status;
10207
0
#endif
10208
0
}
10209
10210
int
10211
ncx_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10212
0
{
10213
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10214
10215
 /* basic algorithm is:
10216
  *   - ensure sane alignment of input data
10217
  *   - copy (conversion happens automatically) input data
10218
  *     to output
10219
  *   - update xpp to point at next unconverted input, and tp to point
10220
  *     at next location for converted output
10221
  */
10222
  long i, j, ni;
10223
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10224
  ushort *xp;
10225
  int nrange = 0;         /* number of range errors */
10226
  int realign = 0;        /* "do we need to fix input data alignment?" */
10227
  long cxp = (long) *((char**)xpp);
10228
10229
  realign = (cxp & 7) % SIZEOF_USHORT;
10230
  /* sjl: manually stripmine so we can limit amount of
10231
   * vector work space reserved to LOOPCNT elements. Also
10232
   * makes vectorisation easy */
10233
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10234
    ni=Min(nelems-j,LOOPCNT);
10235
    if (realign) {
10236
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10237
      xp = tmp;
10238
    } else {
10239
      xp = (ushort *) *xpp;
10240
    }
10241
   /* copy the next block */
10242
#pragma cdir loopcnt=LOOPCNT
10243
#pragma cdir shortloop
10244
    for (i=0; i<ni; i++) {
10245
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
10246
     /* test for range errors (not always needed but do it anyway) */
10247
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10248
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10249
      nrange += xp[i] > UINT_MAX ;
10250
    }
10251
   /* update xpp and tp */
10252
    if (realign) xp = (ushort *) *xpp;
10253
    xp += ni;
10254
    tp += ni;
10255
    *xpp = (void*)xp;
10256
  }
10257
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10258
10259
#else   /* not SX */
10260
0
  const char *xp = (const char *) *xpp;
10261
0
  int status = NC_NOERR;
10262
10263
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10264
0
  {
10265
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10266
0
    if (status == NC_NOERR) /* report the first encountered error */
10267
0
      status = lstatus;
10268
0
  }
10269
10270
0
  *xpp = (const void *)xp;
10271
0
  return status;
10272
0
#endif
10273
0
}
10274
10275
int
10276
ncx_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10277
0
{
10278
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10279
10280
 /* basic algorithm is:
10281
  *   - ensure sane alignment of input data
10282
  *   - copy (conversion happens automatically) input data
10283
  *     to output
10284
  *   - update xpp to point at next unconverted input, and tp to point
10285
  *     at next location for converted output
10286
  */
10287
  long i, j, ni;
10288
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10289
  ushort *xp;
10290
  int nrange = 0;         /* number of range errors */
10291
  int realign = 0;        /* "do we need to fix input data alignment?" */
10292
  long cxp = (long) *((char**)xpp);
10293
10294
  realign = (cxp & 7) % SIZEOF_USHORT;
10295
  /* sjl: manually stripmine so we can limit amount of
10296
   * vector work space reserved to LOOPCNT elements. Also
10297
   * makes vectorisation easy */
10298
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10299
    ni=Min(nelems-j,LOOPCNT);
10300
    if (realign) {
10301
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10302
      xp = tmp;
10303
    } else {
10304
      xp = (ushort *) *xpp;
10305
    }
10306
   /* copy the next block */
10307
#pragma cdir loopcnt=LOOPCNT
10308
#pragma cdir shortloop
10309
    for (i=0; i<ni; i++) {
10310
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
10311
     /* test for range errors (not always needed but do it anyway) */
10312
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10313
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10314
      nrange += xp[i] > ULONGLONG_MAX ;
10315
    }
10316
   /* update xpp and tp */
10317
    if (realign) xp = (ushort *) *xpp;
10318
    xp += ni;
10319
    tp += ni;
10320
    *xpp = (void*)xp;
10321
  }
10322
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10323
10324
#else   /* not SX */
10325
0
  const char *xp = (const char *) *xpp;
10326
0
  int status = NC_NOERR;
10327
10328
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10329
0
  {
10330
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10331
0
    if (status == NC_NOERR) /* report the first encountered error */
10332
0
      status = lstatus;
10333
0
  }
10334
10335
0
  *xpp = (const void *)xp;
10336
0
  return status;
10337
0
#endif
10338
0
}
10339
10340
10341
int
10342
ncx_pad_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
10343
0
{
10344
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10345
10346
0
  const char *xp = (const char *) *xpp;
10347
0
  int status = NC_NOERR;
10348
10349
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10350
0
  {
10351
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
10352
0
    if (status == NC_NOERR) /* report the first encountered error */
10353
0
      status = lstatus;
10354
0
  }
10355
10356
0
  if (rndup != 0)
10357
0
    xp += X_SIZEOF_USHORT;
10358
10359
0
  *xpp = (void *)xp;
10360
0
  return status;
10361
0
}
10362
10363
int
10364
ncx_pad_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
10365
0
{
10366
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10367
10368
0
  const char *xp = (const char *) *xpp;
10369
0
  int status = NC_NOERR;
10370
10371
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10372
0
  {
10373
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
10374
0
    if (status == NC_NOERR) /* report the first encountered error */
10375
0
      status = lstatus;
10376
0
  }
10377
10378
0
  if (rndup != 0)
10379
0
    xp += X_SIZEOF_USHORT;
10380
10381
0
  *xpp = (void *)xp;
10382
0
  return status;
10383
0
}
10384
10385
int
10386
ncx_pad_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10387
0
{
10388
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10389
10390
0
  const char *xp = (const char *) *xpp;
10391
0
  int status = NC_NOERR;
10392
10393
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10394
0
  {
10395
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
10396
0
    if (status == NC_NOERR) /* report the first encountered error */
10397
0
      status = lstatus;
10398
0
  }
10399
10400
0
  if (rndup != 0)
10401
0
    xp += X_SIZEOF_USHORT;
10402
10403
0
  *xpp = (void *)xp;
10404
0
  return status;
10405
0
}
10406
10407
int
10408
ncx_pad_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10409
0
{
10410
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10411
10412
0
  const char *xp = (const char *) *xpp;
10413
0
  int status = NC_NOERR;
10414
10415
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10416
0
  {
10417
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
10418
0
    if (status == NC_NOERR) /* report the first encountered error */
10419
0
      status = lstatus;
10420
0
  }
10421
10422
0
  if (rndup != 0)
10423
0
    xp += X_SIZEOF_USHORT;
10424
10425
0
  *xpp = (void *)xp;
10426
0
  return status;
10427
0
}
10428
10429
int
10430
ncx_pad_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10431
0
{
10432
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10433
10434
0
  const char *xp = (const char *) *xpp;
10435
0
  int status = NC_NOERR;
10436
10437
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10438
0
  {
10439
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10440
0
    if (status == NC_NOERR) /* report the first encountered error */
10441
0
      status = lstatus;
10442
0
  }
10443
10444
0
  if (rndup != 0)
10445
0
    xp += X_SIZEOF_USHORT;
10446
10447
0
  *xpp = (void *)xp;
10448
0
  return status;
10449
0
}
10450
10451
int
10452
ncx_pad_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10453
0
{
10454
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10455
10456
0
  const char *xp = (const char *) *xpp;
10457
0
  int status = NC_NOERR;
10458
10459
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10460
0
  {
10461
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10462
0
    if (status == NC_NOERR) /* report the first encountered error */
10463
0
      status = lstatus;
10464
0
  }
10465
10466
0
  if (rndup != 0)
10467
0
    xp += X_SIZEOF_USHORT;
10468
10469
0
  *xpp = (void *)xp;
10470
0
  return status;
10471
0
}
10472
10473
int
10474
ncx_pad_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10475
0
{
10476
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10477
10478
0
  const char *xp = (const char *) *xpp;
10479
0
  int status = NC_NOERR;
10480
10481
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10482
0
  {
10483
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10484
0
    if (status == NC_NOERR) /* report the first encountered error */
10485
0
      status = lstatus;
10486
0
  }
10487
10488
0
  if (rndup != 0)
10489
0
    xp += X_SIZEOF_USHORT;
10490
10491
0
  *xpp = (void *)xp;
10492
0
  return status;
10493
0
}
10494
10495
int
10496
ncx_pad_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
10497
0
{
10498
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10499
10500
0
  const char *xp = (const char *) *xpp;
10501
0
  int status = NC_NOERR;
10502
10503
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10504
0
  {
10505
0
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
10506
0
    if (status == NC_NOERR) /* report the first encountered error */
10507
0
      status = lstatus;
10508
0
  }
10509
10510
0
  if (rndup != 0)
10511
0
    xp += X_SIZEOF_USHORT;
10512
10513
0
  *xpp = (void *)xp;
10514
0
  return status;
10515
0
}
10516
10517
int
10518
ncx_pad_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10519
0
{
10520
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10521
10522
0
  const char *xp = (const char *) *xpp;
10523
0
  int status = NC_NOERR;
10524
10525
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10526
0
  {
10527
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10528
0
    if (status == NC_NOERR) /* report the first encountered error */
10529
0
      status = lstatus;
10530
0
  }
10531
10532
0
  if (rndup != 0)
10533
0
    xp += X_SIZEOF_USHORT;
10534
10535
0
  *xpp = (void *)xp;
10536
0
  return status;
10537
0
}
10538
10539
int
10540
ncx_pad_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10541
0
{
10542
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10543
10544
0
  const char *xp = (const char *) *xpp;
10545
0
  int status = NC_NOERR;
10546
10547
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10548
0
  {
10549
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10550
0
    if (status == NC_NOERR) /* report the first encountered error */
10551
0
      status = lstatus;
10552
0
  }
10553
10554
0
  if (rndup != 0)
10555
0
    xp += X_SIZEOF_USHORT;
10556
10557
0
  *xpp = (void *)xp;
10558
0
  return status;
10559
0
}
10560
10561
int
10562
ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10563
0
{
10564
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10565
10566
0
  const char *xp = (const char *) *xpp;
10567
0
  int status = NC_NOERR;
10568
10569
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10570
0
  {
10571
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10572
0
    if (status == NC_NOERR) /* report the first encountered error */
10573
0
      status = lstatus;
10574
0
  }
10575
10576
0
  if (rndup != 0)
10577
0
    xp += X_SIZEOF_USHORT;
10578
10579
0
  *xpp = (void *)xp;
10580
0
  return status;
10581
0
}
10582
10583
10584
#if X_SIZEOF_USHORT == SIZEOF_USHORT
10585
/* optimized version */
10586
int
10587
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp, void *fillp)
10588
0
{
10589
#ifdef WORDS_BIGENDIAN
10590
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
10591
# else
10592
0
  swapn2b(*xpp, tp, nelems);
10593
0
# endif
10594
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
10595
0
  return NC_NOERR;
10596
0
}
10597
#else
10598
int
10599
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
10600
{
10601
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10602
10603
 /* basic algorithm is:
10604
  *   - ensure sane alignment of output data
10605
  *   - copy (conversion happens automatically) input data
10606
  *     to output
10607
  *   - update tp to point at next unconverted input, and xpp to point
10608
  *     at next location for converted output
10609
  */
10610
  long i, j, ni;
10611
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10612
  ushort *xp;
10613
  int nrange = 0;         /* number of range errors */
10614
  int realign = 0;        /* "do we need to fix input data alignment?" */
10615
  long cxp = (long) *((char**)xpp);
10616
10617
  realign = (cxp & 7) % SIZEOF_USHORT;
10618
  /* sjl: manually stripmine so we can limit amount of
10619
   * vector work space reserved to LOOPCNT elements. Also
10620
   * makes vectorisation easy */
10621
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10622
    ni=Min(nelems-j,LOOPCNT);
10623
    if (realign) {
10624
      xp = tmp;
10625
    } else {
10626
      xp = (ushort *) *xpp;
10627
    }
10628
   /* copy the next block */
10629
#pragma cdir loopcnt=LOOPCNT
10630
#pragma cdir shortloop
10631
    for (i=0; i<ni; i++) {
10632
      /* the normal case: */
10633
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10634
     /* test for range errors (not always needed but do it anyway) */
10635
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10636
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10637
      nrange += tp[i] > X_USHORT_MAX ;
10638
    }
10639
   /* copy workspace back if necessary */
10640
    if (realign) {
10641
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10642
      xp = (ushort *) *xpp;
10643
    }
10644
   /* update xpp and tp */
10645
    xp += ni;
10646
    tp += ni;
10647
    *xpp = (void*)xp;
10648
  }
10649
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10650
10651
#else   /* not SX */
10652
10653
  char *xp = (char *) *xpp;
10654
  int status = NC_NOERR;
10655
10656
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10657
  {
10658
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
10659
    if (status == NC_NOERR) /* report the first encountered error */
10660
      status = lstatus;
10661
  }
10662
10663
  *xpp = (void *)xp;
10664
  return status;
10665
#endif
10666
}
10667
10668
#endif
10669
int
10670
ncx_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
10671
0
{
10672
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10673
10674
 /* basic algorithm is:
10675
  *   - ensure sane alignment of output data
10676
  *   - copy (conversion happens automatically) input data
10677
  *     to output
10678
  *   - update tp to point at next unconverted input, and xpp to point
10679
  *     at next location for converted output
10680
  */
10681
  long i, j, ni;
10682
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10683
  ushort *xp;
10684
  int nrange = 0;         /* number of range errors */
10685
  int realign = 0;        /* "do we need to fix input data alignment?" */
10686
  long cxp = (long) *((char**)xpp);
10687
10688
  realign = (cxp & 7) % SIZEOF_USHORT;
10689
  /* sjl: manually stripmine so we can limit amount of
10690
   * vector work space reserved to LOOPCNT elements. Also
10691
   * makes vectorisation easy */
10692
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10693
    ni=Min(nelems-j,LOOPCNT);
10694
    if (realign) {
10695
      xp = tmp;
10696
    } else {
10697
      xp = (ushort *) *xpp;
10698
    }
10699
   /* copy the next block */
10700
#pragma cdir loopcnt=LOOPCNT
10701
#pragma cdir shortloop
10702
    for (i=0; i<ni; i++) {
10703
      /* the normal case: */
10704
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10705
     /* test for range errors (not always needed but do it anyway) */
10706
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10707
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10708
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10709
    }
10710
   /* copy workspace back if necessary */
10711
    if (realign) {
10712
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10713
      xp = (ushort *) *xpp;
10714
    }
10715
   /* update xpp and tp */
10716
    xp += ni;
10717
    tp += ni;
10718
    *xpp = (void*)xp;
10719
  }
10720
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10721
10722
#else   /* not SX */
10723
10724
0
  char *xp = (char *) *xpp;
10725
0
  int status = NC_NOERR;
10726
10727
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10728
0
  {
10729
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
10730
0
    if (status == NC_NOERR) /* report the first encountered error */
10731
0
      status = lstatus;
10732
0
  }
10733
10734
0
  *xpp = (void *)xp;
10735
0
  return status;
10736
0
#endif
10737
0
}
10738
10739
int
10740
ncx_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
10741
0
{
10742
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10743
10744
 /* basic algorithm is:
10745
  *   - ensure sane alignment of output data
10746
  *   - copy (conversion happens automatically) input data
10747
  *     to output
10748
  *   - update tp to point at next unconverted input, and xpp to point
10749
  *     at next location for converted output
10750
  */
10751
  long i, j, ni;
10752
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10753
  ushort *xp;
10754
  int nrange = 0;         /* number of range errors */
10755
  int realign = 0;        /* "do we need to fix input data alignment?" */
10756
  long cxp = (long) *((char**)xpp);
10757
10758
  realign = (cxp & 7) % SIZEOF_USHORT;
10759
  /* sjl: manually stripmine so we can limit amount of
10760
   * vector work space reserved to LOOPCNT elements. Also
10761
   * makes vectorisation easy */
10762
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10763
    ni=Min(nelems-j,LOOPCNT);
10764
    if (realign) {
10765
      xp = tmp;
10766
    } else {
10767
      xp = (ushort *) *xpp;
10768
    }
10769
   /* copy the next block */
10770
#pragma cdir loopcnt=LOOPCNT
10771
#pragma cdir shortloop
10772
    for (i=0; i<ni; i++) {
10773
      /* the normal case: */
10774
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10775
     /* test for range errors (not always needed but do it anyway) */
10776
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10777
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10778
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10779
    }
10780
   /* copy workspace back if necessary */
10781
    if (realign) {
10782
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10783
      xp = (ushort *) *xpp;
10784
    }
10785
   /* update xpp and tp */
10786
    xp += ni;
10787
    tp += ni;
10788
    *xpp = (void*)xp;
10789
  }
10790
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10791
10792
#else   /* not SX */
10793
10794
0
  char *xp = (char *) *xpp;
10795
0
  int status = NC_NOERR;
10796
10797
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10798
0
  {
10799
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
10800
0
    if (status == NC_NOERR) /* report the first encountered error */
10801
0
      status = lstatus;
10802
0
  }
10803
10804
0
  *xpp = (void *)xp;
10805
0
  return status;
10806
0
#endif
10807
0
}
10808
10809
int
10810
ncx_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
10811
0
{
10812
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10813
10814
 /* basic algorithm is:
10815
  *   - ensure sane alignment of output data
10816
  *   - copy (conversion happens automatically) input data
10817
  *     to output
10818
  *   - update tp to point at next unconverted input, and xpp to point
10819
  *     at next location for converted output
10820
  */
10821
  long i, j, ni;
10822
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10823
  ushort *xp;
10824
  int nrange = 0;         /* number of range errors */
10825
  int realign = 0;        /* "do we need to fix input data alignment?" */
10826
  long cxp = (long) *((char**)xpp);
10827
10828
  realign = (cxp & 7) % SIZEOF_USHORT;
10829
  /* sjl: manually stripmine so we can limit amount of
10830
   * vector work space reserved to LOOPCNT elements. Also
10831
   * makes vectorisation easy */
10832
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10833
    ni=Min(nelems-j,LOOPCNT);
10834
    if (realign) {
10835
      xp = tmp;
10836
    } else {
10837
      xp = (ushort *) *xpp;
10838
    }
10839
   /* copy the next block */
10840
#pragma cdir loopcnt=LOOPCNT
10841
#pragma cdir shortloop
10842
    for (i=0; i<ni; i++) {
10843
      /* the normal case: */
10844
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10845
     /* test for range errors (not always needed but do it anyway) */
10846
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10847
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10848
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10849
    }
10850
   /* copy workspace back if necessary */
10851
    if (realign) {
10852
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10853
      xp = (ushort *) *xpp;
10854
    }
10855
   /* update xpp and tp */
10856
    xp += ni;
10857
    tp += ni;
10858
    *xpp = (void*)xp;
10859
  }
10860
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10861
10862
#else   /* not SX */
10863
10864
0
  char *xp = (char *) *xpp;
10865
0
  int status = NC_NOERR;
10866
10867
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10868
0
  {
10869
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
10870
0
    if (status == NC_NOERR) /* report the first encountered error */
10871
0
      status = lstatus;
10872
0
  }
10873
10874
0
  *xpp = (void *)xp;
10875
0
  return status;
10876
0
#endif
10877
0
}
10878
10879
int
10880
ncx_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
10881
0
{
10882
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10883
10884
 /* basic algorithm is:
10885
  *   - ensure sane alignment of output data
10886
  *   - copy (conversion happens automatically) input data
10887
  *     to output
10888
  *   - update tp to point at next unconverted input, and xpp to point
10889
  *     at next location for converted output
10890
  */
10891
  long i, j, ni;
10892
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10893
  ushort *xp;
10894
  int nrange = 0;         /* number of range errors */
10895
  int realign = 0;        /* "do we need to fix input data alignment?" */
10896
  long cxp = (long) *((char**)xpp);
10897
10898
  realign = (cxp & 7) % SIZEOF_USHORT;
10899
  /* sjl: manually stripmine so we can limit amount of
10900
   * vector work space reserved to LOOPCNT elements. Also
10901
   * makes vectorisation easy */
10902
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10903
    ni=Min(nelems-j,LOOPCNT);
10904
    if (realign) {
10905
      xp = tmp;
10906
    } else {
10907
      xp = (ushort *) *xpp;
10908
    }
10909
   /* copy the next block */
10910
#pragma cdir loopcnt=LOOPCNT
10911
#pragma cdir shortloop
10912
    for (i=0; i<ni; i++) {
10913
      /* the normal case: */
10914
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10915
     /* test for range errors (not always needed but do it anyway) */
10916
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10917
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10918
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10919
    }
10920
   /* copy workspace back if necessary */
10921
    if (realign) {
10922
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10923
      xp = (ushort *) *xpp;
10924
    }
10925
   /* update xpp and tp */
10926
    xp += ni;
10927
    tp += ni;
10928
    *xpp = (void*)xp;
10929
  }
10930
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10931
10932
#else   /* not SX */
10933
10934
0
  char *xp = (char *) *xpp;
10935
0
  int status = NC_NOERR;
10936
10937
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10938
0
  {
10939
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
10940
0
    if (status == NC_NOERR) /* report the first encountered error */
10941
0
      status = lstatus;
10942
0
  }
10943
10944
0
  *xpp = (void *)xp;
10945
0
  return status;
10946
0
#endif
10947
0
}
10948
10949
int
10950
ncx_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
10951
0
{
10952
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10953
10954
 /* basic algorithm is:
10955
  *   - ensure sane alignment of output data
10956
  *   - copy (conversion happens automatically) input data
10957
  *     to output
10958
  *   - update tp to point at next unconverted input, and xpp to point
10959
  *     at next location for converted output
10960
  */
10961
  long i, j, ni;
10962
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10963
  ushort *xp;
10964
  int nrange = 0;         /* number of range errors */
10965
  int realign = 0;        /* "do we need to fix input data alignment?" */
10966
  long cxp = (long) *((char**)xpp);
10967
10968
  realign = (cxp & 7) % SIZEOF_USHORT;
10969
  /* sjl: manually stripmine so we can limit amount of
10970
   * vector work space reserved to LOOPCNT elements. Also
10971
   * makes vectorisation easy */
10972
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10973
    ni=Min(nelems-j,LOOPCNT);
10974
    if (realign) {
10975
      xp = tmp;
10976
    } else {
10977
      xp = (ushort *) *xpp;
10978
    }
10979
   /* copy the next block */
10980
#pragma cdir loopcnt=LOOPCNT
10981
#pragma cdir shortloop
10982
    for (i=0; i<ni; i++) {
10983
      /* the normal case: */
10984
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10985
     /* test for range errors (not always needed but do it anyway) */
10986
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10987
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10988
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10989
    }
10990
   /* copy workspace back if necessary */
10991
    if (realign) {
10992
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10993
      xp = (ushort *) *xpp;
10994
    }
10995
   /* update xpp and tp */
10996
    xp += ni;
10997
    tp += ni;
10998
    *xpp = (void*)xp;
10999
  }
11000
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11001
11002
#else   /* not SX */
11003
11004
0
  char *xp = (char *) *xpp;
11005
0
  int status = NC_NOERR;
11006
11007
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11008
0
  {
11009
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11010
0
    if (status == NC_NOERR) /* report the first encountered error */
11011
0
      status = lstatus;
11012
0
  }
11013
11014
0
  *xpp = (void *)xp;
11015
0
  return status;
11016
0
#endif
11017
0
}
11018
11019
int
11020
ncx_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11021
0
{
11022
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11023
11024
 /* basic algorithm is:
11025
  *   - ensure sane alignment of output data
11026
  *   - copy (conversion happens automatically) input data
11027
  *     to output
11028
  *   - update tp to point at next unconverted input, and xpp to point
11029
  *     at next location for converted output
11030
  */
11031
  long i, j, ni;
11032
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11033
  ushort *xp;
11034
  int nrange = 0;         /* number of range errors */
11035
  int realign = 0;        /* "do we need to fix input data alignment?" */
11036
  long cxp = (long) *((char**)xpp);
11037
11038
  realign = (cxp & 7) % SIZEOF_USHORT;
11039
  /* sjl: manually stripmine so we can limit amount of
11040
   * vector work space reserved to LOOPCNT elements. Also
11041
   * makes vectorisation easy */
11042
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11043
    ni=Min(nelems-j,LOOPCNT);
11044
    if (realign) {
11045
      xp = tmp;
11046
    } else {
11047
      xp = (ushort *) *xpp;
11048
    }
11049
   /* copy the next block */
11050
#pragma cdir loopcnt=LOOPCNT
11051
#pragma cdir shortloop
11052
    for (i=0; i<ni; i++) {
11053
      /* the normal case: */
11054
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11055
     /* test for range errors (not always needed but do it anyway) */
11056
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11057
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11058
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11059
    }
11060
   /* copy workspace back if necessary */
11061
    if (realign) {
11062
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11063
      xp = (ushort *) *xpp;
11064
    }
11065
   /* update xpp and tp */
11066
    xp += ni;
11067
    tp += ni;
11068
    *xpp = (void*)xp;
11069
  }
11070
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11071
11072
#else   /* not SX */
11073
11074
0
  char *xp = (char *) *xpp;
11075
0
  int status = NC_NOERR;
11076
11077
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11078
0
  {
11079
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11080
0
    if (status == NC_NOERR) /* report the first encountered error */
11081
0
      status = lstatus;
11082
0
  }
11083
11084
0
  *xpp = (void *)xp;
11085
0
  return status;
11086
0
#endif
11087
0
}
11088
11089
int
11090
ncx_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11091
0
{
11092
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11093
11094
 /* basic algorithm is:
11095
  *   - ensure sane alignment of output data
11096
  *   - copy (conversion happens automatically) input data
11097
  *     to output
11098
  *   - update tp to point at next unconverted input, and xpp to point
11099
  *     at next location for converted output
11100
  */
11101
  long i, j, ni;
11102
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11103
  ushort *xp;
11104
  int nrange = 0;         /* number of range errors */
11105
  int realign = 0;        /* "do we need to fix input data alignment?" */
11106
  long cxp = (long) *((char**)xpp);
11107
11108
  realign = (cxp & 7) % SIZEOF_USHORT;
11109
  /* sjl: manually stripmine so we can limit amount of
11110
   * vector work space reserved to LOOPCNT elements. Also
11111
   * makes vectorisation easy */
11112
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11113
    ni=Min(nelems-j,LOOPCNT);
11114
    if (realign) {
11115
      xp = tmp;
11116
    } else {
11117
      xp = (ushort *) *xpp;
11118
    }
11119
   /* copy the next block */
11120
#pragma cdir loopcnt=LOOPCNT
11121
#pragma cdir shortloop
11122
    for (i=0; i<ni; i++) {
11123
      /* the normal case: */
11124
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11125
     /* test for range errors (not always needed but do it anyway) */
11126
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11127
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11128
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11129
    }
11130
   /* copy workspace back if necessary */
11131
    if (realign) {
11132
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11133
      xp = (ushort *) *xpp;
11134
    }
11135
   /* update xpp and tp */
11136
    xp += ni;
11137
    tp += ni;
11138
    *xpp = (void*)xp;
11139
  }
11140
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11141
11142
#else   /* not SX */
11143
11144
0
  char *xp = (char *) *xpp;
11145
0
  int status = NC_NOERR;
11146
11147
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11148
0
  {
11149
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11150
0
    if (status == NC_NOERR) /* report the first encountered error */
11151
0
      status = lstatus;
11152
0
  }
11153
11154
0
  *xpp = (void *)xp;
11155
0
  return status;
11156
0
#endif
11157
0
}
11158
11159
int
11160
ncx_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11161
0
{
11162
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11163
11164
 /* basic algorithm is:
11165
  *   - ensure sane alignment of output data
11166
  *   - copy (conversion happens automatically) input data
11167
  *     to output
11168
  *   - update tp to point at next unconverted input, and xpp to point
11169
  *     at next location for converted output
11170
  */
11171
  long i, j, ni;
11172
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11173
  ushort *xp;
11174
  int nrange = 0;         /* number of range errors */
11175
  int realign = 0;        /* "do we need to fix input data alignment?" */
11176
  long cxp = (long) *((char**)xpp);
11177
11178
  realign = (cxp & 7) % SIZEOF_USHORT;
11179
  /* sjl: manually stripmine so we can limit amount of
11180
   * vector work space reserved to LOOPCNT elements. Also
11181
   * makes vectorisation easy */
11182
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11183
    ni=Min(nelems-j,LOOPCNT);
11184
    if (realign) {
11185
      xp = tmp;
11186
    } else {
11187
      xp = (ushort *) *xpp;
11188
    }
11189
   /* copy the next block */
11190
#pragma cdir loopcnt=LOOPCNT
11191
#pragma cdir shortloop
11192
    for (i=0; i<ni; i++) {
11193
      /* the normal case: */
11194
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11195
     /* test for range errors (not always needed but do it anyway) */
11196
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11197
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11198
      nrange += tp[i] > X_USHORT_MAX ;
11199
    }
11200
   /* copy workspace back if necessary */
11201
    if (realign) {
11202
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11203
      xp = (ushort *) *xpp;
11204
    }
11205
   /* update xpp and tp */
11206
    xp += ni;
11207
    tp += ni;
11208
    *xpp = (void*)xp;
11209
  }
11210
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11211
11212
#else   /* not SX */
11213
11214
0
  char *xp = (char *) *xpp;
11215
0
  int status = NC_NOERR;
11216
11217
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11218
0
  {
11219
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11220
0
    if (status == NC_NOERR) /* report the first encountered error */
11221
0
      status = lstatus;
11222
0
  }
11223
11224
0
  *xpp = (void *)xp;
11225
0
  return status;
11226
0
#endif
11227
0
}
11228
11229
int
11230
ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11231
0
{
11232
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11233
11234
 /* basic algorithm is:
11235
  *   - ensure sane alignment of output data
11236
  *   - copy (conversion happens automatically) input data
11237
  *     to output
11238
  *   - update tp to point at next unconverted input, and xpp to point
11239
  *     at next location for converted output
11240
  */
11241
  long i, j, ni;
11242
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11243
  ushort *xp;
11244
  int nrange = 0;         /* number of range errors */
11245
  int realign = 0;        /* "do we need to fix input data alignment?" */
11246
  long cxp = (long) *((char**)xpp);
11247
11248
  realign = (cxp & 7) % SIZEOF_USHORT;
11249
  /* sjl: manually stripmine so we can limit amount of
11250
   * vector work space reserved to LOOPCNT elements. Also
11251
   * makes vectorisation easy */
11252
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11253
    ni=Min(nelems-j,LOOPCNT);
11254
    if (realign) {
11255
      xp = tmp;
11256
    } else {
11257
      xp = (ushort *) *xpp;
11258
    }
11259
   /* copy the next block */
11260
#pragma cdir loopcnt=LOOPCNT
11261
#pragma cdir shortloop
11262
    for (i=0; i<ni; i++) {
11263
      /* the normal case: */
11264
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11265
     /* test for range errors (not always needed but do it anyway) */
11266
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11267
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11268
      nrange += tp[i] > X_USHORT_MAX ;
11269
    }
11270
   /* copy workspace back if necessary */
11271
    if (realign) {
11272
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11273
      xp = (ushort *) *xpp;
11274
    }
11275
   /* update xpp and tp */
11276
    xp += ni;
11277
    tp += ni;
11278
    *xpp = (void*)xp;
11279
  }
11280
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11281
11282
#else   /* not SX */
11283
11284
0
  char *xp = (char *) *xpp;
11285
0
  int status = NC_NOERR;
11286
11287
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11288
0
  {
11289
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11290
0
    if (status == NC_NOERR) /* report the first encountered error */
11291
0
      status = lstatus;
11292
0
  }
11293
11294
0
  *xpp = (void *)xp;
11295
0
  return status;
11296
0
#endif
11297
0
}
11298
11299
int
11300
ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11301
0
{
11302
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11303
11304
 /* basic algorithm is:
11305
  *   - ensure sane alignment of output data
11306
  *   - copy (conversion happens automatically) input data
11307
  *     to output
11308
  *   - update tp to point at next unconverted input, and xpp to point
11309
  *     at next location for converted output
11310
  */
11311
  long i, j, ni;
11312
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11313
  ushort *xp;
11314
  int nrange = 0;         /* number of range errors */
11315
  int realign = 0;        /* "do we need to fix input data alignment?" */
11316
  long cxp = (long) *((char**)xpp);
11317
11318
  realign = (cxp & 7) % SIZEOF_USHORT;
11319
  /* sjl: manually stripmine so we can limit amount of
11320
   * vector work space reserved to LOOPCNT elements. Also
11321
   * makes vectorisation easy */
11322
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11323
    ni=Min(nelems-j,LOOPCNT);
11324
    if (realign) {
11325
      xp = tmp;
11326
    } else {
11327
      xp = (ushort *) *xpp;
11328
    }
11329
   /* copy the next block */
11330
#pragma cdir loopcnt=LOOPCNT
11331
#pragma cdir shortloop
11332
    for (i=0; i<ni; i++) {
11333
      /* the normal case: */
11334
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11335
     /* test for range errors (not always needed but do it anyway) */
11336
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11337
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11338
      nrange += tp[i] > X_USHORT_MAX ;
11339
    }
11340
   /* copy workspace back if necessary */
11341
    if (realign) {
11342
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11343
      xp = (ushort *) *xpp;
11344
    }
11345
   /* update xpp and tp */
11346
    xp += ni;
11347
    tp += ni;
11348
    *xpp = (void*)xp;
11349
  }
11350
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11351
11352
#else   /* not SX */
11353
11354
0
  char *xp = (char *) *xpp;
11355
0
  int status = NC_NOERR;
11356
11357
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11358
0
  {
11359
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11360
0
    if (status == NC_NOERR) /* report the first encountered error */
11361
0
      status = lstatus;
11362
0
  }
11363
11364
0
  *xpp = (void *)xp;
11365
0
  return status;
11366
0
#endif
11367
0
}
11368
11369
11370
int
11371
ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
11372
0
{
11373
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11374
11375
0
  char *xp = (char *) *xpp;
11376
0
  int status = NC_NOERR;
11377
11378
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11379
0
  {
11380
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
11381
0
    if (status == NC_NOERR) /* report the first encountered error */
11382
0
      status = lstatus;
11383
0
  }
11384
11385
0
  if (rndup != 0)
11386
0
  {
11387
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11388
0
    xp += X_SIZEOF_USHORT;
11389
0
  }
11390
11391
0
  *xpp = (void *)xp;
11392
0
  return status;
11393
0
}
11394
11395
int
11396
ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11397
0
{
11398
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11399
11400
0
  char *xp = (char *) *xpp;
11401
0
  int status = NC_NOERR;
11402
11403
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11404
0
  {
11405
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11406
0
    if (status == NC_NOERR) /* report the first encountered error */
11407
0
      status = lstatus;
11408
0
  }
11409
11410
0
  if (rndup != 0)
11411
0
  {
11412
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11413
0
    xp += X_SIZEOF_USHORT;
11414
0
  }
11415
11416
0
  *xpp = (void *)xp;
11417
0
  return status;
11418
0
}
11419
11420
int
11421
ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
11422
0
{
11423
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11424
11425
0
  char *xp = (char *) *xpp;
11426
0
  int status = NC_NOERR;
11427
11428
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11429
0
  {
11430
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11431
0
    if (status == NC_NOERR) /* report the first encountered error */
11432
0
      status = lstatus;
11433
0
  }
11434
11435
0
  if (rndup != 0)
11436
0
  {
11437
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11438
0
    xp += X_SIZEOF_USHORT;
11439
0
  }
11440
11441
0
  *xpp = (void *)xp;
11442
0
  return status;
11443
0
}
11444
11445
int
11446
ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11447
0
{
11448
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11449
11450
0
  char *xp = (char *) *xpp;
11451
0
  int status = NC_NOERR;
11452
11453
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11454
0
  {
11455
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11456
0
    if (status == NC_NOERR) /* report the first encountered error */
11457
0
      status = lstatus;
11458
0
  }
11459
11460
0
  if (rndup != 0)
11461
0
  {
11462
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11463
0
    xp += X_SIZEOF_USHORT;
11464
0
  }
11465
11466
0
  *xpp = (void *)xp;
11467
0
  return status;
11468
0
}
11469
11470
int
11471
ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11472
0
{
11473
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11474
11475
0
  char *xp = (char *) *xpp;
11476
0
  int status = NC_NOERR;
11477
11478
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11479
0
  {
11480
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11481
0
    if (status == NC_NOERR) /* report the first encountered error */
11482
0
      status = lstatus;
11483
0
  }
11484
11485
0
  if (rndup != 0)
11486
0
  {
11487
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11488
0
    xp += X_SIZEOF_USHORT;
11489
0
  }
11490
11491
0
  *xpp = (void *)xp;
11492
0
  return status;
11493
0
}
11494
11495
int
11496
ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11497
0
{
11498
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11499
11500
0
  char *xp = (char *) *xpp;
11501
0
  int status = NC_NOERR;
11502
11503
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11504
0
  {
11505
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11506
0
    if (status == NC_NOERR) /* report the first encountered error */
11507
0
      status = lstatus;
11508
0
  }
11509
11510
0
  if (rndup != 0)
11511
0
  {
11512
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11513
0
    xp += X_SIZEOF_USHORT;
11514
0
  }
11515
11516
0
  *xpp = (void *)xp;
11517
0
  return status;
11518
0
}
11519
11520
int
11521
ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11522
0
{
11523
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11524
11525
0
  char *xp = (char *) *xpp;
11526
0
  int status = NC_NOERR;
11527
11528
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11529
0
  {
11530
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11531
0
    if (status == NC_NOERR) /* report the first encountered error */
11532
0
      status = lstatus;
11533
0
  }
11534
11535
0
  if (rndup != 0)
11536
0
  {
11537
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11538
0
    xp += X_SIZEOF_USHORT;
11539
0
  }
11540
11541
0
  *xpp = (void *)xp;
11542
0
  return status;
11543
0
}
11544
11545
int
11546
ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11547
0
{
11548
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11549
11550
0
  char *xp = (char *) *xpp;
11551
0
  int status = NC_NOERR;
11552
11553
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11554
0
  {
11555
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11556
0
    if (status == NC_NOERR) /* report the first encountered error */
11557
0
      status = lstatus;
11558
0
  }
11559
11560
0
  if (rndup != 0)
11561
0
  {
11562
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11563
0
    xp += X_SIZEOF_USHORT;
11564
0
  }
11565
11566
0
  *xpp = (void *)xp;
11567
0
  return status;
11568
0
}
11569
11570
int
11571
ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11572
0
{
11573
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11574
11575
0
  char *xp = (char *) *xpp;
11576
0
  int status = NC_NOERR;
11577
11578
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11579
0
  {
11580
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11581
0
    if (status == NC_NOERR) /* report the first encountered error */
11582
0
      status = lstatus;
11583
0
  }
11584
11585
0
  if (rndup != 0)
11586
0
  {
11587
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11588
0
    xp += X_SIZEOF_USHORT;
11589
0
  }
11590
11591
0
  *xpp = (void *)xp;
11592
0
  return status;
11593
0
}
11594
11595
int
11596
ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11597
0
{
11598
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11599
11600
0
  char *xp = (char *) *xpp;
11601
0
  int status = NC_NOERR;
11602
11603
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11604
0
  {
11605
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11606
0
    if (status == NC_NOERR) /* report the first encountered error */
11607
0
      status = lstatus;
11608
0
  }
11609
11610
0
  if (rndup != 0)
11611
0
  {
11612
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11613
0
    xp += X_SIZEOF_USHORT;
11614
0
  }
11615
11616
0
  *xpp = (void *)xp;
11617
0
  return status;
11618
0
}
11619
11620
int
11621
ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
11622
0
{
11623
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11624
11625
0
  char *xp = (char *) *xpp;
11626
0
  int status = NC_NOERR;
11627
11628
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11629
0
  {
11630
0
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
11631
0
    if (status == NC_NOERR) /* report the first encountered error */
11632
0
      status = lstatus;
11633
0
  }
11634
11635
0
  if (rndup != 0)
11636
0
  {
11637
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11638
0
    xp += X_SIZEOF_USHORT;
11639
0
  }
11640
11641
0
  *xpp = (void *)xp;
11642
0
  return status;
11643
0
}
11644
11645
11646
11647
/* int -----------------------------------------------------------------------*/
11648
11649
#if X_SIZEOF_INT == SIZEOF_INT
11650
/* optimized version */
11651
int
11652
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11653
131k
{
11654
#ifdef WORDS_BIGENDIAN
11655
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
11656
# else
11657
131k
  swapn4b(tp, *xpp, nelems);
11658
131k
# endif
11659
131k
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
11660
131k
  return NC_NOERR;
11661
131k
}
11662
#else
11663
int
11664
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11665
{
11666
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11667
11668
 /* basic algorithm is:
11669
  *   - ensure sane alignment of input data
11670
  *   - copy (conversion happens automatically) input data
11671
  *     to output
11672
  *   - update xpp to point at next unconverted input, and tp to point
11673
  *     at next location for converted output
11674
  */
11675
  long i, j, ni;
11676
  int tmp[LOOPCNT];        /* in case input is misaligned */
11677
  int *xp;
11678
  int nrange = 0;         /* number of range errors */
11679
  int realign = 0;        /* "do we need to fix input data alignment?" */
11680
  long cxp = (long) *((char**)xpp);
11681
11682
  realign = (cxp & 7) % SIZEOF_INT;
11683
  /* sjl: manually stripmine so we can limit amount of
11684
   * vector work space reserved to LOOPCNT elements. Also
11685
   * makes vectorisation easy */
11686
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11687
    ni=Min(nelems-j,LOOPCNT);
11688
    if (realign) {
11689
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11690
      xp = tmp;
11691
    } else {
11692
      xp = (int *) *xpp;
11693
    }
11694
   /* copy the next block */
11695
#pragma cdir loopcnt=LOOPCNT
11696
#pragma cdir shortloop
11697
    for (i=0; i<ni; i++) {
11698
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
11699
     /* test for range errors (not always needed but do it anyway) */
11700
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11701
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11702
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
11703
    }
11704
   /* update xpp and tp */
11705
    if (realign) xp = (int *) *xpp;
11706
    xp += ni;
11707
    tp += ni;
11708
    *xpp = (void*)xp;
11709
  }
11710
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11711
11712
#else   /* not SX */
11713
  const char *xp = (const char *) *xpp;
11714
  int status = NC_NOERR;
11715
11716
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11717
  {
11718
    const int lstatus = ncx_get_int_int(xp, tp);
11719
    if (status == NC_NOERR) /* report the first encountered error */
11720
      status = lstatus;
11721
  }
11722
11723
  *xpp = (const void *)xp;
11724
  return status;
11725
#endif
11726
}
11727
11728
#endif
11729
int
11730
ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
11731
0
{
11732
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11733
11734
 /* basic algorithm is:
11735
  *   - ensure sane alignment of input data
11736
  *   - copy (conversion happens automatically) input data
11737
  *     to output
11738
  *   - update xpp to point at next unconverted input, and tp to point
11739
  *     at next location for converted output
11740
  */
11741
  long i, j, ni;
11742
  int tmp[LOOPCNT];        /* in case input is misaligned */
11743
  int *xp;
11744
  int nrange = 0;         /* number of range errors */
11745
  int realign = 0;        /* "do we need to fix input data alignment?" */
11746
  long cxp = (long) *((char**)xpp);
11747
11748
  realign = (cxp & 7) % SIZEOF_INT;
11749
  /* sjl: manually stripmine so we can limit amount of
11750
   * vector work space reserved to LOOPCNT elements. Also
11751
   * makes vectorisation easy */
11752
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11753
    ni=Min(nelems-j,LOOPCNT);
11754
    if (realign) {
11755
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11756
      xp = tmp;
11757
    } else {
11758
      xp = (int *) *xpp;
11759
    }
11760
   /* copy the next block */
11761
#pragma cdir loopcnt=LOOPCNT
11762
#pragma cdir shortloop
11763
    for (i=0; i<ni; i++) {
11764
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
11765
     /* test for range errors (not always needed but do it anyway) */
11766
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11767
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11768
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
11769
    }
11770
   /* update xpp and tp */
11771
    if (realign) xp = (int *) *xpp;
11772
    xp += ni;
11773
    tp += ni;
11774
    *xpp = (void*)xp;
11775
  }
11776
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11777
11778
#else   /* not SX */
11779
0
  const char *xp = (const char *) *xpp;
11780
0
  int status = NC_NOERR;
11781
11782
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11783
0
  {
11784
0
    const int lstatus = ncx_get_int_schar(xp, tp);
11785
0
    if (status == NC_NOERR) /* report the first encountered error */
11786
0
      status = lstatus;
11787
0
  }
11788
11789
0
  *xpp = (const void *)xp;
11790
0
  return status;
11791
0
#endif
11792
0
}
11793
11794
int
11795
ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
11796
0
{
11797
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11798
11799
 /* basic algorithm is:
11800
  *   - ensure sane alignment of input data
11801
  *   - copy (conversion happens automatically) input data
11802
  *     to output
11803
  *   - update xpp to point at next unconverted input, and tp to point
11804
  *     at next location for converted output
11805
  */
11806
  long i, j, ni;
11807
  int tmp[LOOPCNT];        /* in case input is misaligned */
11808
  int *xp;
11809
  int nrange = 0;         /* number of range errors */
11810
  int realign = 0;        /* "do we need to fix input data alignment?" */
11811
  long cxp = (long) *((char**)xpp);
11812
11813
  realign = (cxp & 7) % SIZEOF_INT;
11814
  /* sjl: manually stripmine so we can limit amount of
11815
   * vector work space reserved to LOOPCNT elements. Also
11816
   * makes vectorisation easy */
11817
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11818
    ni=Min(nelems-j,LOOPCNT);
11819
    if (realign) {
11820
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11821
      xp = tmp;
11822
    } else {
11823
      xp = (int *) *xpp;
11824
    }
11825
   /* copy the next block */
11826
#pragma cdir loopcnt=LOOPCNT
11827
#pragma cdir shortloop
11828
    for (i=0; i<ni; i++) {
11829
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
11830
     /* test for range errors (not always needed but do it anyway) */
11831
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11832
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11833
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
11834
    }
11835
   /* update xpp and tp */
11836
    if (realign) xp = (int *) *xpp;
11837
    xp += ni;
11838
    tp += ni;
11839
    *xpp = (void*)xp;
11840
  }
11841
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11842
11843
#else   /* not SX */
11844
0
  const char *xp = (const char *) *xpp;
11845
0
  int status = NC_NOERR;
11846
11847
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11848
0
  {
11849
0
    const int lstatus = ncx_get_int_short(xp, tp);
11850
0
    if (status == NC_NOERR) /* report the first encountered error */
11851
0
      status = lstatus;
11852
0
  }
11853
11854
0
  *xpp = (const void *)xp;
11855
0
  return status;
11856
0
#endif
11857
0
}
11858
11859
int
11860
ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
11861
0
{
11862
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11863
11864
 /* basic algorithm is:
11865
  *   - ensure sane alignment of input data
11866
  *   - copy (conversion happens automatically) input data
11867
  *     to output
11868
  *   - update xpp to point at next unconverted input, and tp to point
11869
  *     at next location for converted output
11870
  */
11871
  long i, j, ni;
11872
  int tmp[LOOPCNT];        /* in case input is misaligned */
11873
  int *xp;
11874
  int nrange = 0;         /* number of range errors */
11875
  int realign = 0;        /* "do we need to fix input data alignment?" */
11876
  long cxp = (long) *((char**)xpp);
11877
11878
  realign = (cxp & 7) % SIZEOF_INT;
11879
  /* sjl: manually stripmine so we can limit amount of
11880
   * vector work space reserved to LOOPCNT elements. Also
11881
   * makes vectorisation easy */
11882
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11883
    ni=Min(nelems-j,LOOPCNT);
11884
    if (realign) {
11885
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11886
      xp = tmp;
11887
    } else {
11888
      xp = (int *) *xpp;
11889
    }
11890
   /* copy the next block */
11891
#pragma cdir loopcnt=LOOPCNT
11892
#pragma cdir shortloop
11893
    for (i=0; i<ni; i++) {
11894
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
11895
     /* test for range errors (not always needed but do it anyway) */
11896
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11897
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11898
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
11899
    }
11900
   /* update xpp and tp */
11901
    if (realign) xp = (int *) *xpp;
11902
    xp += ni;
11903
    tp += ni;
11904
    *xpp = (void*)xp;
11905
  }
11906
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11907
11908
#else   /* not SX */
11909
0
  const char *xp = (const char *) *xpp;
11910
0
  int status = NC_NOERR;
11911
11912
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11913
0
  {
11914
0
    const int lstatus = ncx_get_int_long(xp, tp);
11915
0
    if (status == NC_NOERR) /* report the first encountered error */
11916
0
      status = lstatus;
11917
0
  }
11918
11919
0
  *xpp = (const void *)xp;
11920
0
  return status;
11921
0
#endif
11922
0
}
11923
11924
int
11925
ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
11926
0
{
11927
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11928
11929
 /* basic algorithm is:
11930
  *   - ensure sane alignment of input data
11931
  *   - copy (conversion happens automatically) input data
11932
  *     to output
11933
  *   - update xpp to point at next unconverted input, and tp to point
11934
  *     at next location for converted output
11935
  */
11936
  long i, j, ni;
11937
  int tmp[LOOPCNT];        /* in case input is misaligned */
11938
  int *xp;
11939
  int nrange = 0;         /* number of range errors */
11940
  int realign = 0;        /* "do we need to fix input data alignment?" */
11941
  long cxp = (long) *((char**)xpp);
11942
11943
  realign = (cxp & 7) % SIZEOF_INT;
11944
  /* sjl: manually stripmine so we can limit amount of
11945
   * vector work space reserved to LOOPCNT elements. Also
11946
   * makes vectorisation easy */
11947
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11948
    ni=Min(nelems-j,LOOPCNT);
11949
    if (realign) {
11950
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11951
      xp = tmp;
11952
    } else {
11953
      xp = (int *) *xpp;
11954
    }
11955
   /* copy the next block */
11956
#pragma cdir loopcnt=LOOPCNT
11957
#pragma cdir shortloop
11958
    for (i=0; i<ni; i++) {
11959
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
11960
     /* test for range errors (not always needed but do it anyway) */
11961
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11962
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11963
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
11964
    }
11965
   /* update xpp and tp */
11966
    if (realign) xp = (int *) *xpp;
11967
    xp += ni;
11968
    tp += ni;
11969
    *xpp = (void*)xp;
11970
  }
11971
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11972
11973
#else   /* not SX */
11974
0
  const char *xp = (const char *) *xpp;
11975
0
  int status = NC_NOERR;
11976
11977
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11978
0
  {
11979
0
    const int lstatus = ncx_get_int_float(xp, tp);
11980
0
    if (status == NC_NOERR) /* report the first encountered error */
11981
0
      status = lstatus;
11982
0
  }
11983
11984
0
  *xpp = (const void *)xp;
11985
0
  return status;
11986
0
#endif
11987
0
}
11988
11989
int
11990
ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
11991
0
{
11992
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11993
11994
 /* basic algorithm is:
11995
  *   - ensure sane alignment of input data
11996
  *   - copy (conversion happens automatically) input data
11997
  *     to output
11998
  *   - update xpp to point at next unconverted input, and tp to point
11999
  *     at next location for converted output
12000
  */
12001
  long i, j, ni;
12002
  int tmp[LOOPCNT];        /* in case input is misaligned */
12003
  int *xp;
12004
  int nrange = 0;         /* number of range errors */
12005
  int realign = 0;        /* "do we need to fix input data alignment?" */
12006
  long cxp = (long) *((char**)xpp);
12007
12008
  realign = (cxp & 7) % SIZEOF_INT;
12009
  /* sjl: manually stripmine so we can limit amount of
12010
   * vector work space reserved to LOOPCNT elements. Also
12011
   * makes vectorisation easy */
12012
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12013
    ni=Min(nelems-j,LOOPCNT);
12014
    if (realign) {
12015
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12016
      xp = tmp;
12017
    } else {
12018
      xp = (int *) *xpp;
12019
    }
12020
   /* copy the next block */
12021
#pragma cdir loopcnt=LOOPCNT
12022
#pragma cdir shortloop
12023
    for (i=0; i<ni; i++) {
12024
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
12025
     /* test for range errors (not always needed but do it anyway) */
12026
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12027
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12028
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
12029
    }
12030
   /* update xpp and tp */
12031
    if (realign) xp = (int *) *xpp;
12032
    xp += ni;
12033
    tp += ni;
12034
    *xpp = (void*)xp;
12035
  }
12036
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12037
12038
#else   /* not SX */
12039
0
  const char *xp = (const char *) *xpp;
12040
0
  int status = NC_NOERR;
12041
12042
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12043
0
  {
12044
0
    const int lstatus = ncx_get_int_double(xp, tp);
12045
0
    if (status == NC_NOERR) /* report the first encountered error */
12046
0
      status = lstatus;
12047
0
  }
12048
12049
0
  *xpp = (const void *)xp;
12050
0
  return status;
12051
0
#endif
12052
0
}
12053
12054
int
12055
ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp)
12056
0
{
12057
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12058
12059
 /* basic algorithm is:
12060
  *   - ensure sane alignment of input data
12061
  *   - copy (conversion happens automatically) input data
12062
  *     to output
12063
  *   - update xpp to point at next unconverted input, and tp to point
12064
  *     at next location for converted output
12065
  */
12066
  long i, j, ni;
12067
  int tmp[LOOPCNT];        /* in case input is misaligned */
12068
  int *xp;
12069
  int nrange = 0;         /* number of range errors */
12070
  int realign = 0;        /* "do we need to fix input data alignment?" */
12071
  long cxp = (long) *((char**)xpp);
12072
12073
  realign = (cxp & 7) % SIZEOF_INT;
12074
  /* sjl: manually stripmine so we can limit amount of
12075
   * vector work space reserved to LOOPCNT elements. Also
12076
   * makes vectorisation easy */
12077
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12078
    ni=Min(nelems-j,LOOPCNT);
12079
    if (realign) {
12080
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12081
      xp = tmp;
12082
    } else {
12083
      xp = (int *) *xpp;
12084
    }
12085
   /* copy the next block */
12086
#pragma cdir loopcnt=LOOPCNT
12087
#pragma cdir shortloop
12088
    for (i=0; i<ni; i++) {
12089
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
12090
     /* test for range errors (not always needed but do it anyway) */
12091
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12092
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12093
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
12094
    }
12095
   /* update xpp and tp */
12096
    if (realign) xp = (int *) *xpp;
12097
    xp += ni;
12098
    tp += ni;
12099
    *xpp = (void*)xp;
12100
  }
12101
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12102
12103
#else   /* not SX */
12104
0
  const char *xp = (const char *) *xpp;
12105
0
  int status = NC_NOERR;
12106
12107
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12108
0
  {
12109
0
    const int lstatus = ncx_get_int_longlong(xp, tp);
12110
0
    if (status == NC_NOERR) /* report the first encountered error */
12111
0
      status = lstatus;
12112
0
  }
12113
12114
0
  *xpp = (const void *)xp;
12115
0
  return status;
12116
0
#endif
12117
0
}
12118
12119
int
12120
ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
12121
0
{
12122
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12123
12124
 /* basic algorithm is:
12125
  *   - ensure sane alignment of input data
12126
  *   - copy (conversion happens automatically) input data
12127
  *     to output
12128
  *   - update xpp to point at next unconverted input, and tp to point
12129
  *     at next location for converted output
12130
  */
12131
  long i, j, ni;
12132
  int tmp[LOOPCNT];        /* in case input is misaligned */
12133
  int *xp;
12134
  int nrange = 0;         /* number of range errors */
12135
  int realign = 0;        /* "do we need to fix input data alignment?" */
12136
  long cxp = (long) *((char**)xpp);
12137
12138
  realign = (cxp & 7) % SIZEOF_INT;
12139
  /* sjl: manually stripmine so we can limit amount of
12140
   * vector work space reserved to LOOPCNT elements. Also
12141
   * makes vectorisation easy */
12142
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12143
    ni=Min(nelems-j,LOOPCNT);
12144
    if (realign) {
12145
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12146
      xp = tmp;
12147
    } else {
12148
      xp = (int *) *xpp;
12149
    }
12150
   /* copy the next block */
12151
#pragma cdir loopcnt=LOOPCNT
12152
#pragma cdir shortloop
12153
    for (i=0; i<ni; i++) {
12154
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
12155
     /* test for range errors (not always needed but do it anyway) */
12156
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12157
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12158
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
12159
    }
12160
   /* update xpp and tp */
12161
    if (realign) xp = (int *) *xpp;
12162
    xp += ni;
12163
    tp += ni;
12164
    *xpp = (void*)xp;
12165
  }
12166
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12167
12168
#else   /* not SX */
12169
0
  const char *xp = (const char *) *xpp;
12170
0
  int status = NC_NOERR;
12171
12172
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12173
0
  {
12174
0
    const int lstatus = ncx_get_int_uchar(xp, tp);
12175
0
    if (status == NC_NOERR) /* report the first encountered error */
12176
0
      status = lstatus;
12177
0
  }
12178
12179
0
  *xpp = (const void *)xp;
12180
0
  return status;
12181
0
#endif
12182
0
}
12183
12184
int
12185
ncx_getn_int_ushort(const void **xpp, size_t nelems, ushort *tp)
12186
0
{
12187
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12188
12189
 /* basic algorithm is:
12190
  *   - ensure sane alignment of input data
12191
  *   - copy (conversion happens automatically) input data
12192
  *     to output
12193
  *   - update xpp to point at next unconverted input, and tp to point
12194
  *     at next location for converted output
12195
  */
12196
  long i, j, ni;
12197
  int tmp[LOOPCNT];        /* in case input is misaligned */
12198
  int *xp;
12199
  int nrange = 0;         /* number of range errors */
12200
  int realign = 0;        /* "do we need to fix input data alignment?" */
12201
  long cxp = (long) *((char**)xpp);
12202
12203
  realign = (cxp & 7) % SIZEOF_INT;
12204
  /* sjl: manually stripmine so we can limit amount of
12205
   * vector work space reserved to LOOPCNT elements. Also
12206
   * makes vectorisation easy */
12207
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12208
    ni=Min(nelems-j,LOOPCNT);
12209
    if (realign) {
12210
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12211
      xp = tmp;
12212
    } else {
12213
      xp = (int *) *xpp;
12214
    }
12215
   /* copy the next block */
12216
#pragma cdir loopcnt=LOOPCNT
12217
#pragma cdir shortloop
12218
    for (i=0; i<ni; i++) {
12219
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
12220
     /* test for range errors (not always needed but do it anyway) */
12221
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12222
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12223
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
12224
    }
12225
   /* update xpp and tp */
12226
    if (realign) xp = (int *) *xpp;
12227
    xp += ni;
12228
    tp += ni;
12229
    *xpp = (void*)xp;
12230
  }
12231
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12232
12233
#else   /* not SX */
12234
0
  const char *xp = (const char *) *xpp;
12235
0
  int status = NC_NOERR;
12236
12237
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12238
0
  {
12239
0
    const int lstatus = ncx_get_int_ushort(xp, tp);
12240
0
    if (status == NC_NOERR) /* report the first encountered error */
12241
0
      status = lstatus;
12242
0
  }
12243
12244
0
  *xpp = (const void *)xp;
12245
0
  return status;
12246
0
#endif
12247
0
}
12248
12249
int
12250
ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp)
12251
0
{
12252
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12253
12254
 /* basic algorithm is:
12255
  *   - ensure sane alignment of input data
12256
  *   - copy (conversion happens automatically) input data
12257
  *     to output
12258
  *   - update xpp to point at next unconverted input, and tp to point
12259
  *     at next location for converted output
12260
  */
12261
  long i, j, ni;
12262
  int tmp[LOOPCNT];        /* in case input is misaligned */
12263
  int *xp;
12264
  int nrange = 0;         /* number of range errors */
12265
  int realign = 0;        /* "do we need to fix input data alignment?" */
12266
  long cxp = (long) *((char**)xpp);
12267
12268
  realign = (cxp & 7) % SIZEOF_INT;
12269
  /* sjl: manually stripmine so we can limit amount of
12270
   * vector work space reserved to LOOPCNT elements. Also
12271
   * makes vectorisation easy */
12272
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12273
    ni=Min(nelems-j,LOOPCNT);
12274
    if (realign) {
12275
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12276
      xp = tmp;
12277
    } else {
12278
      xp = (int *) *xpp;
12279
    }
12280
   /* copy the next block */
12281
#pragma cdir loopcnt=LOOPCNT
12282
#pragma cdir shortloop
12283
    for (i=0; i<ni; i++) {
12284
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
12285
     /* test for range errors (not always needed but do it anyway) */
12286
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12287
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12288
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
12289
    }
12290
   /* update xpp and tp */
12291
    if (realign) xp = (int *) *xpp;
12292
    xp += ni;
12293
    tp += ni;
12294
    *xpp = (void*)xp;
12295
  }
12296
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12297
12298
#else   /* not SX */
12299
0
  const char *xp = (const char *) *xpp;
12300
0
  int status = NC_NOERR;
12301
12302
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12303
0
  {
12304
0
    const int lstatus = ncx_get_int_uint(xp, tp);
12305
0
    if (status == NC_NOERR) /* report the first encountered error */
12306
0
      status = lstatus;
12307
0
  }
12308
12309
0
  *xpp = (const void *)xp;
12310
0
  return status;
12311
0
#endif
12312
0
}
12313
12314
int
12315
ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
12316
0
{
12317
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12318
12319
 /* basic algorithm is:
12320
  *   - ensure sane alignment of input data
12321
  *   - copy (conversion happens automatically) input data
12322
  *     to output
12323
  *   - update xpp to point at next unconverted input, and tp to point
12324
  *     at next location for converted output
12325
  */
12326
  long i, j, ni;
12327
  int tmp[LOOPCNT];        /* in case input is misaligned */
12328
  int *xp;
12329
  int nrange = 0;         /* number of range errors */
12330
  int realign = 0;        /* "do we need to fix input data alignment?" */
12331
  long cxp = (long) *((char**)xpp);
12332
12333
  realign = (cxp & 7) % SIZEOF_INT;
12334
  /* sjl: manually stripmine so we can limit amount of
12335
   * vector work space reserved to LOOPCNT elements. Also
12336
   * makes vectorisation easy */
12337
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12338
    ni=Min(nelems-j,LOOPCNT);
12339
    if (realign) {
12340
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12341
      xp = tmp;
12342
    } else {
12343
      xp = (int *) *xpp;
12344
    }
12345
   /* copy the next block */
12346
#pragma cdir loopcnt=LOOPCNT
12347
#pragma cdir shortloop
12348
    for (i=0; i<ni; i++) {
12349
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
12350
     /* test for range errors (not always needed but do it anyway) */
12351
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12352
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12353
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
12354
    }
12355
   /* update xpp and tp */
12356
    if (realign) xp = (int *) *xpp;
12357
    xp += ni;
12358
    tp += ni;
12359
    *xpp = (void*)xp;
12360
  }
12361
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12362
12363
#else   /* not SX */
12364
0
  const char *xp = (const char *) *xpp;
12365
0
  int status = NC_NOERR;
12366
12367
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12368
0
  {
12369
0
    const int lstatus = ncx_get_int_ulonglong(xp, tp);
12370
0
    if (status == NC_NOERR) /* report the first encountered error */
12371
0
      status = lstatus;
12372
0
  }
12373
12374
0
  *xpp = (const void *)xp;
12375
0
  return status;
12376
0
#endif
12377
0
}
12378
12379
12380
#if X_SIZEOF_INT == SIZEOF_INT
12381
/* optimized version */
12382
int
12383
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12384
0
{
12385
#ifdef WORDS_BIGENDIAN
12386
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
12387
# else
12388
0
  swapn4b(*xpp, tp, nelems);
12389
0
# endif
12390
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
12391
0
  return NC_NOERR;
12392
0
}
12393
#else
12394
int
12395
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12396
{
12397
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12398
12399
 /* basic algorithm is:
12400
  *   - ensure sane alignment of output data
12401
  *   - copy (conversion happens automatically) input data
12402
  *     to output
12403
  *   - update tp to point at next unconverted input, and xpp to point
12404
  *     at next location for converted output
12405
  */
12406
  long i, j, ni;
12407
  int tmp[LOOPCNT];        /* in case input is misaligned */
12408
  int *xp;
12409
  int nrange = 0;         /* number of range errors */
12410
  int realign = 0;        /* "do we need to fix input data alignment?" */
12411
  long cxp = (long) *((char**)xpp);
12412
12413
  realign = (cxp & 7) % SIZEOF_INT;
12414
  /* sjl: manually stripmine so we can limit amount of
12415
   * vector work space reserved to LOOPCNT elements. Also
12416
   * makes vectorisation easy */
12417
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12418
    ni=Min(nelems-j,LOOPCNT);
12419
    if (realign) {
12420
      xp = tmp;
12421
    } else {
12422
      xp = (int *) *xpp;
12423
    }
12424
   /* copy the next block */
12425
#pragma cdir loopcnt=LOOPCNT
12426
#pragma cdir shortloop
12427
    for (i=0; i<ni; i++) {
12428
      /* the normal case: */
12429
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12430
     /* test for range errors (not always needed but do it anyway) */
12431
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12432
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12433
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12434
    }
12435
   /* copy workspace back if necessary */
12436
    if (realign) {
12437
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12438
      xp = (int *) *xpp;
12439
    }
12440
   /* update xpp and tp */
12441
    xp += ni;
12442
    tp += ni;
12443
    *xpp = (void*)xp;
12444
  }
12445
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12446
12447
#else   /* not SX */
12448
12449
  char *xp = (char *) *xpp;
12450
  int status = NC_NOERR;
12451
12452
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12453
  {
12454
    int lstatus = ncx_put_int_int(xp, tp, fillp);
12455
    if (status == NC_NOERR) /* report the first encountered error */
12456
      status = lstatus;
12457
  }
12458
12459
  *xpp = (void *)xp;
12460
  return status;
12461
#endif
12462
}
12463
12464
#endif
12465
int
12466
ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
12467
0
{
12468
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12469
12470
 /* basic algorithm is:
12471
  *   - ensure sane alignment of output data
12472
  *   - copy (conversion happens automatically) input data
12473
  *     to output
12474
  *   - update tp to point at next unconverted input, and xpp to point
12475
  *     at next location for converted output
12476
  */
12477
  long i, j, ni;
12478
  int tmp[LOOPCNT];        /* in case input is misaligned */
12479
  int *xp;
12480
  int nrange = 0;         /* number of range errors */
12481
  int realign = 0;        /* "do we need to fix input data alignment?" */
12482
  long cxp = (long) *((char**)xpp);
12483
12484
  realign = (cxp & 7) % SIZEOF_INT;
12485
  /* sjl: manually stripmine so we can limit amount of
12486
   * vector work space reserved to LOOPCNT elements. Also
12487
   * makes vectorisation easy */
12488
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12489
    ni=Min(nelems-j,LOOPCNT);
12490
    if (realign) {
12491
      xp = tmp;
12492
    } else {
12493
      xp = (int *) *xpp;
12494
    }
12495
   /* copy the next block */
12496
#pragma cdir loopcnt=LOOPCNT
12497
#pragma cdir shortloop
12498
    for (i=0; i<ni; i++) {
12499
      /* the normal case: */
12500
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12501
     /* test for range errors (not always needed but do it anyway) */
12502
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12503
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12504
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12505
    }
12506
   /* copy workspace back if necessary */
12507
    if (realign) {
12508
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12509
      xp = (int *) *xpp;
12510
    }
12511
   /* update xpp and tp */
12512
    xp += ni;
12513
    tp += ni;
12514
    *xpp = (void*)xp;
12515
  }
12516
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12517
12518
#else   /* not SX */
12519
12520
0
  char *xp = (char *) *xpp;
12521
0
  int status = NC_NOERR;
12522
12523
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12524
0
  {
12525
0
    int lstatus = ncx_put_int_schar(xp, tp, fillp);
12526
0
    if (status == NC_NOERR) /* report the first encountered error */
12527
0
      status = lstatus;
12528
0
  }
12529
12530
0
  *xpp = (void *)xp;
12531
0
  return status;
12532
0
#endif
12533
0
}
12534
12535
int
12536
ncx_putn_int_short(void **xpp, size_t nelems, const short *tp, void *fillp)
12537
0
{
12538
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12539
12540
 /* basic algorithm is:
12541
  *   - ensure sane alignment of output data
12542
  *   - copy (conversion happens automatically) input data
12543
  *     to output
12544
  *   - update tp to point at next unconverted input, and xpp to point
12545
  *     at next location for converted output
12546
  */
12547
  long i, j, ni;
12548
  int tmp[LOOPCNT];        /* in case input is misaligned */
12549
  int *xp;
12550
  int nrange = 0;         /* number of range errors */
12551
  int realign = 0;        /* "do we need to fix input data alignment?" */
12552
  long cxp = (long) *((char**)xpp);
12553
12554
  realign = (cxp & 7) % SIZEOF_INT;
12555
  /* sjl: manually stripmine so we can limit amount of
12556
   * vector work space reserved to LOOPCNT elements. Also
12557
   * makes vectorisation easy */
12558
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12559
    ni=Min(nelems-j,LOOPCNT);
12560
    if (realign) {
12561
      xp = tmp;
12562
    } else {
12563
      xp = (int *) *xpp;
12564
    }
12565
   /* copy the next block */
12566
#pragma cdir loopcnt=LOOPCNT
12567
#pragma cdir shortloop
12568
    for (i=0; i<ni; i++) {
12569
      /* the normal case: */
12570
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12571
     /* test for range errors (not always needed but do it anyway) */
12572
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12573
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12574
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12575
    }
12576
   /* copy workspace back if necessary */
12577
    if (realign) {
12578
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12579
      xp = (int *) *xpp;
12580
    }
12581
   /* update xpp and tp */
12582
    xp += ni;
12583
    tp += ni;
12584
    *xpp = (void*)xp;
12585
  }
12586
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12587
12588
#else   /* not SX */
12589
12590
0
  char *xp = (char *) *xpp;
12591
0
  int status = NC_NOERR;
12592
12593
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12594
0
  {
12595
0
    int lstatus = ncx_put_int_short(xp, tp, fillp);
12596
0
    if (status == NC_NOERR) /* report the first encountered error */
12597
0
      status = lstatus;
12598
0
  }
12599
12600
0
  *xpp = (void *)xp;
12601
0
  return status;
12602
0
#endif
12603
0
}
12604
12605
int
12606
ncx_putn_int_long(void **xpp, size_t nelems, const long *tp, void *fillp)
12607
0
{
12608
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12609
12610
 /* basic algorithm is:
12611
  *   - ensure sane alignment of output data
12612
  *   - copy (conversion happens automatically) input data
12613
  *     to output
12614
  *   - update tp to point at next unconverted input, and xpp to point
12615
  *     at next location for converted output
12616
  */
12617
  long i, j, ni;
12618
  int tmp[LOOPCNT];        /* in case input is misaligned */
12619
  int *xp;
12620
  int nrange = 0;         /* number of range errors */
12621
  int realign = 0;        /* "do we need to fix input data alignment?" */
12622
  long cxp = (long) *((char**)xpp);
12623
12624
  realign = (cxp & 7) % SIZEOF_INT;
12625
  /* sjl: manually stripmine so we can limit amount of
12626
   * vector work space reserved to LOOPCNT elements. Also
12627
   * makes vectorisation easy */
12628
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12629
    ni=Min(nelems-j,LOOPCNT);
12630
    if (realign) {
12631
      xp = tmp;
12632
    } else {
12633
      xp = (int *) *xpp;
12634
    }
12635
   /* copy the next block */
12636
#pragma cdir loopcnt=LOOPCNT
12637
#pragma cdir shortloop
12638
    for (i=0; i<ni; i++) {
12639
      /* the normal case: */
12640
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12641
     /* test for range errors (not always needed but do it anyway) */
12642
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12643
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12644
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12645
    }
12646
   /* copy workspace back if necessary */
12647
    if (realign) {
12648
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12649
      xp = (int *) *xpp;
12650
    }
12651
   /* update xpp and tp */
12652
    xp += ni;
12653
    tp += ni;
12654
    *xpp = (void*)xp;
12655
  }
12656
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12657
12658
#else   /* not SX */
12659
12660
0
  char *xp = (char *) *xpp;
12661
0
  int status = NC_NOERR;
12662
12663
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12664
0
  {
12665
0
    int lstatus = ncx_put_int_long(xp, tp, fillp);
12666
0
    if (status == NC_NOERR) /* report the first encountered error */
12667
0
      status = lstatus;
12668
0
  }
12669
12670
0
  *xpp = (void *)xp;
12671
0
  return status;
12672
0
#endif
12673
0
}
12674
12675
int
12676
ncx_putn_int_float(void **xpp, size_t nelems, const float *tp, void *fillp)
12677
0
{
12678
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12679
12680
 /* basic algorithm is:
12681
  *   - ensure sane alignment of output data
12682
  *   - copy (conversion happens automatically) input data
12683
  *     to output
12684
  *   - update tp to point at next unconverted input, and xpp to point
12685
  *     at next location for converted output
12686
  */
12687
  long i, j, ni;
12688
  int tmp[LOOPCNT];        /* in case input is misaligned */
12689
  int *xp;
12690
  double d;               /* special case for ncx_putn_int_float */
12691
  int nrange = 0;         /* number of range errors */
12692
  int realign = 0;        /* "do we need to fix input data alignment?" */
12693
  long cxp = (long) *((char**)xpp);
12694
12695
  realign = (cxp & 7) % SIZEOF_INT;
12696
  /* sjl: manually stripmine so we can limit amount of
12697
   * vector work space reserved to LOOPCNT elements. Also
12698
   * makes vectorisation easy */
12699
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12700
    ni=Min(nelems-j,LOOPCNT);
12701
    if (realign) {
12702
      xp = tmp;
12703
    } else {
12704
      xp = (int *) *xpp;
12705
    }
12706
   /* copy the next block */
12707
#pragma cdir loopcnt=LOOPCNT
12708
#pragma cdir shortloop
12709
    for (i=0; i<ni; i++) {
12710
      /* for some reason int to float, for putn, requires a special case */
12711
      d = tp[i];
12712
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
12713
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12714
    }
12715
   /* copy workspace back if necessary */
12716
    if (realign) {
12717
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12718
      xp = (int *) *xpp;
12719
    }
12720
   /* update xpp and tp */
12721
    xp += ni;
12722
    tp += ni;
12723
    *xpp = (void*)xp;
12724
  }
12725
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12726
12727
#else   /* not SX */
12728
12729
0
  char *xp = (char *) *xpp;
12730
0
  int status = NC_NOERR;
12731
12732
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12733
0
  {
12734
0
    int lstatus = ncx_put_int_float(xp, tp, fillp);
12735
0
    if (status == NC_NOERR) /* report the first encountered error */
12736
0
      status = lstatus;
12737
0
  }
12738
12739
0
  *xpp = (void *)xp;
12740
0
  return status;
12741
0
#endif
12742
0
}
12743
12744
int
12745
ncx_putn_int_double(void **xpp, size_t nelems, const double *tp, void *fillp)
12746
0
{
12747
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12748
12749
 /* basic algorithm is:
12750
  *   - ensure sane alignment of output data
12751
  *   - copy (conversion happens automatically) input data
12752
  *     to output
12753
  *   - update tp to point at next unconverted input, and xpp to point
12754
  *     at next location for converted output
12755
  */
12756
  long i, j, ni;
12757
  int tmp[LOOPCNT];        /* in case input is misaligned */
12758
  int *xp;
12759
  int nrange = 0;         /* number of range errors */
12760
  int realign = 0;        /* "do we need to fix input data alignment?" */
12761
  long cxp = (long) *((char**)xpp);
12762
12763
  realign = (cxp & 7) % SIZEOF_INT;
12764
  /* sjl: manually stripmine so we can limit amount of
12765
   * vector work space reserved to LOOPCNT elements. Also
12766
   * makes vectorisation easy */
12767
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12768
    ni=Min(nelems-j,LOOPCNT);
12769
    if (realign) {
12770
      xp = tmp;
12771
    } else {
12772
      xp = (int *) *xpp;
12773
    }
12774
   /* copy the next block */
12775
#pragma cdir loopcnt=LOOPCNT
12776
#pragma cdir shortloop
12777
    for (i=0; i<ni; i++) {
12778
      /* the normal case: */
12779
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12780
     /* test for range errors (not always needed but do it anyway) */
12781
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12782
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12783
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12784
    }
12785
   /* copy workspace back if necessary */
12786
    if (realign) {
12787
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12788
      xp = (int *) *xpp;
12789
    }
12790
   /* update xpp and tp */
12791
    xp += ni;
12792
    tp += ni;
12793
    *xpp = (void*)xp;
12794
  }
12795
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12796
12797
#else   /* not SX */
12798
12799
0
  char *xp = (char *) *xpp;
12800
0
  int status = NC_NOERR;
12801
12802
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12803
0
  {
12804
0
    int lstatus = ncx_put_int_double(xp, tp, fillp);
12805
0
    if (status == NC_NOERR) /* report the first encountered error */
12806
0
      status = lstatus;
12807
0
  }
12808
12809
0
  *xpp = (void *)xp;
12810
0
  return status;
12811
0
#endif
12812
0
}
12813
12814
int
12815
ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
12816
0
{
12817
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12818
12819
 /* basic algorithm is:
12820
  *   - ensure sane alignment of output data
12821
  *   - copy (conversion happens automatically) input data
12822
  *     to output
12823
  *   - update tp to point at next unconverted input, and xpp to point
12824
  *     at next location for converted output
12825
  */
12826
  long i, j, ni;
12827
  int tmp[LOOPCNT];        /* in case input is misaligned */
12828
  int *xp;
12829
  int nrange = 0;         /* number of range errors */
12830
  int realign = 0;        /* "do we need to fix input data alignment?" */
12831
  long cxp = (long) *((char**)xpp);
12832
12833
  realign = (cxp & 7) % SIZEOF_INT;
12834
  /* sjl: manually stripmine so we can limit amount of
12835
   * vector work space reserved to LOOPCNT elements. Also
12836
   * makes vectorisation easy */
12837
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12838
    ni=Min(nelems-j,LOOPCNT);
12839
    if (realign) {
12840
      xp = tmp;
12841
    } else {
12842
      xp = (int *) *xpp;
12843
    }
12844
   /* copy the next block */
12845
#pragma cdir loopcnt=LOOPCNT
12846
#pragma cdir shortloop
12847
    for (i=0; i<ni; i++) {
12848
      /* the normal case: */
12849
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12850
     /* test for range errors (not always needed but do it anyway) */
12851
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12852
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12853
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12854
    }
12855
   /* copy workspace back if necessary */
12856
    if (realign) {
12857
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12858
      xp = (int *) *xpp;
12859
    }
12860
   /* update xpp and tp */
12861
    xp += ni;
12862
    tp += ni;
12863
    *xpp = (void*)xp;
12864
  }
12865
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12866
12867
#else   /* not SX */
12868
12869
0
  char *xp = (char *) *xpp;
12870
0
  int status = NC_NOERR;
12871
12872
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12873
0
  {
12874
0
    int lstatus = ncx_put_int_longlong(xp, tp, fillp);
12875
0
    if (status == NC_NOERR) /* report the first encountered error */
12876
0
      status = lstatus;
12877
0
  }
12878
12879
0
  *xpp = (void *)xp;
12880
0
  return status;
12881
0
#endif
12882
0
}
12883
12884
int
12885
ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
12886
0
{
12887
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12888
12889
 /* basic algorithm is:
12890
  *   - ensure sane alignment of output data
12891
  *   - copy (conversion happens automatically) input data
12892
  *     to output
12893
  *   - update tp to point at next unconverted input, and xpp to point
12894
  *     at next location for converted output
12895
  */
12896
  long i, j, ni;
12897
  int tmp[LOOPCNT];        /* in case input is misaligned */
12898
  int *xp;
12899
  int nrange = 0;         /* number of range errors */
12900
  int realign = 0;        /* "do we need to fix input data alignment?" */
12901
  long cxp = (long) *((char**)xpp);
12902
12903
  realign = (cxp & 7) % SIZEOF_INT;
12904
  /* sjl: manually stripmine so we can limit amount of
12905
   * vector work space reserved to LOOPCNT elements. Also
12906
   * makes vectorisation easy */
12907
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12908
    ni=Min(nelems-j,LOOPCNT);
12909
    if (realign) {
12910
      xp = tmp;
12911
    } else {
12912
      xp = (int *) *xpp;
12913
    }
12914
   /* copy the next block */
12915
#pragma cdir loopcnt=LOOPCNT
12916
#pragma cdir shortloop
12917
    for (i=0; i<ni; i++) {
12918
      /* the normal case: */
12919
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12920
     /* test for range errors (not always needed but do it anyway) */
12921
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12922
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12923
      nrange += tp[i] > X_INT_MAX ;
12924
    }
12925
   /* copy workspace back if necessary */
12926
    if (realign) {
12927
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12928
      xp = (int *) *xpp;
12929
    }
12930
   /* update xpp and tp */
12931
    xp += ni;
12932
    tp += ni;
12933
    *xpp = (void*)xp;
12934
  }
12935
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12936
12937
#else   /* not SX */
12938
12939
0
  char *xp = (char *) *xpp;
12940
0
  int status = NC_NOERR;
12941
12942
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12943
0
  {
12944
0
    int lstatus = ncx_put_int_uchar(xp, tp, fillp);
12945
0
    if (status == NC_NOERR) /* report the first encountered error */
12946
0
      status = lstatus;
12947
0
  }
12948
12949
0
  *xpp = (void *)xp;
12950
0
  return status;
12951
0
#endif
12952
0
}
12953
12954
int
12955
ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
12956
0
{
12957
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12958
12959
 /* basic algorithm is:
12960
  *   - ensure sane alignment of output data
12961
  *   - copy (conversion happens automatically) input data
12962
  *     to output
12963
  *   - update tp to point at next unconverted input, and xpp to point
12964
  *     at next location for converted output
12965
  */
12966
  long i, j, ni;
12967
  int tmp[LOOPCNT];        /* in case input is misaligned */
12968
  int *xp;
12969
  int nrange = 0;         /* number of range errors */
12970
  int realign = 0;        /* "do we need to fix input data alignment?" */
12971
  long cxp = (long) *((char**)xpp);
12972
12973
  realign = (cxp & 7) % SIZEOF_INT;
12974
  /* sjl: manually stripmine so we can limit amount of
12975
   * vector work space reserved to LOOPCNT elements. Also
12976
   * makes vectorisation easy */
12977
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12978
    ni=Min(nelems-j,LOOPCNT);
12979
    if (realign) {
12980
      xp = tmp;
12981
    } else {
12982
      xp = (int *) *xpp;
12983
    }
12984
   /* copy the next block */
12985
#pragma cdir loopcnt=LOOPCNT
12986
#pragma cdir shortloop
12987
    for (i=0; i<ni; i++) {
12988
      /* the normal case: */
12989
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12990
     /* test for range errors (not always needed but do it anyway) */
12991
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12992
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12993
      nrange += tp[i] > X_INT_MAX ;
12994
    }
12995
   /* copy workspace back if necessary */
12996
    if (realign) {
12997
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12998
      xp = (int *) *xpp;
12999
    }
13000
   /* update xpp and tp */
13001
    xp += ni;
13002
    tp += ni;
13003
    *xpp = (void*)xp;
13004
  }
13005
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13006
13007
#else   /* not SX */
13008
13009
0
  char *xp = (char *) *xpp;
13010
0
  int status = NC_NOERR;
13011
13012
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13013
0
  {
13014
0
    int lstatus = ncx_put_int_ushort(xp, tp, fillp);
13015
0
    if (status == NC_NOERR) /* report the first encountered error */
13016
0
      status = lstatus;
13017
0
  }
13018
13019
0
  *xpp = (void *)xp;
13020
0
  return status;
13021
0
#endif
13022
0
}
13023
13024
int
13025
ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13026
0
{
13027
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13028
13029
 /* basic algorithm is:
13030
  *   - ensure sane alignment of output data
13031
  *   - copy (conversion happens automatically) input data
13032
  *     to output
13033
  *   - update tp to point at next unconverted input, and xpp to point
13034
  *     at next location for converted output
13035
  */
13036
  long i, j, ni;
13037
  int tmp[LOOPCNT];        /* in case input is misaligned */
13038
  int *xp;
13039
  int nrange = 0;         /* number of range errors */
13040
  int realign = 0;        /* "do we need to fix input data alignment?" */
13041
  long cxp = (long) *((char**)xpp);
13042
13043
  realign = (cxp & 7) % SIZEOF_INT;
13044
  /* sjl: manually stripmine so we can limit amount of
13045
   * vector work space reserved to LOOPCNT elements. Also
13046
   * makes vectorisation easy */
13047
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13048
    ni=Min(nelems-j,LOOPCNT);
13049
    if (realign) {
13050
      xp = tmp;
13051
    } else {
13052
      xp = (int *) *xpp;
13053
    }
13054
   /* copy the next block */
13055
#pragma cdir loopcnt=LOOPCNT
13056
#pragma cdir shortloop
13057
    for (i=0; i<ni; i++) {
13058
      /* the normal case: */
13059
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13060
     /* test for range errors (not always needed but do it anyway) */
13061
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13062
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13063
      nrange += tp[i] > X_INT_MAX ;
13064
    }
13065
   /* copy workspace back if necessary */
13066
    if (realign) {
13067
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13068
      xp = (int *) *xpp;
13069
    }
13070
   /* update xpp and tp */
13071
    xp += ni;
13072
    tp += ni;
13073
    *xpp = (void*)xp;
13074
  }
13075
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13076
13077
#else   /* not SX */
13078
13079
0
  char *xp = (char *) *xpp;
13080
0
  int status = NC_NOERR;
13081
13082
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13083
0
  {
13084
0
    int lstatus = ncx_put_int_uint(xp, tp, fillp);
13085
0
    if (status == NC_NOERR) /* report the first encountered error */
13086
0
      status = lstatus;
13087
0
  }
13088
13089
0
  *xpp = (void *)xp;
13090
0
  return status;
13091
0
#endif
13092
0
}
13093
13094
int
13095
ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
13096
0
{
13097
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13098
13099
 /* basic algorithm is:
13100
  *   - ensure sane alignment of output data
13101
  *   - copy (conversion happens automatically) input data
13102
  *     to output
13103
  *   - update tp to point at next unconverted input, and xpp to point
13104
  *     at next location for converted output
13105
  */
13106
  long i, j, ni;
13107
  int tmp[LOOPCNT];        /* in case input is misaligned */
13108
  int *xp;
13109
  int nrange = 0;         /* number of range errors */
13110
  int realign = 0;        /* "do we need to fix input data alignment?" */
13111
  long cxp = (long) *((char**)xpp);
13112
13113
  realign = (cxp & 7) % SIZEOF_INT;
13114
  /* sjl: manually stripmine so we can limit amount of
13115
   * vector work space reserved to LOOPCNT elements. Also
13116
   * makes vectorisation easy */
13117
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13118
    ni=Min(nelems-j,LOOPCNT);
13119
    if (realign) {
13120
      xp = tmp;
13121
    } else {
13122
      xp = (int *) *xpp;
13123
    }
13124
   /* copy the next block */
13125
#pragma cdir loopcnt=LOOPCNT
13126
#pragma cdir shortloop
13127
    for (i=0; i<ni; i++) {
13128
      /* the normal case: */
13129
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13130
     /* test for range errors (not always needed but do it anyway) */
13131
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13132
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13133
      nrange += tp[i] > X_INT_MAX ;
13134
    }
13135
   /* copy workspace back if necessary */
13136
    if (realign) {
13137
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13138
      xp = (int *) *xpp;
13139
    }
13140
   /* update xpp and tp */
13141
    xp += ni;
13142
    tp += ni;
13143
    *xpp = (void*)xp;
13144
  }
13145
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13146
13147
#else   /* not SX */
13148
13149
0
  char *xp = (char *) *xpp;
13150
0
  int status = NC_NOERR;
13151
13152
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13153
0
  {
13154
0
    int lstatus = ncx_put_int_ulonglong(xp, tp, fillp);
13155
0
    if (status == NC_NOERR) /* report the first encountered error */
13156
0
      status = lstatus;
13157
0
  }
13158
13159
0
  *xpp = (void *)xp;
13160
0
  return status;
13161
0
#endif
13162
0
}
13163
13164
13165
/* uint ----------------------------------------------------------------------*/
13166
13167
#if X_SIZEOF_UINT == SIZEOF_UINT
13168
/* optimized version */
13169
int
13170
ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
13171
0
{
13172
#ifdef WORDS_BIGENDIAN
13173
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
13174
# else
13175
0
  swapn4b(tp, *xpp, nelems);
13176
0
# endif
13177
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
13178
0
  return NC_NOERR;
13179
0
}
13180
#else
13181
int
13182
ncx_getn_uint_uint(const void **xpp, size_t nelems, uint *tp)
13183
{
13184
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13185
13186
 /* basic algorithm is:
13187
  *   - ensure sane alignment of input data
13188
  *   - copy (conversion happens automatically) input data
13189
  *     to output
13190
  *   - update xpp to point at next unconverted input, and tp to point
13191
  *     at next location for converted output
13192
  */
13193
  long i, j, ni;
13194
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13195
  uint *xp;
13196
  int nrange = 0;         /* number of range errors */
13197
  int realign = 0;        /* "do we need to fix input data alignment?" */
13198
  long cxp = (long) *((char**)xpp);
13199
13200
  realign = (cxp & 7) % SIZEOF_UINT;
13201
  /* sjl: manually stripmine so we can limit amount of
13202
   * vector work space reserved to LOOPCNT elements. Also
13203
   * makes vectorisation easy */
13204
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13205
    ni=Min(nelems-j,LOOPCNT);
13206
    if (realign) {
13207
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13208
      xp = tmp;
13209
    } else {
13210
      xp = (uint *) *xpp;
13211
    }
13212
   /* copy the next block */
13213
#pragma cdir loopcnt=LOOPCNT
13214
#pragma cdir shortloop
13215
    for (i=0; i<ni; i++) {
13216
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
13217
     /* test for range errors (not always needed but do it anyway) */
13218
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13219
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13220
      nrange += xp[i] > UINT_MAX ;
13221
    }
13222
   /* update xpp and tp */
13223
    if (realign) xp = (uint *) *xpp;
13224
    xp += ni;
13225
    tp += ni;
13226
    *xpp = (void*)xp;
13227
  }
13228
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13229
13230
#else   /* not SX */
13231
  const char *xp = (const char *) *xpp;
13232
  int status = NC_NOERR;
13233
13234
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13235
  {
13236
    const int lstatus = ncx_get_uint_uint(xp, tp);
13237
    if (status == NC_NOERR) /* report the first encountered error */
13238
      status = lstatus;
13239
  }
13240
13241
  *xpp = (const void *)xp;
13242
  return status;
13243
#endif
13244
}
13245
13246
#endif
13247
int
13248
ncx_getn_uint_schar(const void **xpp, size_t nelems, schar *tp)
13249
0
{
13250
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13251
13252
 /* basic algorithm is:
13253
  *   - ensure sane alignment of input data
13254
  *   - copy (conversion happens automatically) input data
13255
  *     to output
13256
  *   - update xpp to point at next unconverted input, and tp to point
13257
  *     at next location for converted output
13258
  */
13259
  long i, j, ni;
13260
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13261
  uint *xp;
13262
  int nrange = 0;         /* number of range errors */
13263
  int realign = 0;        /* "do we need to fix input data alignment?" */
13264
  long cxp = (long) *((char**)xpp);
13265
13266
  realign = (cxp & 7) % SIZEOF_UINT;
13267
  /* sjl: manually stripmine so we can limit amount of
13268
   * vector work space reserved to LOOPCNT elements. Also
13269
   * makes vectorisation easy */
13270
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13271
    ni=Min(nelems-j,LOOPCNT);
13272
    if (realign) {
13273
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13274
      xp = tmp;
13275
    } else {
13276
      xp = (uint *) *xpp;
13277
    }
13278
   /* copy the next block */
13279
#pragma cdir loopcnt=LOOPCNT
13280
#pragma cdir shortloop
13281
    for (i=0; i<ni; i++) {
13282
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
13283
     /* test for range errors (not always needed but do it anyway) */
13284
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13285
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13286
      nrange += xp[i] > SCHAR_MAX ;
13287
    }
13288
   /* update xpp and tp */
13289
    if (realign) xp = (uint *) *xpp;
13290
    xp += ni;
13291
    tp += ni;
13292
    *xpp = (void*)xp;
13293
  }
13294
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13295
13296
#else   /* not SX */
13297
0
  const char *xp = (const char *) *xpp;
13298
0
  int status = NC_NOERR;
13299
13300
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13301
0
  {
13302
0
    const int lstatus = ncx_get_uint_schar(xp, tp);
13303
0
    if (status == NC_NOERR) /* report the first encountered error */
13304
0
      status = lstatus;
13305
0
  }
13306
13307
0
  *xpp = (const void *)xp;
13308
0
  return status;
13309
0
#endif
13310
0
}
13311
13312
int
13313
ncx_getn_uint_short(const void **xpp, size_t nelems, short *tp)
13314
0
{
13315
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13316
13317
 /* basic algorithm is:
13318
  *   - ensure sane alignment of input data
13319
  *   - copy (conversion happens automatically) input data
13320
  *     to output
13321
  *   - update xpp to point at next unconverted input, and tp to point
13322
  *     at next location for converted output
13323
  */
13324
  long i, j, ni;
13325
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13326
  uint *xp;
13327
  int nrange = 0;         /* number of range errors */
13328
  int realign = 0;        /* "do we need to fix input data alignment?" */
13329
  long cxp = (long) *((char**)xpp);
13330
13331
  realign = (cxp & 7) % SIZEOF_UINT;
13332
  /* sjl: manually stripmine so we can limit amount of
13333
   * vector work space reserved to LOOPCNT elements. Also
13334
   * makes vectorisation easy */
13335
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13336
    ni=Min(nelems-j,LOOPCNT);
13337
    if (realign) {
13338
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13339
      xp = tmp;
13340
    } else {
13341
      xp = (uint *) *xpp;
13342
    }
13343
   /* copy the next block */
13344
#pragma cdir loopcnt=LOOPCNT
13345
#pragma cdir shortloop
13346
    for (i=0; i<ni; i++) {
13347
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
13348
     /* test for range errors (not always needed but do it anyway) */
13349
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13350
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13351
      nrange += xp[i] > SHORT_MAX ;
13352
    }
13353
   /* update xpp and tp */
13354
    if (realign) xp = (uint *) *xpp;
13355
    xp += ni;
13356
    tp += ni;
13357
    *xpp = (void*)xp;
13358
  }
13359
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13360
13361
#else   /* not SX */
13362
0
  const char *xp = (const char *) *xpp;
13363
0
  int status = NC_NOERR;
13364
13365
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13366
0
  {
13367
0
    const int lstatus = ncx_get_uint_short(xp, tp);
13368
0
    if (status == NC_NOERR) /* report the first encountered error */
13369
0
      status = lstatus;
13370
0
  }
13371
13372
0
  *xpp = (const void *)xp;
13373
0
  return status;
13374
0
#endif
13375
0
}
13376
13377
int
13378
ncx_getn_uint_int(const void **xpp, size_t nelems, int *tp)
13379
0
{
13380
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13381
13382
 /* basic algorithm is:
13383
  *   - ensure sane alignment of input data
13384
  *   - copy (conversion happens automatically) input data
13385
  *     to output
13386
  *   - update xpp to point at next unconverted input, and tp to point
13387
  *     at next location for converted output
13388
  */
13389
  long i, j, ni;
13390
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13391
  uint *xp;
13392
  int nrange = 0;         /* number of range errors */
13393
  int realign = 0;        /* "do we need to fix input data alignment?" */
13394
  long cxp = (long) *((char**)xpp);
13395
13396
  realign = (cxp & 7) % SIZEOF_UINT;
13397
  /* sjl: manually stripmine so we can limit amount of
13398
   * vector work space reserved to LOOPCNT elements. Also
13399
   * makes vectorisation easy */
13400
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13401
    ni=Min(nelems-j,LOOPCNT);
13402
    if (realign) {
13403
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13404
      xp = tmp;
13405
    } else {
13406
      xp = (uint *) *xpp;
13407
    }
13408
   /* copy the next block */
13409
#pragma cdir loopcnt=LOOPCNT
13410
#pragma cdir shortloop
13411
    for (i=0; i<ni; i++) {
13412
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
13413
     /* test for range errors (not always needed but do it anyway) */
13414
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13415
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13416
      nrange += xp[i] > INT_MAX ;
13417
    }
13418
   /* update xpp and tp */
13419
    if (realign) xp = (uint *) *xpp;
13420
    xp += ni;
13421
    tp += ni;
13422
    *xpp = (void*)xp;
13423
  }
13424
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13425
13426
#else   /* not SX */
13427
0
  const char *xp = (const char *) *xpp;
13428
0
  int status = NC_NOERR;
13429
13430
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13431
0
  {
13432
0
    const int lstatus = ncx_get_uint_int(xp, tp);
13433
0
    if (status == NC_NOERR) /* report the first encountered error */
13434
0
      status = lstatus;
13435
0
  }
13436
13437
0
  *xpp = (const void *)xp;
13438
0
  return status;
13439
0
#endif
13440
0
}
13441
13442
int
13443
ncx_getn_uint_long(const void **xpp, size_t nelems, long *tp)
13444
0
{
13445
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13446
13447
 /* basic algorithm is:
13448
  *   - ensure sane alignment of input data
13449
  *   - copy (conversion happens automatically) input data
13450
  *     to output
13451
  *   - update xpp to point at next unconverted input, and tp to point
13452
  *     at next location for converted output
13453
  */
13454
  long i, j, ni;
13455
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13456
  uint *xp;
13457
  int nrange = 0;         /* number of range errors */
13458
  int realign = 0;        /* "do we need to fix input data alignment?" */
13459
  long cxp = (long) *((char**)xpp);
13460
13461
  realign = (cxp & 7) % SIZEOF_UINT;
13462
  /* sjl: manually stripmine so we can limit amount of
13463
   * vector work space reserved to LOOPCNT elements. Also
13464
   * makes vectorisation easy */
13465
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13466
    ni=Min(nelems-j,LOOPCNT);
13467
    if (realign) {
13468
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13469
      xp = tmp;
13470
    } else {
13471
      xp = (uint *) *xpp;
13472
    }
13473
   /* copy the next block */
13474
#pragma cdir loopcnt=LOOPCNT
13475
#pragma cdir shortloop
13476
    for (i=0; i<ni; i++) {
13477
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
13478
     /* test for range errors (not always needed but do it anyway) */
13479
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13480
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13481
      nrange += xp[i] > LONG_MAX ;
13482
    }
13483
   /* update xpp and tp */
13484
    if (realign) xp = (uint *) *xpp;
13485
    xp += ni;
13486
    tp += ni;
13487
    *xpp = (void*)xp;
13488
  }
13489
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13490
13491
#else   /* not SX */
13492
0
  const char *xp = (const char *) *xpp;
13493
0
  int status = NC_NOERR;
13494
13495
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13496
0
  {
13497
0
    const int lstatus = ncx_get_uint_long(xp, tp);
13498
0
    if (status == NC_NOERR) /* report the first encountered error */
13499
0
      status = lstatus;
13500
0
  }
13501
13502
0
  *xpp = (const void *)xp;
13503
0
  return status;
13504
0
#endif
13505
0
}
13506
13507
int
13508
ncx_getn_uint_float(const void **xpp, size_t nelems, float *tp)
13509
0
{
13510
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13511
13512
 /* basic algorithm is:
13513
  *   - ensure sane alignment of input data
13514
  *   - copy (conversion happens automatically) input data
13515
  *     to output
13516
  *   - update xpp to point at next unconverted input, and tp to point
13517
  *     at next location for converted output
13518
  */
13519
  long i, j, ni;
13520
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13521
  uint *xp;
13522
  int nrange = 0;         /* number of range errors */
13523
  int realign = 0;        /* "do we need to fix input data alignment?" */
13524
  long cxp = (long) *((char**)xpp);
13525
13526
  realign = (cxp & 7) % SIZEOF_UINT;
13527
  /* sjl: manually stripmine so we can limit amount of
13528
   * vector work space reserved to LOOPCNT elements. Also
13529
   * makes vectorisation easy */
13530
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13531
    ni=Min(nelems-j,LOOPCNT);
13532
    if (realign) {
13533
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13534
      xp = tmp;
13535
    } else {
13536
      xp = (uint *) *xpp;
13537
    }
13538
   /* copy the next block */
13539
#pragma cdir loopcnt=LOOPCNT
13540
#pragma cdir shortloop
13541
    for (i=0; i<ni; i++) {
13542
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
13543
     /* test for range errors (not always needed but do it anyway) */
13544
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13545
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13546
      nrange += xp[i] > FLOAT_MAX ;
13547
    }
13548
   /* update xpp and tp */
13549
    if (realign) xp = (uint *) *xpp;
13550
    xp += ni;
13551
    tp += ni;
13552
    *xpp = (void*)xp;
13553
  }
13554
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13555
13556
#else   /* not SX */
13557
0
  const char *xp = (const char *) *xpp;
13558
0
  int status = NC_NOERR;
13559
13560
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13561
0
  {
13562
0
    const int lstatus = ncx_get_uint_float(xp, tp);
13563
0
    if (status == NC_NOERR) /* report the first encountered error */
13564
0
      status = lstatus;
13565
0
  }
13566
13567
0
  *xpp = (const void *)xp;
13568
0
  return status;
13569
0
#endif
13570
0
}
13571
13572
int
13573
ncx_getn_uint_double(const void **xpp, size_t nelems, double *tp)
13574
0
{
13575
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13576
13577
 /* basic algorithm is:
13578
  *   - ensure sane alignment of input data
13579
  *   - copy (conversion happens automatically) input data
13580
  *     to output
13581
  *   - update xpp to point at next unconverted input, and tp to point
13582
  *     at next location for converted output
13583
  */
13584
  long i, j, ni;
13585
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13586
  uint *xp;
13587
  int nrange = 0;         /* number of range errors */
13588
  int realign = 0;        /* "do we need to fix input data alignment?" */
13589
  long cxp = (long) *((char**)xpp);
13590
13591
  realign = (cxp & 7) % SIZEOF_UINT;
13592
  /* sjl: manually stripmine so we can limit amount of
13593
   * vector work space reserved to LOOPCNT elements. Also
13594
   * makes vectorisation easy */
13595
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13596
    ni=Min(nelems-j,LOOPCNT);
13597
    if (realign) {
13598
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13599
      xp = tmp;
13600
    } else {
13601
      xp = (uint *) *xpp;
13602
    }
13603
   /* copy the next block */
13604
#pragma cdir loopcnt=LOOPCNT
13605
#pragma cdir shortloop
13606
    for (i=0; i<ni; i++) {
13607
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
13608
     /* test for range errors (not always needed but do it anyway) */
13609
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13610
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13611
      nrange += xp[i] > DOUBLE_MAX ;
13612
    }
13613
   /* update xpp and tp */
13614
    if (realign) xp = (uint *) *xpp;
13615
    xp += ni;
13616
    tp += ni;
13617
    *xpp = (void*)xp;
13618
  }
13619
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13620
13621
#else   /* not SX */
13622
0
  const char *xp = (const char *) *xpp;
13623
0
  int status = NC_NOERR;
13624
13625
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13626
0
  {
13627
0
    const int lstatus = ncx_get_uint_double(xp, tp);
13628
0
    if (status == NC_NOERR) /* report the first encountered error */
13629
0
      status = lstatus;
13630
0
  }
13631
13632
0
  *xpp = (const void *)xp;
13633
0
  return status;
13634
0
#endif
13635
0
}
13636
13637
int
13638
ncx_getn_uint_longlong(const void **xpp, size_t nelems, longlong *tp)
13639
0
{
13640
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13641
13642
 /* basic algorithm is:
13643
  *   - ensure sane alignment of input data
13644
  *   - copy (conversion happens automatically) input data
13645
  *     to output
13646
  *   - update xpp to point at next unconverted input, and tp to point
13647
  *     at next location for converted output
13648
  */
13649
  long i, j, ni;
13650
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13651
  uint *xp;
13652
  int nrange = 0;         /* number of range errors */
13653
  int realign = 0;        /* "do we need to fix input data alignment?" */
13654
  long cxp = (long) *((char**)xpp);
13655
13656
  realign = (cxp & 7) % SIZEOF_UINT;
13657
  /* sjl: manually stripmine so we can limit amount of
13658
   * vector work space reserved to LOOPCNT elements. Also
13659
   * makes vectorisation easy */
13660
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13661
    ni=Min(nelems-j,LOOPCNT);
13662
    if (realign) {
13663
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13664
      xp = tmp;
13665
    } else {
13666
      xp = (uint *) *xpp;
13667
    }
13668
   /* copy the next block */
13669
#pragma cdir loopcnt=LOOPCNT
13670
#pragma cdir shortloop
13671
    for (i=0; i<ni; i++) {
13672
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
13673
     /* test for range errors (not always needed but do it anyway) */
13674
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13675
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13676
      nrange += xp[i] > LONGLONG_MAX ;
13677
    }
13678
   /* update xpp and tp */
13679
    if (realign) xp = (uint *) *xpp;
13680
    xp += ni;
13681
    tp += ni;
13682
    *xpp = (void*)xp;
13683
  }
13684
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13685
13686
#else   /* not SX */
13687
0
  const char *xp = (const char *) *xpp;
13688
0
  int status = NC_NOERR;
13689
13690
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13691
0
  {
13692
0
    const int lstatus = ncx_get_uint_longlong(xp, tp);
13693
0
    if (status == NC_NOERR) /* report the first encountered error */
13694
0
      status = lstatus;
13695
0
  }
13696
13697
0
  *xpp = (const void *)xp;
13698
0
  return status;
13699
0
#endif
13700
0
}
13701
13702
int
13703
ncx_getn_uint_uchar(const void **xpp, size_t nelems, uchar *tp)
13704
0
{
13705
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13706
13707
 /* basic algorithm is:
13708
  *   - ensure sane alignment of input data
13709
  *   - copy (conversion happens automatically) input data
13710
  *     to output
13711
  *   - update xpp to point at next unconverted input, and tp to point
13712
  *     at next location for converted output
13713
  */
13714
  long i, j, ni;
13715
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13716
  uint *xp;
13717
  int nrange = 0;         /* number of range errors */
13718
  int realign = 0;        /* "do we need to fix input data alignment?" */
13719
  long cxp = (long) *((char**)xpp);
13720
13721
  realign = (cxp & 7) % SIZEOF_UINT;
13722
  /* sjl: manually stripmine so we can limit amount of
13723
   * vector work space reserved to LOOPCNT elements. Also
13724
   * makes vectorisation easy */
13725
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13726
    ni=Min(nelems-j,LOOPCNT);
13727
    if (realign) {
13728
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13729
      xp = tmp;
13730
    } else {
13731
      xp = (uint *) *xpp;
13732
    }
13733
   /* copy the next block */
13734
#pragma cdir loopcnt=LOOPCNT
13735
#pragma cdir shortloop
13736
    for (i=0; i<ni; i++) {
13737
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
13738
     /* test for range errors (not always needed but do it anyway) */
13739
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13740
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13741
      nrange += xp[i] > UCHAR_MAX ;
13742
    }
13743
   /* update xpp and tp */
13744
    if (realign) xp = (uint *) *xpp;
13745
    xp += ni;
13746
    tp += ni;
13747
    *xpp = (void*)xp;
13748
  }
13749
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13750
13751
#else   /* not SX */
13752
0
  const char *xp = (const char *) *xpp;
13753
0
  int status = NC_NOERR;
13754
13755
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13756
0
  {
13757
0
    const int lstatus = ncx_get_uint_uchar(xp, tp);
13758
0
    if (status == NC_NOERR) /* report the first encountered error */
13759
0
      status = lstatus;
13760
0
  }
13761
13762
0
  *xpp = (const void *)xp;
13763
0
  return status;
13764
0
#endif
13765
0
}
13766
13767
int
13768
ncx_getn_uint_ushort(const void **xpp, size_t nelems, ushort *tp)
13769
0
{
13770
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13771
13772
 /* basic algorithm is:
13773
  *   - ensure sane alignment of input data
13774
  *   - copy (conversion happens automatically) input data
13775
  *     to output
13776
  *   - update xpp to point at next unconverted input, and tp to point
13777
  *     at next location for converted output
13778
  */
13779
  long i, j, ni;
13780
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13781
  uint *xp;
13782
  int nrange = 0;         /* number of range errors */
13783
  int realign = 0;        /* "do we need to fix input data alignment?" */
13784
  long cxp = (long) *((char**)xpp);
13785
13786
  realign = (cxp & 7) % SIZEOF_UINT;
13787
  /* sjl: manually stripmine so we can limit amount of
13788
   * vector work space reserved to LOOPCNT elements. Also
13789
   * makes vectorisation easy */
13790
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13791
    ni=Min(nelems-j,LOOPCNT);
13792
    if (realign) {
13793
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13794
      xp = tmp;
13795
    } else {
13796
      xp = (uint *) *xpp;
13797
    }
13798
   /* copy the next block */
13799
#pragma cdir loopcnt=LOOPCNT
13800
#pragma cdir shortloop
13801
    for (i=0; i<ni; i++) {
13802
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
13803
     /* test for range errors (not always needed but do it anyway) */
13804
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13805
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13806
      nrange += xp[i] > USHORT_MAX ;
13807
    }
13808
   /* update xpp and tp */
13809
    if (realign) xp = (uint *) *xpp;
13810
    xp += ni;
13811
    tp += ni;
13812
    *xpp = (void*)xp;
13813
  }
13814
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13815
13816
#else   /* not SX */
13817
0
  const char *xp = (const char *) *xpp;
13818
0
  int status = NC_NOERR;
13819
13820
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13821
0
  {
13822
0
    const int lstatus = ncx_get_uint_ushort(xp, tp);
13823
0
    if (status == NC_NOERR) /* report the first encountered error */
13824
0
      status = lstatus;
13825
0
  }
13826
13827
0
  *xpp = (const void *)xp;
13828
0
  return status;
13829
0
#endif
13830
0
}
13831
13832
int
13833
ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
13834
0
{
13835
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13836
13837
 /* basic algorithm is:
13838
  *   - ensure sane alignment of input data
13839
  *   - copy (conversion happens automatically) input data
13840
  *     to output
13841
  *   - update xpp to point at next unconverted input, and tp to point
13842
  *     at next location for converted output
13843
  */
13844
  long i, j, ni;
13845
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13846
  uint *xp;
13847
  int nrange = 0;         /* number of range errors */
13848
  int realign = 0;        /* "do we need to fix input data alignment?" */
13849
  long cxp = (long) *((char**)xpp);
13850
13851
  realign = (cxp & 7) % SIZEOF_UINT;
13852
  /* sjl: manually stripmine so we can limit amount of
13853
   * vector work space reserved to LOOPCNT elements. Also
13854
   * makes vectorisation easy */
13855
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13856
    ni=Min(nelems-j,LOOPCNT);
13857
    if (realign) {
13858
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13859
      xp = tmp;
13860
    } else {
13861
      xp = (uint *) *xpp;
13862
    }
13863
   /* copy the next block */
13864
#pragma cdir loopcnt=LOOPCNT
13865
#pragma cdir shortloop
13866
    for (i=0; i<ni; i++) {
13867
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
13868
     /* test for range errors (not always needed but do it anyway) */
13869
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13870
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13871
      nrange += xp[i] > ULONGLONG_MAX ;
13872
    }
13873
   /* update xpp and tp */
13874
    if (realign) xp = (uint *) *xpp;
13875
    xp += ni;
13876
    tp += ni;
13877
    *xpp = (void*)xp;
13878
  }
13879
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13880
13881
#else   /* not SX */
13882
0
  const char *xp = (const char *) *xpp;
13883
0
  int status = NC_NOERR;
13884
13885
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13886
0
  {
13887
0
    const int lstatus = ncx_get_uint_ulonglong(xp, tp);
13888
0
    if (status == NC_NOERR) /* report the first encountered error */
13889
0
      status = lstatus;
13890
0
  }
13891
13892
0
  *xpp = (const void *)xp;
13893
0
  return status;
13894
0
#endif
13895
0
}
13896
13897
13898
#if X_SIZEOF_UINT == SIZEOF_UINT
13899
/* optimized version */
13900
int
13901
ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp, void *fillp)
13902
0
{
13903
#ifdef WORDS_BIGENDIAN
13904
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
13905
# else
13906
0
  swapn4b(*xpp, tp, nelems);
13907
0
# endif
13908
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
13909
0
  return NC_NOERR;
13910
0
}
13911
#else
13912
int
13913
ncx_putn_uint_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13914
{
13915
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13916
13917
 /* basic algorithm is:
13918
  *   - ensure sane alignment of output data
13919
  *   - copy (conversion happens automatically) input data
13920
  *     to output
13921
  *   - update tp to point at next unconverted input, and xpp to point
13922
  *     at next location for converted output
13923
  */
13924
  long i, j, ni;
13925
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13926
  uint *xp;
13927
  int nrange = 0;         /* number of range errors */
13928
  int realign = 0;        /* "do we need to fix input data alignment?" */
13929
  long cxp = (long) *((char**)xpp);
13930
13931
  realign = (cxp & 7) % SIZEOF_UINT;
13932
  /* sjl: manually stripmine so we can limit amount of
13933
   * vector work space reserved to LOOPCNT elements. Also
13934
   * makes vectorisation easy */
13935
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13936
    ni=Min(nelems-j,LOOPCNT);
13937
    if (realign) {
13938
      xp = tmp;
13939
    } else {
13940
      xp = (uint *) *xpp;
13941
    }
13942
   /* copy the next block */
13943
#pragma cdir loopcnt=LOOPCNT
13944
#pragma cdir shortloop
13945
    for (i=0; i<ni; i++) {
13946
      /* the normal case: */
13947
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
13948
     /* test for range errors (not always needed but do it anyway) */
13949
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13950
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13951
      nrange += tp[i] > X_UINT_MAX ;
13952
    }
13953
   /* copy workspace back if necessary */
13954
    if (realign) {
13955
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
13956
      xp = (uint *) *xpp;
13957
    }
13958
   /* update xpp and tp */
13959
    xp += ni;
13960
    tp += ni;
13961
    *xpp = (void*)xp;
13962
  }
13963
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13964
13965
#else   /* not SX */
13966
13967
  char *xp = (char *) *xpp;
13968
  int status = NC_NOERR;
13969
13970
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13971
  {
13972
    int lstatus = ncx_put_uint_uint(xp, tp, fillp);
13973
    if (status == NC_NOERR) /* report the first encountered error */
13974
      status = lstatus;
13975
  }
13976
13977
  *xpp = (void *)xp;
13978
  return status;
13979
#endif
13980
}
13981
13982
#endif
13983
int
13984
ncx_putn_uint_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
13985
0
{
13986
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13987
13988
 /* basic algorithm is:
13989
  *   - ensure sane alignment of output data
13990
  *   - copy (conversion happens automatically) input data
13991
  *     to output
13992
  *   - update tp to point at next unconverted input, and xpp to point
13993
  *     at next location for converted output
13994
  */
13995
  long i, j, ni;
13996
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13997
  uint *xp;
13998
  int nrange = 0;         /* number of range errors */
13999
  int realign = 0;        /* "do we need to fix input data alignment?" */
14000
  long cxp = (long) *((char**)xpp);
14001
14002
  realign = (cxp & 7) % SIZEOF_UINT;
14003
  /* sjl: manually stripmine so we can limit amount of
14004
   * vector work space reserved to LOOPCNT elements. Also
14005
   * makes vectorisation easy */
14006
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14007
    ni=Min(nelems-j,LOOPCNT);
14008
    if (realign) {
14009
      xp = tmp;
14010
    } else {
14011
      xp = (uint *) *xpp;
14012
    }
14013
   /* copy the next block */
14014
#pragma cdir loopcnt=LOOPCNT
14015
#pragma cdir shortloop
14016
    for (i=0; i<ni; i++) {
14017
      /* the normal case: */
14018
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14019
     /* test for range errors (not always needed but do it anyway) */
14020
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14021
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14022
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14023
    }
14024
   /* copy workspace back if necessary */
14025
    if (realign) {
14026
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14027
      xp = (uint *) *xpp;
14028
    }
14029
   /* update xpp and tp */
14030
    xp += ni;
14031
    tp += ni;
14032
    *xpp = (void*)xp;
14033
  }
14034
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14035
14036
#else   /* not SX */
14037
14038
0
  char *xp = (char *) *xpp;
14039
0
  int status = NC_NOERR;
14040
14041
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14042
0
  {
14043
0
    int lstatus = ncx_put_uint_schar(xp, tp, fillp);
14044
0
    if (status == NC_NOERR) /* report the first encountered error */
14045
0
      status = lstatus;
14046
0
  }
14047
14048
0
  *xpp = (void *)xp;
14049
0
  return status;
14050
0
#endif
14051
0
}
14052
14053
int
14054
ncx_putn_uint_short(void **xpp, size_t nelems, const short *tp, void *fillp)
14055
0
{
14056
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14057
14058
 /* basic algorithm is:
14059
  *   - ensure sane alignment of output data
14060
  *   - copy (conversion happens automatically) input data
14061
  *     to output
14062
  *   - update tp to point at next unconverted input, and xpp to point
14063
  *     at next location for converted output
14064
  */
14065
  long i, j, ni;
14066
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14067
  uint *xp;
14068
  int nrange = 0;         /* number of range errors */
14069
  int realign = 0;        /* "do we need to fix input data alignment?" */
14070
  long cxp = (long) *((char**)xpp);
14071
14072
  realign = (cxp & 7) % SIZEOF_UINT;
14073
  /* sjl: manually stripmine so we can limit amount of
14074
   * vector work space reserved to LOOPCNT elements. Also
14075
   * makes vectorisation easy */
14076
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14077
    ni=Min(nelems-j,LOOPCNT);
14078
    if (realign) {
14079
      xp = tmp;
14080
    } else {
14081
      xp = (uint *) *xpp;
14082
    }
14083
   /* copy the next block */
14084
#pragma cdir loopcnt=LOOPCNT
14085
#pragma cdir shortloop
14086
    for (i=0; i<ni; i++) {
14087
      /* the normal case: */
14088
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14089
     /* test for range errors (not always needed but do it anyway) */
14090
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14091
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14092
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14093
    }
14094
   /* copy workspace back if necessary */
14095
    if (realign) {
14096
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14097
      xp = (uint *) *xpp;
14098
    }
14099
   /* update xpp and tp */
14100
    xp += ni;
14101
    tp += ni;
14102
    *xpp = (void*)xp;
14103
  }
14104
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14105
14106
#else   /* not SX */
14107
14108
0
  char *xp = (char *) *xpp;
14109
0
  int status = NC_NOERR;
14110
14111
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14112
0
  {
14113
0
    int lstatus = ncx_put_uint_short(xp, tp, fillp);
14114
0
    if (status == NC_NOERR) /* report the first encountered error */
14115
0
      status = lstatus;
14116
0
  }
14117
14118
0
  *xpp = (void *)xp;
14119
0
  return status;
14120
0
#endif
14121
0
}
14122
14123
int
14124
ncx_putn_uint_int(void **xpp, size_t nelems, const int *tp, void *fillp)
14125
0
{
14126
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14127
14128
 /* basic algorithm is:
14129
  *   - ensure sane alignment of output data
14130
  *   - copy (conversion happens automatically) input data
14131
  *     to output
14132
  *   - update tp to point at next unconverted input, and xpp to point
14133
  *     at next location for converted output
14134
  */
14135
  long i, j, ni;
14136
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14137
  uint *xp;
14138
  int nrange = 0;         /* number of range errors */
14139
  int realign = 0;        /* "do we need to fix input data alignment?" */
14140
  long cxp = (long) *((char**)xpp);
14141
14142
  realign = (cxp & 7) % SIZEOF_UINT;
14143
  /* sjl: manually stripmine so we can limit amount of
14144
   * vector work space reserved to LOOPCNT elements. Also
14145
   * makes vectorisation easy */
14146
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14147
    ni=Min(nelems-j,LOOPCNT);
14148
    if (realign) {
14149
      xp = tmp;
14150
    } else {
14151
      xp = (uint *) *xpp;
14152
    }
14153
   /* copy the next block */
14154
#pragma cdir loopcnt=LOOPCNT
14155
#pragma cdir shortloop
14156
    for (i=0; i<ni; i++) {
14157
      /* the normal case: */
14158
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14159
     /* test for range errors (not always needed but do it anyway) */
14160
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14161
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14162
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14163
    }
14164
   /* copy workspace back if necessary */
14165
    if (realign) {
14166
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14167
      xp = (uint *) *xpp;
14168
    }
14169
   /* update xpp and tp */
14170
    xp += ni;
14171
    tp += ni;
14172
    *xpp = (void*)xp;
14173
  }
14174
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14175
14176
#else   /* not SX */
14177
14178
0
  char *xp = (char *) *xpp;
14179
0
  int status = NC_NOERR;
14180
14181
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14182
0
  {
14183
0
    int lstatus = ncx_put_uint_int(xp, tp, fillp);
14184
0
    if (status == NC_NOERR) /* report the first encountered error */
14185
0
      status = lstatus;
14186
0
  }
14187
14188
0
  *xpp = (void *)xp;
14189
0
  return status;
14190
0
#endif
14191
0
}
14192
14193
int
14194
ncx_putn_uint_long(void **xpp, size_t nelems, const long *tp, void *fillp)
14195
0
{
14196
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14197
14198
 /* basic algorithm is:
14199
  *   - ensure sane alignment of output data
14200
  *   - copy (conversion happens automatically) input data
14201
  *     to output
14202
  *   - update tp to point at next unconverted input, and xpp to point
14203
  *     at next location for converted output
14204
  */
14205
  long i, j, ni;
14206
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14207
  uint *xp;
14208
  int nrange = 0;         /* number of range errors */
14209
  int realign = 0;        /* "do we need to fix input data alignment?" */
14210
  long cxp = (long) *((char**)xpp);
14211
14212
  realign = (cxp & 7) % SIZEOF_UINT;
14213
  /* sjl: manually stripmine so we can limit amount of
14214
   * vector work space reserved to LOOPCNT elements. Also
14215
   * makes vectorisation easy */
14216
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14217
    ni=Min(nelems-j,LOOPCNT);
14218
    if (realign) {
14219
      xp = tmp;
14220
    } else {
14221
      xp = (uint *) *xpp;
14222
    }
14223
   /* copy the next block */
14224
#pragma cdir loopcnt=LOOPCNT
14225
#pragma cdir shortloop
14226
    for (i=0; i<ni; i++) {
14227
      /* the normal case: */
14228
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14229
     /* test for range errors (not always needed but do it anyway) */
14230
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14231
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14232
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14233
    }
14234
   /* copy workspace back if necessary */
14235
    if (realign) {
14236
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14237
      xp = (uint *) *xpp;
14238
    }
14239
   /* update xpp and tp */
14240
    xp += ni;
14241
    tp += ni;
14242
    *xpp = (void*)xp;
14243
  }
14244
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14245
14246
#else   /* not SX */
14247
14248
0
  char *xp = (char *) *xpp;
14249
0
  int status = NC_NOERR;
14250
14251
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14252
0
  {
14253
0
    int lstatus = ncx_put_uint_long(xp, tp, fillp);
14254
0
    if (status == NC_NOERR) /* report the first encountered error */
14255
0
      status = lstatus;
14256
0
  }
14257
14258
0
  *xpp = (void *)xp;
14259
0
  return status;
14260
0
#endif
14261
0
}
14262
14263
int
14264
ncx_putn_uint_float(void **xpp, size_t nelems, const float *tp, void *fillp)
14265
0
{
14266
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14267
14268
 /* basic algorithm is:
14269
  *   - ensure sane alignment of output data
14270
  *   - copy (conversion happens automatically) input data
14271
  *     to output
14272
  *   - update tp to point at next unconverted input, and xpp to point
14273
  *     at next location for converted output
14274
  */
14275
  long i, j, ni;
14276
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14277
  uint *xp;
14278
  int nrange = 0;         /* number of range errors */
14279
  int realign = 0;        /* "do we need to fix input data alignment?" */
14280
  long cxp = (long) *((char**)xpp);
14281
14282
  realign = (cxp & 7) % SIZEOF_UINT;
14283
  /* sjl: manually stripmine so we can limit amount of
14284
   * vector work space reserved to LOOPCNT elements. Also
14285
   * makes vectorisation easy */
14286
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14287
    ni=Min(nelems-j,LOOPCNT);
14288
    if (realign) {
14289
      xp = tmp;
14290
    } else {
14291
      xp = (uint *) *xpp;
14292
    }
14293
   /* copy the next block */
14294
#pragma cdir loopcnt=LOOPCNT
14295
#pragma cdir shortloop
14296
    for (i=0; i<ni; i++) {
14297
      /* the normal case: */
14298
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14299
     /* test for range errors (not always needed but do it anyway) */
14300
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14301
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14302
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14303
    }
14304
   /* copy workspace back if necessary */
14305
    if (realign) {
14306
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14307
      xp = (uint *) *xpp;
14308
    }
14309
   /* update xpp and tp */
14310
    xp += ni;
14311
    tp += ni;
14312
    *xpp = (void*)xp;
14313
  }
14314
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14315
14316
#else   /* not SX */
14317
14318
0
  char *xp = (char *) *xpp;
14319
0
  int status = NC_NOERR;
14320
14321
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14322
0
  {
14323
0
    int lstatus = ncx_put_uint_float(xp, tp, fillp);
14324
0
    if (status == NC_NOERR) /* report the first encountered error */
14325
0
      status = lstatus;
14326
0
  }
14327
14328
0
  *xpp = (void *)xp;
14329
0
  return status;
14330
0
#endif
14331
0
}
14332
14333
int
14334
ncx_putn_uint_double(void **xpp, size_t nelems, const double *tp, void *fillp)
14335
0
{
14336
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14337
14338
 /* basic algorithm is:
14339
  *   - ensure sane alignment of output data
14340
  *   - copy (conversion happens automatically) input data
14341
  *     to output
14342
  *   - update tp to point at next unconverted input, and xpp to point
14343
  *     at next location for converted output
14344
  */
14345
  long i, j, ni;
14346
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14347
  uint *xp;
14348
  int nrange = 0;         /* number of range errors */
14349
  int realign = 0;        /* "do we need to fix input data alignment?" */
14350
  long cxp = (long) *((char**)xpp);
14351
14352
  realign = (cxp & 7) % SIZEOF_UINT;
14353
  /* sjl: manually stripmine so we can limit amount of
14354
   * vector work space reserved to LOOPCNT elements. Also
14355
   * makes vectorisation easy */
14356
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14357
    ni=Min(nelems-j,LOOPCNT);
14358
    if (realign) {
14359
      xp = tmp;
14360
    } else {
14361
      xp = (uint *) *xpp;
14362
    }
14363
   /* copy the next block */
14364
#pragma cdir loopcnt=LOOPCNT
14365
#pragma cdir shortloop
14366
    for (i=0; i<ni; i++) {
14367
      /* the normal case: */
14368
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14369
     /* test for range errors (not always needed but do it anyway) */
14370
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14371
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14372
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14373
    }
14374
   /* copy workspace back if necessary */
14375
    if (realign) {
14376
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14377
      xp = (uint *) *xpp;
14378
    }
14379
   /* update xpp and tp */
14380
    xp += ni;
14381
    tp += ni;
14382
    *xpp = (void*)xp;
14383
  }
14384
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14385
14386
#else   /* not SX */
14387
14388
0
  char *xp = (char *) *xpp;
14389
0
  int status = NC_NOERR;
14390
14391
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14392
0
  {
14393
0
    int lstatus = ncx_put_uint_double(xp, tp, fillp);
14394
0
    if (status == NC_NOERR) /* report the first encountered error */
14395
0
      status = lstatus;
14396
0
  }
14397
14398
0
  *xpp = (void *)xp;
14399
0
  return status;
14400
0
#endif
14401
0
}
14402
14403
int
14404
ncx_putn_uint_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
14405
0
{
14406
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14407
14408
 /* basic algorithm is:
14409
  *   - ensure sane alignment of output data
14410
  *   - copy (conversion happens automatically) input data
14411
  *     to output
14412
  *   - update tp to point at next unconverted input, and xpp to point
14413
  *     at next location for converted output
14414
  */
14415
  long i, j, ni;
14416
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14417
  uint *xp;
14418
  int nrange = 0;         /* number of range errors */
14419
  int realign = 0;        /* "do we need to fix input data alignment?" */
14420
  long cxp = (long) *((char**)xpp);
14421
14422
  realign = (cxp & 7) % SIZEOF_UINT;
14423
  /* sjl: manually stripmine so we can limit amount of
14424
   * vector work space reserved to LOOPCNT elements. Also
14425
   * makes vectorisation easy */
14426
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14427
    ni=Min(nelems-j,LOOPCNT);
14428
    if (realign) {
14429
      xp = tmp;
14430
    } else {
14431
      xp = (uint *) *xpp;
14432
    }
14433
   /* copy the next block */
14434
#pragma cdir loopcnt=LOOPCNT
14435
#pragma cdir shortloop
14436
    for (i=0; i<ni; i++) {
14437
      /* the normal case: */
14438
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14439
     /* test for range errors (not always needed but do it anyway) */
14440
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14441
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14442
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14443
    }
14444
   /* copy workspace back if necessary */
14445
    if (realign) {
14446
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14447
      xp = (uint *) *xpp;
14448
    }
14449
   /* update xpp and tp */
14450
    xp += ni;
14451
    tp += ni;
14452
    *xpp = (void*)xp;
14453
  }
14454
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14455
14456
#else   /* not SX */
14457
14458
0
  char *xp = (char *) *xpp;
14459
0
  int status = NC_NOERR;
14460
14461
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14462
0
  {
14463
0
    int lstatus = ncx_put_uint_longlong(xp, tp, fillp);
14464
0
    if (status == NC_NOERR) /* report the first encountered error */
14465
0
      status = lstatus;
14466
0
  }
14467
14468
0
  *xpp = (void *)xp;
14469
0
  return status;
14470
0
#endif
14471
0
}
14472
14473
int
14474
ncx_putn_uint_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
14475
0
{
14476
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14477
14478
 /* basic algorithm is:
14479
  *   - ensure sane alignment of output data
14480
  *   - copy (conversion happens automatically) input data
14481
  *     to output
14482
  *   - update tp to point at next unconverted input, and xpp to point
14483
  *     at next location for converted output
14484
  */
14485
  long i, j, ni;
14486
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14487
  uint *xp;
14488
  int nrange = 0;         /* number of range errors */
14489
  int realign = 0;        /* "do we need to fix input data alignment?" */
14490
  long cxp = (long) *((char**)xpp);
14491
14492
  realign = (cxp & 7) % SIZEOF_UINT;
14493
  /* sjl: manually stripmine so we can limit amount of
14494
   * vector work space reserved to LOOPCNT elements. Also
14495
   * makes vectorisation easy */
14496
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14497
    ni=Min(nelems-j,LOOPCNT);
14498
    if (realign) {
14499
      xp = tmp;
14500
    } else {
14501
      xp = (uint *) *xpp;
14502
    }
14503
   /* copy the next block */
14504
#pragma cdir loopcnt=LOOPCNT
14505
#pragma cdir shortloop
14506
    for (i=0; i<ni; i++) {
14507
      /* the normal case: */
14508
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14509
     /* test for range errors (not always needed but do it anyway) */
14510
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14511
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14512
      nrange += tp[i] > X_UINT_MAX ;
14513
    }
14514
   /* copy workspace back if necessary */
14515
    if (realign) {
14516
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14517
      xp = (uint *) *xpp;
14518
    }
14519
   /* update xpp and tp */
14520
    xp += ni;
14521
    tp += ni;
14522
    *xpp = (void*)xp;
14523
  }
14524
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14525
14526
#else   /* not SX */
14527
14528
0
  char *xp = (char *) *xpp;
14529
0
  int status = NC_NOERR;
14530
14531
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14532
0
  {
14533
0
    int lstatus = ncx_put_uint_uchar(xp, tp, fillp);
14534
0
    if (status == NC_NOERR) /* report the first encountered error */
14535
0
      status = lstatus;
14536
0
  }
14537
14538
0
  *xpp = (void *)xp;
14539
0
  return status;
14540
0
#endif
14541
0
}
14542
14543
int
14544
ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
14545
0
{
14546
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14547
14548
 /* basic algorithm is:
14549
  *   - ensure sane alignment of output data
14550
  *   - copy (conversion happens automatically) input data
14551
  *     to output
14552
  *   - update tp to point at next unconverted input, and xpp to point
14553
  *     at next location for converted output
14554
  */
14555
  long i, j, ni;
14556
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14557
  uint *xp;
14558
  int nrange = 0;         /* number of range errors */
14559
  int realign = 0;        /* "do we need to fix input data alignment?" */
14560
  long cxp = (long) *((char**)xpp);
14561
14562
  realign = (cxp & 7) % SIZEOF_UINT;
14563
  /* sjl: manually stripmine so we can limit amount of
14564
   * vector work space reserved to LOOPCNT elements. Also
14565
   * makes vectorisation easy */
14566
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14567
    ni=Min(nelems-j,LOOPCNT);
14568
    if (realign) {
14569
      xp = tmp;
14570
    } else {
14571
      xp = (uint *) *xpp;
14572
    }
14573
   /* copy the next block */
14574
#pragma cdir loopcnt=LOOPCNT
14575
#pragma cdir shortloop
14576
    for (i=0; i<ni; i++) {
14577
      /* the normal case: */
14578
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14579
     /* test for range errors (not always needed but do it anyway) */
14580
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14581
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14582
      nrange += tp[i] > X_UINT_MAX ;
14583
    }
14584
   /* copy workspace back if necessary */
14585
    if (realign) {
14586
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14587
      xp = (uint *) *xpp;
14588
    }
14589
   /* update xpp and tp */
14590
    xp += ni;
14591
    tp += ni;
14592
    *xpp = (void*)xp;
14593
  }
14594
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14595
14596
#else   /* not SX */
14597
14598
0
  char *xp = (char *) *xpp;
14599
0
  int status = NC_NOERR;
14600
14601
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14602
0
  {
14603
0
    int lstatus = ncx_put_uint_ushort(xp, tp, fillp);
14604
0
    if (status == NC_NOERR) /* report the first encountered error */
14605
0
      status = lstatus;
14606
0
  }
14607
14608
0
  *xpp = (void *)xp;
14609
0
  return status;
14610
0
#endif
14611
0
}
14612
14613
int
14614
ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
14615
0
{
14616
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14617
14618
 /* basic algorithm is:
14619
  *   - ensure sane alignment of output data
14620
  *   - copy (conversion happens automatically) input data
14621
  *     to output
14622
  *   - update tp to point at next unconverted input, and xpp to point
14623
  *     at next location for converted output
14624
  */
14625
  long i, j, ni;
14626
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14627
  uint *xp;
14628
  int nrange = 0;         /* number of range errors */
14629
  int realign = 0;        /* "do we need to fix input data alignment?" */
14630
  long cxp = (long) *((char**)xpp);
14631
14632
  realign = (cxp & 7) % SIZEOF_UINT;
14633
  /* sjl: manually stripmine so we can limit amount of
14634
   * vector work space reserved to LOOPCNT elements. Also
14635
   * makes vectorisation easy */
14636
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14637
    ni=Min(nelems-j,LOOPCNT);
14638
    if (realign) {
14639
      xp = tmp;
14640
    } else {
14641
      xp = (uint *) *xpp;
14642
    }
14643
   /* copy the next block */
14644
#pragma cdir loopcnt=LOOPCNT
14645
#pragma cdir shortloop
14646
    for (i=0; i<ni; i++) {
14647
      /* the normal case: */
14648
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14649
     /* test for range errors (not always needed but do it anyway) */
14650
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14651
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14652
      nrange += tp[i] > X_UINT_MAX ;
14653
    }
14654
   /* copy workspace back if necessary */
14655
    if (realign) {
14656
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14657
      xp = (uint *) *xpp;
14658
    }
14659
   /* update xpp and tp */
14660
    xp += ni;
14661
    tp += ni;
14662
    *xpp = (void*)xp;
14663
  }
14664
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14665
14666
#else   /* not SX */
14667
14668
0
  char *xp = (char *) *xpp;
14669
0
  int status = NC_NOERR;
14670
14671
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14672
0
  {
14673
0
    int lstatus = ncx_put_uint_ulonglong(xp, tp, fillp);
14674
0
    if (status == NC_NOERR) /* report the first encountered error */
14675
0
      status = lstatus;
14676
0
  }
14677
14678
0
  *xpp = (void *)xp;
14679
0
  return status;
14680
0
#endif
14681
0
}
14682
14683
14684
14685
/* float ---------------------------------------------------------------------*/
14686
14687
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
14688
/* optimized version */
14689
int
14690
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14691
0
{
14692
#ifdef WORDS_BIGENDIAN
14693
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
14694
# else
14695
0
  swapn4b(tp, *xpp, nelems);
14696
0
# endif
14697
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
14698
0
  return NC_NOERR;
14699
0
}
14700
#elif defined(vax) && vax != 0
14701
int
14702
ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
14703
{
14704
  float *const end = ip + nfloats;
14705
14706
  while (ip < end)
14707
  {
14708
    struct vax_single *const vsp = (struct vax_single *) ip;
14709
    const struct ieee_single *const isp =
14710
       (const struct ieee_single *) (*xpp);
14711
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
14712
14713
    switch(exp) {
14714
    case 0 :
14715
      /* ieee subnormal */
14716
      if (isp->mant_hi == min.ieee.mant_hi
14717
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
14718
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
14719
      {
14720
        *vsp = min.s;
14721
      }
14722
      else
14723
      {
14724
        unsigned mantissa = (isp->mant_hi << 16)
14725
           | isp->mant_lo_hi << 8
14726
           | isp->mant_lo_lo;
14727
        unsigned tmp = mantissa >> 20;
14728
        if (tmp >= 4) {
14729
          vsp->exp = 2;
14730
        } else if (tmp >= 2) {
14731
          vsp->exp = 1;
14732
        } else {
14733
          *vsp = min.s;
14734
          break;
14735
        } /* else */
14736
        tmp = mantissa - (1 << (20 + vsp->exp ));
14737
        tmp <<= 3 - vsp->exp;
14738
        vsp->mantissa2 = tmp;
14739
        vsp->mantissa1 = (tmp >> 16);
14740
      }
14741
      break;
14742
    case 0xfe :
14743
    case 0xff :
14744
      *vsp = max.s;
14745
      break;
14746
    default :
14747
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
14748
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
14749
      vsp->mantissa1 = isp->mant_hi;
14750
    }
14751
14752
    vsp->sign = isp->sign;
14753
14754
14755
    ip++;
14756
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
14757
  }
14758
  return NC_NOERR;
14759
}
14760
#else
14761
int
14762
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14763
{
14764
  const char *xp = *xpp;
14765
  int status = NC_NOERR;
14766
14767
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14768
  {
14769
    const int lstatus = ncx_get_float_float(xp, tp, fillp);
14770
    if (status == NC_NOERR) /* report the first encountered error */
14771
      status = lstatus;
14772
  }
14773
14774
  *xpp = (const void *)xp;
14775
  return status;
14776
}
14777
14778
#endif
14779
int
14780
ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
14781
0
{
14782
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14783
14784
 /* basic algorithm is:
14785
  *   - ensure sane alignment of input data
14786
  *   - copy (conversion happens automatically) input data
14787
  *     to output
14788
  *   - update xpp to point at next unconverted input, and tp to point
14789
  *     at next location for converted output
14790
  */
14791
  long i, j, ni;
14792
  float tmp[LOOPCNT];        /* in case input is misaligned */
14793
  float *xp;
14794
  int nrange = 0;         /* number of range errors */
14795
  int realign = 0;        /* "do we need to fix input data alignment?" */
14796
  long cxp = (long) *((char**)xpp);
14797
14798
  realign = (cxp & 7) % SIZEOF_FLOAT;
14799
  /* sjl: manually stripmine so we can limit amount of
14800
   * vector work space reserved to LOOPCNT elements. Also
14801
   * makes vectorisation easy */
14802
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14803
    ni=Min(nelems-j,LOOPCNT);
14804
    if (realign) {
14805
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14806
      xp = tmp;
14807
    } else {
14808
      xp = (float *) *xpp;
14809
    }
14810
   /* copy the next block */
14811
#pragma cdir loopcnt=LOOPCNT
14812
#pragma cdir shortloop
14813
    for (i=0; i<ni; i++) {
14814
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
14815
     /* test for range errors (not always needed but do it anyway) */
14816
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14817
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14818
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
14819
    }
14820
   /* update xpp and tp */
14821
    if (realign) xp = (float *) *xpp;
14822
    xp += ni;
14823
    tp += ni;
14824
    *xpp = (void*)xp;
14825
  }
14826
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14827
14828
#else   /* not SX */
14829
0
  const char *xp = (const char *) *xpp;
14830
0
  int status = NC_NOERR;
14831
14832
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14833
0
  {
14834
0
    const int lstatus = ncx_get_float_schar(xp, tp);
14835
0
    if (status == NC_NOERR) /* report the first encountered error */
14836
0
      status = lstatus;
14837
0
  }
14838
14839
0
  *xpp = (const void *)xp;
14840
0
  return status;
14841
0
#endif
14842
0
}
14843
14844
int
14845
ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
14846
0
{
14847
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14848
14849
 /* basic algorithm is:
14850
  *   - ensure sane alignment of input data
14851
  *   - copy (conversion happens automatically) input data
14852
  *     to output
14853
  *   - update xpp to point at next unconverted input, and tp to point
14854
  *     at next location for converted output
14855
  */
14856
  long i, j, ni;
14857
  float tmp[LOOPCNT];        /* in case input is misaligned */
14858
  float *xp;
14859
  int nrange = 0;         /* number of range errors */
14860
  int realign = 0;        /* "do we need to fix input data alignment?" */
14861
  long cxp = (long) *((char**)xpp);
14862
14863
  realign = (cxp & 7) % SIZEOF_FLOAT;
14864
  /* sjl: manually stripmine so we can limit amount of
14865
   * vector work space reserved to LOOPCNT elements. Also
14866
   * makes vectorisation easy */
14867
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14868
    ni=Min(nelems-j,LOOPCNT);
14869
    if (realign) {
14870
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14871
      xp = tmp;
14872
    } else {
14873
      xp = (float *) *xpp;
14874
    }
14875
   /* copy the next block */
14876
#pragma cdir loopcnt=LOOPCNT
14877
#pragma cdir shortloop
14878
    for (i=0; i<ni; i++) {
14879
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
14880
     /* test for range errors (not always needed but do it anyway) */
14881
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14882
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14883
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
14884
    }
14885
   /* update xpp and tp */
14886
    if (realign) xp = (float *) *xpp;
14887
    xp += ni;
14888
    tp += ni;
14889
    *xpp = (void*)xp;
14890
  }
14891
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14892
14893
#else   /* not SX */
14894
0
  const char *xp = (const char *) *xpp;
14895
0
  int status = NC_NOERR;
14896
14897
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14898
0
  {
14899
0
    const int lstatus = ncx_get_float_short(xp, tp);
14900
0
    if (status == NC_NOERR) /* report the first encountered error */
14901
0
      status = lstatus;
14902
0
  }
14903
14904
0
  *xpp = (const void *)xp;
14905
0
  return status;
14906
0
#endif
14907
0
}
14908
14909
int
14910
ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
14911
0
{
14912
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14913
14914
 /* basic algorithm is:
14915
  *   - ensure sane alignment of input data
14916
  *   - copy (conversion happens automatically) input data
14917
  *     to output
14918
  *   - update xpp to point at next unconverted input, and tp to point
14919
  *     at next location for converted output
14920
  */
14921
  long i, j, ni;
14922
  float tmp[LOOPCNT];        /* in case input is misaligned */
14923
  float *xp;
14924
  int nrange = 0;         /* number of range errors */
14925
  int realign = 0;        /* "do we need to fix input data alignment?" */
14926
  long cxp = (long) *((char**)xpp);
14927
14928
  realign = (cxp & 7) % SIZEOF_FLOAT;
14929
  /* sjl: manually stripmine so we can limit amount of
14930
   * vector work space reserved to LOOPCNT elements. Also
14931
   * makes vectorisation easy */
14932
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14933
    ni=Min(nelems-j,LOOPCNT);
14934
    if (realign) {
14935
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14936
      xp = tmp;
14937
    } else {
14938
      xp = (float *) *xpp;
14939
    }
14940
   /* copy the next block */
14941
#pragma cdir loopcnt=LOOPCNT
14942
#pragma cdir shortloop
14943
    for (i=0; i<ni; i++) {
14944
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
14945
     /* test for range errors (not always needed but do it anyway) */
14946
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14947
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14948
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
14949
    }
14950
   /* update xpp and tp */
14951
    if (realign) xp = (float *) *xpp;
14952
    xp += ni;
14953
    tp += ni;
14954
    *xpp = (void*)xp;
14955
  }
14956
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14957
14958
#else   /* not SX */
14959
0
  const char *xp = (const char *) *xpp;
14960
0
  int status = NC_NOERR;
14961
14962
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14963
0
  {
14964
0
    const int lstatus = ncx_get_float_int(xp, tp);
14965
0
    if (status == NC_NOERR) /* report the first encountered error */
14966
0
      status = lstatus;
14967
0
  }
14968
14969
0
  *xpp = (const void *)xp;
14970
0
  return status;
14971
0
#endif
14972
0
}
14973
14974
int
14975
ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
14976
0
{
14977
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14978
14979
 /* basic algorithm is:
14980
  *   - ensure sane alignment of input data
14981
  *   - copy (conversion happens automatically) input data
14982
  *     to output
14983
  *   - update xpp to point at next unconverted input, and tp to point
14984
  *     at next location for converted output
14985
  */
14986
  long i, j, ni;
14987
  float tmp[LOOPCNT];        /* in case input is misaligned */
14988
  float *xp;
14989
  int nrange = 0;         /* number of range errors */
14990
  int realign = 0;        /* "do we need to fix input data alignment?" */
14991
  long cxp = (long) *((char**)xpp);
14992
14993
  realign = (cxp & 7) % SIZEOF_FLOAT;
14994
  /* sjl: manually stripmine so we can limit amount of
14995
   * vector work space reserved to LOOPCNT elements. Also
14996
   * makes vectorisation easy */
14997
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14998
    ni=Min(nelems-j,LOOPCNT);
14999
    if (realign) {
15000
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15001
      xp = tmp;
15002
    } else {
15003
      xp = (float *) *xpp;
15004
    }
15005
   /* copy the next block */
15006
#pragma cdir loopcnt=LOOPCNT
15007
#pragma cdir shortloop
15008
    for (i=0; i<ni; i++) {
15009
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
15010
     /* test for range errors (not always needed but do it anyway) */
15011
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15012
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15013
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
15014
    }
15015
   /* update xpp and tp */
15016
    if (realign) xp = (float *) *xpp;
15017
    xp += ni;
15018
    tp += ni;
15019
    *xpp = (void*)xp;
15020
  }
15021
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15022
15023
#else   /* not SX */
15024
0
  const char *xp = (const char *) *xpp;
15025
0
  int status = NC_NOERR;
15026
15027
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15028
0
  {
15029
0
    const int lstatus = ncx_get_float_long(xp, tp);
15030
0
    if (status == NC_NOERR) /* report the first encountered error */
15031
0
      status = lstatus;
15032
0
  }
15033
15034
0
  *xpp = (const void *)xp;
15035
0
  return status;
15036
0
#endif
15037
0
}
15038
15039
int
15040
ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
15041
0
{
15042
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15043
15044
 /* basic algorithm is:
15045
  *   - ensure sane alignment of input data
15046
  *   - copy (conversion happens automatically) input data
15047
  *     to output
15048
  *   - update xpp to point at next unconverted input, and tp to point
15049
  *     at next location for converted output
15050
  */
15051
  long i, j, ni;
15052
  float tmp[LOOPCNT];        /* in case input is misaligned */
15053
  float *xp;
15054
  int nrange = 0;         /* number of range errors */
15055
  int realign = 0;        /* "do we need to fix input data alignment?" */
15056
  long cxp = (long) *((char**)xpp);
15057
15058
  realign = (cxp & 7) % SIZEOF_FLOAT;
15059
  /* sjl: manually stripmine so we can limit amount of
15060
   * vector work space reserved to LOOPCNT elements. Also
15061
   * makes vectorisation easy */
15062
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15063
    ni=Min(nelems-j,LOOPCNT);
15064
    if (realign) {
15065
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15066
      xp = tmp;
15067
    } else {
15068
      xp = (float *) *xpp;
15069
    }
15070
   /* copy the next block */
15071
#pragma cdir loopcnt=LOOPCNT
15072
#pragma cdir shortloop
15073
    for (i=0; i<ni; i++) {
15074
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
15075
     /* test for range errors (not always needed but do it anyway) */
15076
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15077
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15078
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
15079
    }
15080
   /* update xpp and tp */
15081
    if (realign) xp = (float *) *xpp;
15082
    xp += ni;
15083
    tp += ni;
15084
    *xpp = (void*)xp;
15085
  }
15086
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15087
15088
#else   /* not SX */
15089
0
  const char *xp = (const char *) *xpp;
15090
0
  int status = NC_NOERR;
15091
15092
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15093
0
  {
15094
0
    const int lstatus = ncx_get_float_double(xp, tp);
15095
0
    if (status == NC_NOERR) /* report the first encountered error */
15096
0
      status = lstatus;
15097
0
  }
15098
15099
0
  *xpp = (const void *)xp;
15100
0
  return status;
15101
0
#endif
15102
0
}
15103
15104
int
15105
ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp)
15106
0
{
15107
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15108
15109
 /* basic algorithm is:
15110
  *   - ensure sane alignment of input data
15111
  *   - copy (conversion happens automatically) input data
15112
  *     to output
15113
  *   - update xpp to point at next unconverted input, and tp to point
15114
  *     at next location for converted output
15115
  */
15116
  long i, j, ni;
15117
  float tmp[LOOPCNT];        /* in case input is misaligned */
15118
  float *xp;
15119
  int nrange = 0;         /* number of range errors */
15120
  int realign = 0;        /* "do we need to fix input data alignment?" */
15121
  long cxp = (long) *((char**)xpp);
15122
15123
  realign = (cxp & 7) % SIZEOF_FLOAT;
15124
  /* sjl: manually stripmine so we can limit amount of
15125
   * vector work space reserved to LOOPCNT elements. Also
15126
   * makes vectorisation easy */
15127
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15128
    ni=Min(nelems-j,LOOPCNT);
15129
    if (realign) {
15130
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15131
      xp = tmp;
15132
    } else {
15133
      xp = (float *) *xpp;
15134
    }
15135
   /* copy the next block */
15136
#pragma cdir loopcnt=LOOPCNT
15137
#pragma cdir shortloop
15138
    for (i=0; i<ni; i++) {
15139
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
15140
     /* test for range errors (not always needed but do it anyway) */
15141
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15142
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15143
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
15144
    }
15145
   /* update xpp and tp */
15146
    if (realign) xp = (float *) *xpp;
15147
    xp += ni;
15148
    tp += ni;
15149
    *xpp = (void*)xp;
15150
  }
15151
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15152
15153
#else   /* not SX */
15154
0
  const char *xp = (const char *) *xpp;
15155
0
  int status = NC_NOERR;
15156
15157
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15158
0
  {
15159
0
    const int lstatus = ncx_get_float_longlong(xp, tp);
15160
0
    if (status == NC_NOERR) /* report the first encountered error */
15161
0
      status = lstatus;
15162
0
  }
15163
15164
0
  *xpp = (const void *)xp;
15165
0
  return status;
15166
0
#endif
15167
0
}
15168
15169
int
15170
ncx_getn_float_ushort(const void **xpp, size_t nelems, ushort *tp)
15171
0
{
15172
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15173
15174
 /* basic algorithm is:
15175
  *   - ensure sane alignment of input data
15176
  *   - copy (conversion happens automatically) input data
15177
  *     to output
15178
  *   - update xpp to point at next unconverted input, and tp to point
15179
  *     at next location for converted output
15180
  */
15181
  long i, j, ni;
15182
  float tmp[LOOPCNT];        /* in case input is misaligned */
15183
  float *xp;
15184
  int nrange = 0;         /* number of range errors */
15185
  int realign = 0;        /* "do we need to fix input data alignment?" */
15186
  long cxp = (long) *((char**)xpp);
15187
15188
  realign = (cxp & 7) % SIZEOF_FLOAT;
15189
  /* sjl: manually stripmine so we can limit amount of
15190
   * vector work space reserved to LOOPCNT elements. Also
15191
   * makes vectorisation easy */
15192
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15193
    ni=Min(nelems-j,LOOPCNT);
15194
    if (realign) {
15195
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15196
      xp = tmp;
15197
    } else {
15198
      xp = (float *) *xpp;
15199
    }
15200
   /* copy the next block */
15201
#pragma cdir loopcnt=LOOPCNT
15202
#pragma cdir shortloop
15203
    for (i=0; i<ni; i++) {
15204
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
15205
     /* test for range errors (not always needed but do it anyway) */
15206
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15207
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15208
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
15209
    }
15210
   /* update xpp and tp */
15211
    if (realign) xp = (float *) *xpp;
15212
    xp += ni;
15213
    tp += ni;
15214
    *xpp = (void*)xp;
15215
  }
15216
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15217
15218
#else   /* not SX */
15219
0
  const char *xp = (const char *) *xpp;
15220
0
  int status = NC_NOERR;
15221
15222
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15223
0
  {
15224
0
    const int lstatus = ncx_get_float_ushort(xp, tp);
15225
0
    if (status == NC_NOERR) /* report the first encountered error */
15226
0
      status = lstatus;
15227
0
  }
15228
15229
0
  *xpp = (const void *)xp;
15230
0
  return status;
15231
0
#endif
15232
0
}
15233
15234
int
15235
ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
15236
0
{
15237
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15238
15239
 /* basic algorithm is:
15240
  *   - ensure sane alignment of input data
15241
  *   - copy (conversion happens automatically) input data
15242
  *     to output
15243
  *   - update xpp to point at next unconverted input, and tp to point
15244
  *     at next location for converted output
15245
  */
15246
  long i, j, ni;
15247
  float tmp[LOOPCNT];        /* in case input is misaligned */
15248
  float *xp;
15249
  int nrange = 0;         /* number of range errors */
15250
  int realign = 0;        /* "do we need to fix input data alignment?" */
15251
  long cxp = (long) *((char**)xpp);
15252
15253
  realign = (cxp & 7) % SIZEOF_FLOAT;
15254
  /* sjl: manually stripmine so we can limit amount of
15255
   * vector work space reserved to LOOPCNT elements. Also
15256
   * makes vectorisation easy */
15257
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15258
    ni=Min(nelems-j,LOOPCNT);
15259
    if (realign) {
15260
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15261
      xp = tmp;
15262
    } else {
15263
      xp = (float *) *xpp;
15264
    }
15265
   /* copy the next block */
15266
#pragma cdir loopcnt=LOOPCNT
15267
#pragma cdir shortloop
15268
    for (i=0; i<ni; i++) {
15269
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
15270
     /* test for range errors (not always needed but do it anyway) */
15271
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15272
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15273
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
15274
    }
15275
   /* update xpp and tp */
15276
    if (realign) xp = (float *) *xpp;
15277
    xp += ni;
15278
    tp += ni;
15279
    *xpp = (void*)xp;
15280
  }
15281
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15282
15283
#else   /* not SX */
15284
0
  const char *xp = (const char *) *xpp;
15285
0
  int status = NC_NOERR;
15286
15287
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15288
0
  {
15289
0
    const int lstatus = ncx_get_float_uchar(xp, tp);
15290
0
    if (status == NC_NOERR) /* report the first encountered error */
15291
0
      status = lstatus;
15292
0
  }
15293
15294
0
  *xpp = (const void *)xp;
15295
0
  return status;
15296
0
#endif
15297
0
}
15298
15299
int
15300
ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp)
15301
0
{
15302
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15303
15304
 /* basic algorithm is:
15305
  *   - ensure sane alignment of input data
15306
  *   - copy (conversion happens automatically) input data
15307
  *     to output
15308
  *   - update xpp to point at next unconverted input, and tp to point
15309
  *     at next location for converted output
15310
  */
15311
  long i, j, ni;
15312
  float tmp[LOOPCNT];        /* in case input is misaligned */
15313
  float *xp;
15314
  int nrange = 0;         /* number of range errors */
15315
  int realign = 0;        /* "do we need to fix input data alignment?" */
15316
  long cxp = (long) *((char**)xpp);
15317
15318
  realign = (cxp & 7) % SIZEOF_FLOAT;
15319
  /* sjl: manually stripmine so we can limit amount of
15320
   * vector work space reserved to LOOPCNT elements. Also
15321
   * makes vectorisation easy */
15322
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15323
    ni=Min(nelems-j,LOOPCNT);
15324
    if (realign) {
15325
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15326
      xp = tmp;
15327
    } else {
15328
      xp = (float *) *xpp;
15329
    }
15330
   /* copy the next block */
15331
#pragma cdir loopcnt=LOOPCNT
15332
#pragma cdir shortloop
15333
    for (i=0; i<ni; i++) {
15334
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
15335
     /* test for range errors (not always needed but do it anyway) */
15336
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15337
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15338
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
15339
    }
15340
   /* update xpp and tp */
15341
    if (realign) xp = (float *) *xpp;
15342
    xp += ni;
15343
    tp += ni;
15344
    *xpp = (void*)xp;
15345
  }
15346
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15347
15348
#else   /* not SX */
15349
0
  const char *xp = (const char *) *xpp;
15350
0
  int status = NC_NOERR;
15351
15352
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15353
0
  {
15354
0
    const int lstatus = ncx_get_float_uint(xp, tp);
15355
0
    if (status == NC_NOERR) /* report the first encountered error */
15356
0
      status = lstatus;
15357
0
  }
15358
15359
0
  *xpp = (const void *)xp;
15360
0
  return status;
15361
0
#endif
15362
0
}
15363
15364
int
15365
ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
15366
0
{
15367
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15368
15369
 /* basic algorithm is:
15370
  *   - ensure sane alignment of input data
15371
  *   - copy (conversion happens automatically) input data
15372
  *     to output
15373
  *   - update xpp to point at next unconverted input, and tp to point
15374
  *     at next location for converted output
15375
  */
15376
  long i, j, ni;
15377
  float tmp[LOOPCNT];        /* in case input is misaligned */
15378
  float *xp;
15379
  int nrange = 0;         /* number of range errors */
15380
  int realign = 0;        /* "do we need to fix input data alignment?" */
15381
  long cxp = (long) *((char**)xpp);
15382
15383
  realign = (cxp & 7) % SIZEOF_FLOAT;
15384
  /* sjl: manually stripmine so we can limit amount of
15385
   * vector work space reserved to LOOPCNT elements. Also
15386
   * makes vectorisation easy */
15387
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15388
    ni=Min(nelems-j,LOOPCNT);
15389
    if (realign) {
15390
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15391
      xp = tmp;
15392
    } else {
15393
      xp = (float *) *xpp;
15394
    }
15395
   /* copy the next block */
15396
#pragma cdir loopcnt=LOOPCNT
15397
#pragma cdir shortloop
15398
    for (i=0; i<ni; i++) {
15399
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
15400
     /* test for range errors (not always needed but do it anyway) */
15401
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15402
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15403
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
15404
    }
15405
   /* update xpp and tp */
15406
    if (realign) xp = (float *) *xpp;
15407
    xp += ni;
15408
    tp += ni;
15409
    *xpp = (void*)xp;
15410
  }
15411
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15412
15413
#else   /* not SX */
15414
0
  const char *xp = (const char *) *xpp;
15415
0
  int status = NC_NOERR;
15416
15417
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15418
0
  {
15419
0
    const int lstatus = ncx_get_float_ulonglong(xp, tp);
15420
0
    if (status == NC_NOERR) /* report the first encountered error */
15421
0
      status = lstatus;
15422
0
  }
15423
15424
0
  *xpp = (const void *)xp;
15425
0
  return status;
15426
0
#endif
15427
0
}
15428
15429
15430
int
15431
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
15432
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
15433
/* optimized version */
15434
0
{
15435
#ifdef WORDS_BIGENDIAN
15436
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
15437
# else
15438
0
  swapn4b(*xpp, tp, nelems);
15439
0
# endif
15440
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
15441
0
  return NC_NOERR;
15442
0
}
15443
#elif defined(vax) && vax != 0
15444
{
15445
  const float *const end = tp + nelems;
15446
15447
  while (tp < end) {
15448
        const struct vax_single *const vsp =
15449
       (const struct vax_single *)ip;
15450
    struct ieee_single *const isp = (struct ieee_single *) (*xpp);
15451
15452
    switch(vsp->exp){
15453
    case 0 :
15454
      /* all vax float with zero exponent map to zero */
15455
      *isp = min.ieee;
15456
      break;
15457
    case 2 :
15458
    case 1 :
15459
    {
15460
      /* These will map to subnormals */
15461
      unsigned mantissa = (vsp->mantissa1 << 16)
15462
           | vsp->mantissa2;
15463
      mantissa >>= 3 - vsp->exp;
15464
      mantissa += (1 << (20 + vsp->exp));
15465
      isp->mant_lo_lo = mantissa;
15466
      isp->mant_lo_hi = mantissa >> 8;
15467
      isp->mant_hi = mantissa >> 16;
15468
      isp->exp_lo = 0;
15469
      isp->exp_hi = 0;
15470
    }
15471
      break;
15472
    case 0xff : /* max.s.exp */
15473
      if (vsp->mantissa2 == max.s.mantissa2 &&
15474
          vsp->mantissa1 == max.s.mantissa1)
15475
      {
15476
        /* map largest vax float to ieee infinity */
15477
        *isp = max.ieee;
15478
        break;
15479
      } /* else, fall thru */
15480
    default :
15481
    {
15482
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
15483
      isp->exp_hi = exp >> 1;
15484
      isp->exp_lo = exp;
15485
      isp->mant_lo_lo = vsp->mantissa2;
15486
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
15487
      isp->mant_hi = vsp->mantissa1;
15488
    }
15489
    }
15490
15491
    isp->sign = vsp->sign;
15492
15493
    tp++;
15494
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
15495
  }
15496
  return NC_NOERR;
15497
}
15498
#else
15499
{
15500
  char *xp = *xpp;
15501
  int status = NC_NOERR;
15502
15503
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
15504
    int lstatus = ncx_put_float_float(xp, tp, fillp);
15505
    if (status == NC_NOERR) /* report the first encountered error */
15506
      status = lstatus;
15507
  }
15508
15509
  *xpp = (void *)xp;
15510
  return status;
15511
}
15512
#endif
15513
int
15514
ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
15515
0
{
15516
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15517
15518
 /* basic algorithm is:
15519
  *   - ensure sane alignment of output data
15520
  *   - copy (conversion happens automatically) input data
15521
  *     to output
15522
  *   - update tp to point at next unconverted input, and xpp to point
15523
  *     at next location for converted output
15524
  */
15525
  long i, j, ni;
15526
  float tmp[LOOPCNT];        /* in case input is misaligned */
15527
  float *xp;
15528
  int nrange = 0;         /* number of range errors */
15529
  int realign = 0;        /* "do we need to fix input data alignment?" */
15530
  long cxp = (long) *((char**)xpp);
15531
15532
  realign = (cxp & 7) % SIZEOF_FLOAT;
15533
  /* sjl: manually stripmine so we can limit amount of
15534
   * vector work space reserved to LOOPCNT elements. Also
15535
   * makes vectorisation easy */
15536
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15537
    ni=Min(nelems-j,LOOPCNT);
15538
    if (realign) {
15539
      xp = tmp;
15540
    } else {
15541
      xp = (float *) *xpp;
15542
    }
15543
   /* copy the next block */
15544
#pragma cdir loopcnt=LOOPCNT
15545
#pragma cdir shortloop
15546
    for (i=0; i<ni; i++) {
15547
      /* the normal case: */
15548
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15549
     /* test for range errors (not always needed but do it anyway) */
15550
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15551
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15552
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15553
    }
15554
   /* copy workspace back if necessary */
15555
    if (realign) {
15556
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15557
      xp = (float *) *xpp;
15558
    }
15559
   /* update xpp and tp */
15560
    xp += ni;
15561
    tp += ni;
15562
    *xpp = (void*)xp;
15563
  }
15564
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15565
15566
#else   /* not SX */
15567
15568
0
  char *xp = (char *) *xpp;
15569
0
  int status = NC_NOERR;
15570
15571
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15572
0
  {
15573
0
    int lstatus = ncx_put_float_schar(xp, tp, fillp);
15574
0
    if (status == NC_NOERR) /* report the first encountered error */
15575
0
      status = lstatus;
15576
0
  }
15577
15578
0
  *xpp = (void *)xp;
15579
0
  return status;
15580
0
#endif
15581
0
}
15582
15583
int
15584
ncx_putn_float_short(void **xpp, size_t nelems, const short *tp, void *fillp)
15585
0
{
15586
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15587
15588
 /* basic algorithm is:
15589
  *   - ensure sane alignment of output data
15590
  *   - copy (conversion happens automatically) input data
15591
  *     to output
15592
  *   - update tp to point at next unconverted input, and xpp to point
15593
  *     at next location for converted output
15594
  */
15595
  long i, j, ni;
15596
  float tmp[LOOPCNT];        /* in case input is misaligned */
15597
  float *xp;
15598
  int nrange = 0;         /* number of range errors */
15599
  int realign = 0;        /* "do we need to fix input data alignment?" */
15600
  long cxp = (long) *((char**)xpp);
15601
15602
  realign = (cxp & 7) % SIZEOF_FLOAT;
15603
  /* sjl: manually stripmine so we can limit amount of
15604
   * vector work space reserved to LOOPCNT elements. Also
15605
   * makes vectorisation easy */
15606
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15607
    ni=Min(nelems-j,LOOPCNT);
15608
    if (realign) {
15609
      xp = tmp;
15610
    } else {
15611
      xp = (float *) *xpp;
15612
    }
15613
   /* copy the next block */
15614
#pragma cdir loopcnt=LOOPCNT
15615
#pragma cdir shortloop
15616
    for (i=0; i<ni; i++) {
15617
      /* the normal case: */
15618
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15619
     /* test for range errors (not always needed but do it anyway) */
15620
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15621
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15622
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15623
    }
15624
   /* copy workspace back if necessary */
15625
    if (realign) {
15626
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15627
      xp = (float *) *xpp;
15628
    }
15629
   /* update xpp and tp */
15630
    xp += ni;
15631
    tp += ni;
15632
    *xpp = (void*)xp;
15633
  }
15634
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15635
15636
#else   /* not SX */
15637
15638
0
  char *xp = (char *) *xpp;
15639
0
  int status = NC_NOERR;
15640
15641
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15642
0
  {
15643
0
    int lstatus = ncx_put_float_short(xp, tp, fillp);
15644
0
    if (status == NC_NOERR) /* report the first encountered error */
15645
0
      status = lstatus;
15646
0
  }
15647
15648
0
  *xpp = (void *)xp;
15649
0
  return status;
15650
0
#endif
15651
0
}
15652
15653
int
15654
ncx_putn_float_int(void **xpp, size_t nelems, const int *tp, void *fillp)
15655
0
{
15656
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15657
15658
 /* basic algorithm is:
15659
  *   - ensure sane alignment of output data
15660
  *   - copy (conversion happens automatically) input data
15661
  *     to output
15662
  *   - update tp to point at next unconverted input, and xpp to point
15663
  *     at next location for converted output
15664
  */
15665
  long i, j, ni;
15666
  float tmp[LOOPCNT];        /* in case input is misaligned */
15667
  float *xp;
15668
  int nrange = 0;         /* number of range errors */
15669
  int realign = 0;        /* "do we need to fix input data alignment?" */
15670
  long cxp = (long) *((char**)xpp);
15671
15672
  realign = (cxp & 7) % SIZEOF_FLOAT;
15673
  /* sjl: manually stripmine so we can limit amount of
15674
   * vector work space reserved to LOOPCNT elements. Also
15675
   * makes vectorisation easy */
15676
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15677
    ni=Min(nelems-j,LOOPCNT);
15678
    if (realign) {
15679
      xp = tmp;
15680
    } else {
15681
      xp = (float *) *xpp;
15682
    }
15683
   /* copy the next block */
15684
#pragma cdir loopcnt=LOOPCNT
15685
#pragma cdir shortloop
15686
    for (i=0; i<ni; i++) {
15687
      /* the normal case: */
15688
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15689
     /* test for range errors (not always needed but do it anyway) */
15690
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15691
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15692
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15693
    }
15694
   /* copy workspace back if necessary */
15695
    if (realign) {
15696
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15697
      xp = (float *) *xpp;
15698
    }
15699
   /* update xpp and tp */
15700
    xp += ni;
15701
    tp += ni;
15702
    *xpp = (void*)xp;
15703
  }
15704
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15705
15706
#else   /* not SX */
15707
15708
0
  char *xp = (char *) *xpp;
15709
0
  int status = NC_NOERR;
15710
15711
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15712
0
  {
15713
0
    int lstatus = ncx_put_float_int(xp, tp, fillp);
15714
0
    if (status == NC_NOERR) /* report the first encountered error */
15715
0
      status = lstatus;
15716
0
  }
15717
15718
0
  *xpp = (void *)xp;
15719
0
  return status;
15720
0
#endif
15721
0
}
15722
15723
int
15724
ncx_putn_float_long(void **xpp, size_t nelems, const long *tp, void *fillp)
15725
0
{
15726
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15727
15728
 /* basic algorithm is:
15729
  *   - ensure sane alignment of output data
15730
  *   - copy (conversion happens automatically) input data
15731
  *     to output
15732
  *   - update tp to point at next unconverted input, and xpp to point
15733
  *     at next location for converted output
15734
  */
15735
  long i, j, ni;
15736
  float tmp[LOOPCNT];        /* in case input is misaligned */
15737
  float *xp;
15738
  int nrange = 0;         /* number of range errors */
15739
  int realign = 0;        /* "do we need to fix input data alignment?" */
15740
  long cxp = (long) *((char**)xpp);
15741
15742
  realign = (cxp & 7) % SIZEOF_FLOAT;
15743
  /* sjl: manually stripmine so we can limit amount of
15744
   * vector work space reserved to LOOPCNT elements. Also
15745
   * makes vectorisation easy */
15746
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15747
    ni=Min(nelems-j,LOOPCNT);
15748
    if (realign) {
15749
      xp = tmp;
15750
    } else {
15751
      xp = (float *) *xpp;
15752
    }
15753
   /* copy the next block */
15754
#pragma cdir loopcnt=LOOPCNT
15755
#pragma cdir shortloop
15756
    for (i=0; i<ni; i++) {
15757
      /* the normal case: */
15758
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15759
     /* test for range errors (not always needed but do it anyway) */
15760
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15761
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15762
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15763
    }
15764
   /* copy workspace back if necessary */
15765
    if (realign) {
15766
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15767
      xp = (float *) *xpp;
15768
    }
15769
   /* update xpp and tp */
15770
    xp += ni;
15771
    tp += ni;
15772
    *xpp = (void*)xp;
15773
  }
15774
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15775
15776
#else   /* not SX */
15777
15778
0
  char *xp = (char *) *xpp;
15779
0
  int status = NC_NOERR;
15780
15781
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15782
0
  {
15783
0
    int lstatus = ncx_put_float_long(xp, tp, fillp);
15784
0
    if (status == NC_NOERR) /* report the first encountered error */
15785
0
      status = lstatus;
15786
0
  }
15787
15788
0
  *xpp = (void *)xp;
15789
0
  return status;
15790
0
#endif
15791
0
}
15792
15793
int
15794
ncx_putn_float_double(void **xpp, size_t nelems, const double *tp, void *fillp)
15795
0
{
15796
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15797
15798
 /* basic algorithm is:
15799
  *   - ensure sane alignment of output data
15800
  *   - copy (conversion happens automatically) input data
15801
  *     to output
15802
  *   - update tp to point at next unconverted input, and xpp to point
15803
  *     at next location for converted output
15804
  */
15805
  long i, j, ni;
15806
  float tmp[LOOPCNT];        /* in case input is misaligned */
15807
  float *xp;
15808
  int nrange = 0;         /* number of range errors */
15809
  int realign = 0;        /* "do we need to fix input data alignment?" */
15810
  long cxp = (long) *((char**)xpp);
15811
15812
  realign = (cxp & 7) % SIZEOF_FLOAT;
15813
  /* sjl: manually stripmine so we can limit amount of
15814
   * vector work space reserved to LOOPCNT elements. Also
15815
   * makes vectorisation easy */
15816
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15817
    ni=Min(nelems-j,LOOPCNT);
15818
    if (realign) {
15819
      xp = tmp;
15820
    } else {
15821
      xp = (float *) *xpp;
15822
    }
15823
   /* copy the next block */
15824
#pragma cdir loopcnt=LOOPCNT
15825
#pragma cdir shortloop
15826
    for (i=0; i<ni; i++) {
15827
      /* the normal case: */
15828
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15829
     /* test for range errors (not always needed but do it anyway) */
15830
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15831
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15832
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15833
    }
15834
   /* copy workspace back if necessary */
15835
    if (realign) {
15836
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15837
      xp = (float *) *xpp;
15838
    }
15839
   /* update xpp and tp */
15840
    xp += ni;
15841
    tp += ni;
15842
    *xpp = (void*)xp;
15843
  }
15844
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15845
15846
#else   /* not SX */
15847
15848
0
  char *xp = (char *) *xpp;
15849
0
  int status = NC_NOERR;
15850
15851
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15852
0
  {
15853
0
    int lstatus = ncx_put_float_double(xp, tp, fillp);
15854
0
    if (status == NC_NOERR) /* report the first encountered error */
15855
0
      status = lstatus;
15856
0
  }
15857
15858
0
  *xpp = (void *)xp;
15859
0
  return status;
15860
0
#endif
15861
0
}
15862
15863
int
15864
ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
15865
0
{
15866
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15867
15868
 /* basic algorithm is:
15869
  *   - ensure sane alignment of output data
15870
  *   - copy (conversion happens automatically) input data
15871
  *     to output
15872
  *   - update tp to point at next unconverted input, and xpp to point
15873
  *     at next location for converted output
15874
  */
15875
  long i, j, ni;
15876
  float tmp[LOOPCNT];        /* in case input is misaligned */
15877
  float *xp;
15878
  int nrange = 0;         /* number of range errors */
15879
  int realign = 0;        /* "do we need to fix input data alignment?" */
15880
  long cxp = (long) *((char**)xpp);
15881
15882
  realign = (cxp & 7) % SIZEOF_FLOAT;
15883
  /* sjl: manually stripmine so we can limit amount of
15884
   * vector work space reserved to LOOPCNT elements. Also
15885
   * makes vectorisation easy */
15886
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15887
    ni=Min(nelems-j,LOOPCNT);
15888
    if (realign) {
15889
      xp = tmp;
15890
    } else {
15891
      xp = (float *) *xpp;
15892
    }
15893
   /* copy the next block */
15894
#pragma cdir loopcnt=LOOPCNT
15895
#pragma cdir shortloop
15896
    for (i=0; i<ni; i++) {
15897
      /* the normal case: */
15898
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15899
     /* test for range errors (not always needed but do it anyway) */
15900
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15901
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15902
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15903
    }
15904
   /* copy workspace back if necessary */
15905
    if (realign) {
15906
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15907
      xp = (float *) *xpp;
15908
    }
15909
   /* update xpp and tp */
15910
    xp += ni;
15911
    tp += ni;
15912
    *xpp = (void*)xp;
15913
  }
15914
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15915
15916
#else   /* not SX */
15917
15918
0
  char *xp = (char *) *xpp;
15919
0
  int status = NC_NOERR;
15920
15921
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15922
0
  {
15923
0
    int lstatus = ncx_put_float_longlong(xp, tp, fillp);
15924
0
    if (status == NC_NOERR) /* report the first encountered error */
15925
0
      status = lstatus;
15926
0
  }
15927
15928
0
  *xpp = (void *)xp;
15929
0
  return status;
15930
0
#endif
15931
0
}
15932
15933
int
15934
ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
15935
0
{
15936
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15937
15938
 /* basic algorithm is:
15939
  *   - ensure sane alignment of output data
15940
  *   - copy (conversion happens automatically) input data
15941
  *     to output
15942
  *   - update tp to point at next unconverted input, and xpp to point
15943
  *     at next location for converted output
15944
  */
15945
  long i, j, ni;
15946
  float tmp[LOOPCNT];        /* in case input is misaligned */
15947
  float *xp;
15948
  int nrange = 0;         /* number of range errors */
15949
  int realign = 0;        /* "do we need to fix input data alignment?" */
15950
  long cxp = (long) *((char**)xpp);
15951
15952
  realign = (cxp & 7) % SIZEOF_FLOAT;
15953
  /* sjl: manually stripmine so we can limit amount of
15954
   * vector work space reserved to LOOPCNT elements. Also
15955
   * makes vectorisation easy */
15956
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15957
    ni=Min(nelems-j,LOOPCNT);
15958
    if (realign) {
15959
      xp = tmp;
15960
    } else {
15961
      xp = (float *) *xpp;
15962
    }
15963
   /* copy the next block */
15964
#pragma cdir loopcnt=LOOPCNT
15965
#pragma cdir shortloop
15966
    for (i=0; i<ni; i++) {
15967
      /* the normal case: */
15968
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15969
     /* test for range errors (not always needed but do it anyway) */
15970
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15971
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15972
      nrange += tp[i] > X_FLOAT_MAX ;
15973
    }
15974
   /* copy workspace back if necessary */
15975
    if (realign) {
15976
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15977
      xp = (float *) *xpp;
15978
    }
15979
   /* update xpp and tp */
15980
    xp += ni;
15981
    tp += ni;
15982
    *xpp = (void*)xp;
15983
  }
15984
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15985
15986
#else   /* not SX */
15987
15988
0
  char *xp = (char *) *xpp;
15989
0
  int status = NC_NOERR;
15990
15991
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15992
0
  {
15993
0
    int lstatus = ncx_put_float_uchar(xp, tp, fillp);
15994
0
    if (status == NC_NOERR) /* report the first encountered error */
15995
0
      status = lstatus;
15996
0
  }
15997
15998
0
  *xpp = (void *)xp;
15999
0
  return status;
16000
0
#endif
16001
0
}
16002
16003
int
16004
ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
16005
0
{
16006
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16007
16008
 /* basic algorithm is:
16009
  *   - ensure sane alignment of output data
16010
  *   - copy (conversion happens automatically) input data
16011
  *     to output
16012
  *   - update tp to point at next unconverted input, and xpp to point
16013
  *     at next location for converted output
16014
  */
16015
  long i, j, ni;
16016
  float tmp[LOOPCNT];        /* in case input is misaligned */
16017
  float *xp;
16018
  int nrange = 0;         /* number of range errors */
16019
  int realign = 0;        /* "do we need to fix input data alignment?" */
16020
  long cxp = (long) *((char**)xpp);
16021
16022
  realign = (cxp & 7) % SIZEOF_FLOAT;
16023
  /* sjl: manually stripmine so we can limit amount of
16024
   * vector work space reserved to LOOPCNT elements. Also
16025
   * makes vectorisation easy */
16026
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16027
    ni=Min(nelems-j,LOOPCNT);
16028
    if (realign) {
16029
      xp = tmp;
16030
    } else {
16031
      xp = (float *) *xpp;
16032
    }
16033
   /* copy the next block */
16034
#pragma cdir loopcnt=LOOPCNT
16035
#pragma cdir shortloop
16036
    for (i=0; i<ni; i++) {
16037
      /* the normal case: */
16038
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16039
     /* test for range errors (not always needed but do it anyway) */
16040
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16041
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16042
      nrange += tp[i] > X_FLOAT_MAX ;
16043
    }
16044
   /* copy workspace back if necessary */
16045
    if (realign) {
16046
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16047
      xp = (float *) *xpp;
16048
    }
16049
   /* update xpp and tp */
16050
    xp += ni;
16051
    tp += ni;
16052
    *xpp = (void*)xp;
16053
  }
16054
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16055
16056
#else   /* not SX */
16057
16058
0
  char *xp = (char *) *xpp;
16059
0
  int status = NC_NOERR;
16060
16061
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16062
0
  {
16063
0
    int lstatus = ncx_put_float_ushort(xp, tp, fillp);
16064
0
    if (status == NC_NOERR) /* report the first encountered error */
16065
0
      status = lstatus;
16066
0
  }
16067
16068
0
  *xpp = (void *)xp;
16069
0
  return status;
16070
0
#endif
16071
0
}
16072
16073
int
16074
ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
16075
0
{
16076
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16077
16078
 /* basic algorithm is:
16079
  *   - ensure sane alignment of output data
16080
  *   - copy (conversion happens automatically) input data
16081
  *     to output
16082
  *   - update tp to point at next unconverted input, and xpp to point
16083
  *     at next location for converted output
16084
  */
16085
  long i, j, ni;
16086
  float tmp[LOOPCNT];        /* in case input is misaligned */
16087
  float *xp;
16088
  int nrange = 0;         /* number of range errors */
16089
  int realign = 0;        /* "do we need to fix input data alignment?" */
16090
  long cxp = (long) *((char**)xpp);
16091
16092
  realign = (cxp & 7) % SIZEOF_FLOAT;
16093
  /* sjl: manually stripmine so we can limit amount of
16094
   * vector work space reserved to LOOPCNT elements. Also
16095
   * makes vectorisation easy */
16096
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16097
    ni=Min(nelems-j,LOOPCNT);
16098
    if (realign) {
16099
      xp = tmp;
16100
    } else {
16101
      xp = (float *) *xpp;
16102
    }
16103
   /* copy the next block */
16104
#pragma cdir loopcnt=LOOPCNT
16105
#pragma cdir shortloop
16106
    for (i=0; i<ni; i++) {
16107
      /* the normal case: */
16108
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16109
     /* test for range errors (not always needed but do it anyway) */
16110
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16111
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16112
      nrange += tp[i] > X_FLOAT_MAX ;
16113
    }
16114
   /* copy workspace back if necessary */
16115
    if (realign) {
16116
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16117
      xp = (float *) *xpp;
16118
    }
16119
   /* update xpp and tp */
16120
    xp += ni;
16121
    tp += ni;
16122
    *xpp = (void*)xp;
16123
  }
16124
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16125
16126
#else   /* not SX */
16127
16128
0
  char *xp = (char *) *xpp;
16129
0
  int status = NC_NOERR;
16130
16131
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16132
0
  {
16133
0
    int lstatus = ncx_put_float_uint(xp, tp, fillp);
16134
0
    if (status == NC_NOERR) /* report the first encountered error */
16135
0
      status = lstatus;
16136
0
  }
16137
16138
0
  *xpp = (void *)xp;
16139
0
  return status;
16140
0
#endif
16141
0
}
16142
16143
int
16144
ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
16145
0
{
16146
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16147
16148
 /* basic algorithm is:
16149
  *   - ensure sane alignment of output data
16150
  *   - copy (conversion happens automatically) input data
16151
  *     to output
16152
  *   - update tp to point at next unconverted input, and xpp to point
16153
  *     at next location for converted output
16154
  */
16155
  long i, j, ni;
16156
  float tmp[LOOPCNT];        /* in case input is misaligned */
16157
  float *xp;
16158
  int nrange = 0;         /* number of range errors */
16159
  int realign = 0;        /* "do we need to fix input data alignment?" */
16160
  long cxp = (long) *((char**)xpp);
16161
16162
  realign = (cxp & 7) % SIZEOF_FLOAT;
16163
  /* sjl: manually stripmine so we can limit amount of
16164
   * vector work space reserved to LOOPCNT elements. Also
16165
   * makes vectorisation easy */
16166
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16167
    ni=Min(nelems-j,LOOPCNT);
16168
    if (realign) {
16169
      xp = tmp;
16170
    } else {
16171
      xp = (float *) *xpp;
16172
    }
16173
   /* copy the next block */
16174
#pragma cdir loopcnt=LOOPCNT
16175
#pragma cdir shortloop
16176
    for (i=0; i<ni; i++) {
16177
      /* the normal case: */
16178
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16179
     /* test for range errors (not always needed but do it anyway) */
16180
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16181
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16182
      nrange += tp[i] > X_FLOAT_MAX ;
16183
    }
16184
   /* copy workspace back if necessary */
16185
    if (realign) {
16186
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16187
      xp = (float *) *xpp;
16188
    }
16189
   /* update xpp and tp */
16190
    xp += ni;
16191
    tp += ni;
16192
    *xpp = (void*)xp;
16193
  }
16194
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16195
16196
#else   /* not SX */
16197
16198
0
  char *xp = (char *) *xpp;
16199
0
  int status = NC_NOERR;
16200
16201
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16202
0
  {
16203
0
    int lstatus = ncx_put_float_ulonglong(xp, tp, fillp);
16204
0
    if (status == NC_NOERR) /* report the first encountered error */
16205
0
      status = lstatus;
16206
0
  }
16207
16208
0
  *xpp = (void *)xp;
16209
0
  return status;
16210
0
#endif
16211
0
}
16212
16213
16214
/* double --------------------------------------------------------------------*/
16215
16216
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16217
/* optimized version */
16218
int
16219
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16220
0
{
16221
#ifdef WORDS_BIGENDIAN
16222
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
16223
# else
16224
0
  swapn8b(tp, *xpp, nelems);
16225
0
# endif
16226
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16227
0
  return NC_NOERR;
16228
0
}
16229
#elif defined(vax) && vax != 0
16230
int
16231
ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
16232
{
16233
  double *const end = ip + ndoubles;
16234
16235
  while (ip < end)
16236
  {
16237
  struct vax_double *const vdp =
16238
       (struct vax_double *)ip;
16239
  const struct ieee_double *const idp =
16240
       (const struct ieee_double *) (*xpp);
16241
  {
16242
    const struct dbl_limits *lim;
16243
    int ii;
16244
    for (ii = 0, lim = dbl_limits;
16245
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
16246
      ii++, lim++)
16247
    {
16248
      if ((idp->mant_lo == lim->ieee.mant_lo)
16249
        && (idp->mant_4 == lim->ieee.mant_4)
16250
        && (idp->mant_5 == lim->ieee.mant_5)
16251
        && (idp->mant_6 == lim->ieee.mant_6)
16252
        && (idp->exp_lo == lim->ieee.exp_lo)
16253
        && (idp->exp_hi == lim->ieee.exp_hi)
16254
        )
16255
      {
16256
        *vdp = lim->d;
16257
        goto doneit;
16258
      }
16259
    }
16260
  }
16261
  {
16262
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
16263
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
16264
  }
16265
  {
16266
    unsigned mant_hi = ((idp->mant_6 << 16)
16267
         | (idp->mant_5 << 8)
16268
         | idp->mant_4);
16269
    unsigned mant_lo = SWAP4(idp->mant_lo);
16270
    vdp->mantissa1 = (mant_hi >> 13);
16271
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
16272
        | (mant_lo >> 29);
16273
    vdp->mantissa3 = (mant_lo >> 13);
16274
    vdp->mantissa4 = (mant_lo << 3);
16275
  }
16276
  doneit:
16277
    vdp->sign = idp->sign;
16278
16279
    ip++;
16280
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
16281
  }
16282
  return NC_NOERR;
16283
}
16284
  /* vax */
16285
#else
16286
int
16287
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16288
{
16289
  const char *xp = *xpp;
16290
  int status = NC_NOERR;
16291
16292
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16293
  {
16294
    const int lstatus = ncx_get_double_double(xp, tp, fillp);
16295
    if (status == NC_NOERR) /* report the first encountered error */
16296
      status = lstatus;
16297
  }
16298
16299
  *xpp = (const void *)xp;
16300
  return status;
16301
}
16302
#endif
16303
int
16304
ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
16305
0
{
16306
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16307
16308
 /* basic algorithm is:
16309
  *   - ensure sane alignment of input data
16310
  *   - copy (conversion happens automatically) input data
16311
  *     to output
16312
  *   - update xpp to point at next unconverted input, and tp to point
16313
  *     at next location for converted output
16314
  */
16315
  long i, j, ni;
16316
  double tmp[LOOPCNT];        /* in case input is misaligned */
16317
  double *xp;
16318
  int nrange = 0;         /* number of range errors */
16319
  int realign = 0;        /* "do we need to fix input data alignment?" */
16320
  long cxp = (long) *((char**)xpp);
16321
16322
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16323
  /* sjl: manually stripmine so we can limit amount of
16324
   * vector work space reserved to LOOPCNT elements. Also
16325
   * makes vectorisation easy */
16326
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16327
    ni=Min(nelems-j,LOOPCNT);
16328
    if (realign) {
16329
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16330
      xp = tmp;
16331
    } else {
16332
      xp = (double *) *xpp;
16333
    }
16334
   /* copy the next block */
16335
#pragma cdir loopcnt=LOOPCNT
16336
#pragma cdir shortloop
16337
    for (i=0; i<ni; i++) {
16338
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
16339
     /* test for range errors (not always needed but do it anyway) */
16340
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16341
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16342
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
16343
    }
16344
   /* update xpp and tp */
16345
    if (realign) xp = (double *) *xpp;
16346
    xp += ni;
16347
    tp += ni;
16348
    *xpp = (void*)xp;
16349
  }
16350
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16351
16352
#else   /* not SX */
16353
0
  const char *xp = (const char *) *xpp;
16354
0
  int status = NC_NOERR;
16355
16356
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16357
0
  {
16358
0
    const int lstatus = ncx_get_double_schar(xp, tp);
16359
0
    if (status == NC_NOERR) /* report the first encountered error */
16360
0
      status = lstatus;
16361
0
  }
16362
16363
0
  *xpp = (const void *)xp;
16364
0
  return status;
16365
0
#endif
16366
0
}
16367
16368
int
16369
ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
16370
0
{
16371
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16372
16373
 /* basic algorithm is:
16374
  *   - ensure sane alignment of input data
16375
  *   - copy (conversion happens automatically) input data
16376
  *     to output
16377
  *   - update xpp to point at next unconverted input, and tp to point
16378
  *     at next location for converted output
16379
  */
16380
  long i, j, ni;
16381
  double tmp[LOOPCNT];        /* in case input is misaligned */
16382
  double *xp;
16383
  int nrange = 0;         /* number of range errors */
16384
  int realign = 0;        /* "do we need to fix input data alignment?" */
16385
  long cxp = (long) *((char**)xpp);
16386
16387
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16388
  /* sjl: manually stripmine so we can limit amount of
16389
   * vector work space reserved to LOOPCNT elements. Also
16390
   * makes vectorisation easy */
16391
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16392
    ni=Min(nelems-j,LOOPCNT);
16393
    if (realign) {
16394
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16395
      xp = tmp;
16396
    } else {
16397
      xp = (double *) *xpp;
16398
    }
16399
   /* copy the next block */
16400
#pragma cdir loopcnt=LOOPCNT
16401
#pragma cdir shortloop
16402
    for (i=0; i<ni; i++) {
16403
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
16404
     /* test for range errors (not always needed but do it anyway) */
16405
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16406
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16407
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
16408
    }
16409
   /* update xpp and tp */
16410
    if (realign) xp = (double *) *xpp;
16411
    xp += ni;
16412
    tp += ni;
16413
    *xpp = (void*)xp;
16414
  }
16415
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16416
16417
#else   /* not SX */
16418
0
  const char *xp = (const char *) *xpp;
16419
0
  int status = NC_NOERR;
16420
16421
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16422
0
  {
16423
0
    const int lstatus = ncx_get_double_short(xp, tp);
16424
0
    if (status == NC_NOERR) /* report the first encountered error */
16425
0
      status = lstatus;
16426
0
  }
16427
16428
0
  *xpp = (const void *)xp;
16429
0
  return status;
16430
0
#endif
16431
0
}
16432
16433
int
16434
ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
16435
0
{
16436
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16437
16438
 /* basic algorithm is:
16439
  *   - ensure sane alignment of input data
16440
  *   - copy (conversion happens automatically) input data
16441
  *     to output
16442
  *   - update xpp to point at next unconverted input, and tp to point
16443
  *     at next location for converted output
16444
  */
16445
  long i, j, ni;
16446
  double tmp[LOOPCNT];        /* in case input is misaligned */
16447
  double *xp;
16448
  int nrange = 0;         /* number of range errors */
16449
  int realign = 0;        /* "do we need to fix input data alignment?" */
16450
  long cxp = (long) *((char**)xpp);
16451
16452
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16453
  /* sjl: manually stripmine so we can limit amount of
16454
   * vector work space reserved to LOOPCNT elements. Also
16455
   * makes vectorisation easy */
16456
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16457
    ni=Min(nelems-j,LOOPCNT);
16458
    if (realign) {
16459
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16460
      xp = tmp;
16461
    } else {
16462
      xp = (double *) *xpp;
16463
    }
16464
   /* copy the next block */
16465
#pragma cdir loopcnt=LOOPCNT
16466
#pragma cdir shortloop
16467
    for (i=0; i<ni; i++) {
16468
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
16469
     /* test for range errors (not always needed but do it anyway) */
16470
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16471
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16472
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
16473
    }
16474
   /* update xpp and tp */
16475
    if (realign) xp = (double *) *xpp;
16476
    xp += ni;
16477
    tp += ni;
16478
    *xpp = (void*)xp;
16479
  }
16480
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16481
16482
#else   /* not SX */
16483
0
  const char *xp = (const char *) *xpp;
16484
0
  int status = NC_NOERR;
16485
16486
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16487
0
  {
16488
0
    const int lstatus = ncx_get_double_int(xp, tp);
16489
0
    if (status == NC_NOERR) /* report the first encountered error */
16490
0
      status = lstatus;
16491
0
  }
16492
16493
0
  *xpp = (const void *)xp;
16494
0
  return status;
16495
0
#endif
16496
0
}
16497
16498
int
16499
ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
16500
0
{
16501
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16502
16503
 /* basic algorithm is:
16504
  *   - ensure sane alignment of input data
16505
  *   - copy (conversion happens automatically) input data
16506
  *     to output
16507
  *   - update xpp to point at next unconverted input, and tp to point
16508
  *     at next location for converted output
16509
  */
16510
  long i, j, ni;
16511
  double tmp[LOOPCNT];        /* in case input is misaligned */
16512
  double *xp;
16513
  int nrange = 0;         /* number of range errors */
16514
  int realign = 0;        /* "do we need to fix input data alignment?" */
16515
  long cxp = (long) *((char**)xpp);
16516
16517
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16518
  /* sjl: manually stripmine so we can limit amount of
16519
   * vector work space reserved to LOOPCNT elements. Also
16520
   * makes vectorisation easy */
16521
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16522
    ni=Min(nelems-j,LOOPCNT);
16523
    if (realign) {
16524
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16525
      xp = tmp;
16526
    } else {
16527
      xp = (double *) *xpp;
16528
    }
16529
   /* copy the next block */
16530
#pragma cdir loopcnt=LOOPCNT
16531
#pragma cdir shortloop
16532
    for (i=0; i<ni; i++) {
16533
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
16534
     /* test for range errors (not always needed but do it anyway) */
16535
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16536
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16537
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
16538
    }
16539
   /* update xpp and tp */
16540
    if (realign) xp = (double *) *xpp;
16541
    xp += ni;
16542
    tp += ni;
16543
    *xpp = (void*)xp;
16544
  }
16545
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16546
16547
#else   /* not SX */
16548
0
  const char *xp = (const char *) *xpp;
16549
0
  int status = NC_NOERR;
16550
16551
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16552
0
  {
16553
0
    const int lstatus = ncx_get_double_long(xp, tp);
16554
0
    if (status == NC_NOERR) /* report the first encountered error */
16555
0
      status = lstatus;
16556
0
  }
16557
16558
0
  *xpp = (const void *)xp;
16559
0
  return status;
16560
0
#endif
16561
0
}
16562
16563
int
16564
ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
16565
0
{
16566
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16567
16568
 /* basic algorithm is:
16569
  *   - ensure sane alignment of input data
16570
  *   - copy (conversion happens automatically) input data
16571
  *     to output
16572
  *   - update xpp to point at next unconverted input, and tp to point
16573
  *     at next location for converted output
16574
  */
16575
  long i, j, ni;
16576
  double tmp[LOOPCNT];        /* in case input is misaligned */
16577
  double *xp;
16578
  int nrange = 0;         /* number of range errors */
16579
  int realign = 0;        /* "do we need to fix input data alignment?" */
16580
  long cxp = (long) *((char**)xpp);
16581
16582
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16583
  /* sjl: manually stripmine so we can limit amount of
16584
   * vector work space reserved to LOOPCNT elements. Also
16585
   * makes vectorisation easy */
16586
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16587
    ni=Min(nelems-j,LOOPCNT);
16588
    if (realign) {
16589
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16590
      xp = tmp;
16591
    } else {
16592
      xp = (double *) *xpp;
16593
    }
16594
   /* copy the next block */
16595
#pragma cdir loopcnt=LOOPCNT
16596
#pragma cdir shortloop
16597
    for (i=0; i<ni; i++) {
16598
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
16599
     /* test for range errors (not always needed but do it anyway) */
16600
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16601
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16602
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
16603
    }
16604
   /* update xpp and tp */
16605
    if (realign) xp = (double *) *xpp;
16606
    xp += ni;
16607
    tp += ni;
16608
    *xpp = (void*)xp;
16609
  }
16610
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16611
16612
#else   /* not SX */
16613
0
  const char *xp = (const char *) *xpp;
16614
0
  int status = NC_NOERR;
16615
16616
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16617
0
  {
16618
0
    const int lstatus = ncx_get_double_float(xp, tp);
16619
0
    if (status == NC_NOERR) /* report the first encountered error */
16620
0
      status = lstatus;
16621
0
  }
16622
16623
0
  *xpp = (const void *)xp;
16624
0
  return status;
16625
0
#endif
16626
0
}
16627
16628
int
16629
ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp)
16630
0
{
16631
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16632
16633
 /* basic algorithm is:
16634
  *   - ensure sane alignment of input data
16635
  *   - copy (conversion happens automatically) input data
16636
  *     to output
16637
  *   - update xpp to point at next unconverted input, and tp to point
16638
  *     at next location for converted output
16639
  */
16640
  long i, j, ni;
16641
  double tmp[LOOPCNT];        /* in case input is misaligned */
16642
  double *xp;
16643
  int nrange = 0;         /* number of range errors */
16644
  int realign = 0;        /* "do we need to fix input data alignment?" */
16645
  long cxp = (long) *((char**)xpp);
16646
16647
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16648
  /* sjl: manually stripmine so we can limit amount of
16649
   * vector work space reserved to LOOPCNT elements. Also
16650
   * makes vectorisation easy */
16651
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16652
    ni=Min(nelems-j,LOOPCNT);
16653
    if (realign) {
16654
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16655
      xp = tmp;
16656
    } else {
16657
      xp = (double *) *xpp;
16658
    }
16659
   /* copy the next block */
16660
#pragma cdir loopcnt=LOOPCNT
16661
#pragma cdir shortloop
16662
    for (i=0; i<ni; i++) {
16663
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
16664
     /* test for range errors (not always needed but do it anyway) */
16665
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16666
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16667
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
16668
    }
16669
   /* update xpp and tp */
16670
    if (realign) xp = (double *) *xpp;
16671
    xp += ni;
16672
    tp += ni;
16673
    *xpp = (void*)xp;
16674
  }
16675
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16676
16677
#else   /* not SX */
16678
0
  const char *xp = (const char *) *xpp;
16679
0
  int status = NC_NOERR;
16680
16681
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16682
0
  {
16683
0
    const int lstatus = ncx_get_double_longlong(xp, tp);
16684
0
    if (status == NC_NOERR) /* report the first encountered error */
16685
0
      status = lstatus;
16686
0
  }
16687
16688
0
  *xpp = (const void *)xp;
16689
0
  return status;
16690
0
#endif
16691
0
}
16692
16693
int
16694
ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
16695
0
{
16696
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16697
16698
 /* basic algorithm is:
16699
  *   - ensure sane alignment of input data
16700
  *   - copy (conversion happens automatically) input data
16701
  *     to output
16702
  *   - update xpp to point at next unconverted input, and tp to point
16703
  *     at next location for converted output
16704
  */
16705
  long i, j, ni;
16706
  double tmp[LOOPCNT];        /* in case input is misaligned */
16707
  double *xp;
16708
  int nrange = 0;         /* number of range errors */
16709
  int realign = 0;        /* "do we need to fix input data alignment?" */
16710
  long cxp = (long) *((char**)xpp);
16711
16712
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16713
  /* sjl: manually stripmine so we can limit amount of
16714
   * vector work space reserved to LOOPCNT elements. Also
16715
   * makes vectorisation easy */
16716
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16717
    ni=Min(nelems-j,LOOPCNT);
16718
    if (realign) {
16719
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16720
      xp = tmp;
16721
    } else {
16722
      xp = (double *) *xpp;
16723
    }
16724
   /* copy the next block */
16725
#pragma cdir loopcnt=LOOPCNT
16726
#pragma cdir shortloop
16727
    for (i=0; i<ni; i++) {
16728
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
16729
     /* test for range errors (not always needed but do it anyway) */
16730
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16731
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16732
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
16733
    }
16734
   /* update xpp and tp */
16735
    if (realign) xp = (double *) *xpp;
16736
    xp += ni;
16737
    tp += ni;
16738
    *xpp = (void*)xp;
16739
  }
16740
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16741
16742
#else   /* not SX */
16743
0
  const char *xp = (const char *) *xpp;
16744
0
  int status = NC_NOERR;
16745
16746
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16747
0
  {
16748
0
    const int lstatus = ncx_get_double_uchar(xp, tp);
16749
0
    if (status == NC_NOERR) /* report the first encountered error */
16750
0
      status = lstatus;
16751
0
  }
16752
16753
0
  *xpp = (const void *)xp;
16754
0
  return status;
16755
0
#endif
16756
0
}
16757
16758
int
16759
ncx_getn_double_ushort(const void **xpp, size_t nelems, ushort *tp)
16760
0
{
16761
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16762
16763
 /* basic algorithm is:
16764
  *   - ensure sane alignment of input data
16765
  *   - copy (conversion happens automatically) input data
16766
  *     to output
16767
  *   - update xpp to point at next unconverted input, and tp to point
16768
  *     at next location for converted output
16769
  */
16770
  long i, j, ni;
16771
  double tmp[LOOPCNT];        /* in case input is misaligned */
16772
  double *xp;
16773
  int nrange = 0;         /* number of range errors */
16774
  int realign = 0;        /* "do we need to fix input data alignment?" */
16775
  long cxp = (long) *((char**)xpp);
16776
16777
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16778
  /* sjl: manually stripmine so we can limit amount of
16779
   * vector work space reserved to LOOPCNT elements. Also
16780
   * makes vectorisation easy */
16781
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16782
    ni=Min(nelems-j,LOOPCNT);
16783
    if (realign) {
16784
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16785
      xp = tmp;
16786
    } else {
16787
      xp = (double *) *xpp;
16788
    }
16789
   /* copy the next block */
16790
#pragma cdir loopcnt=LOOPCNT
16791
#pragma cdir shortloop
16792
    for (i=0; i<ni; i++) {
16793
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
16794
     /* test for range errors (not always needed but do it anyway) */
16795
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16796
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16797
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
16798
    }
16799
   /* update xpp and tp */
16800
    if (realign) xp = (double *) *xpp;
16801
    xp += ni;
16802
    tp += ni;
16803
    *xpp = (void*)xp;
16804
  }
16805
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16806
16807
#else   /* not SX */
16808
0
  const char *xp = (const char *) *xpp;
16809
0
  int status = NC_NOERR;
16810
16811
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16812
0
  {
16813
0
    const int lstatus = ncx_get_double_ushort(xp, tp);
16814
0
    if (status == NC_NOERR) /* report the first encountered error */
16815
0
      status = lstatus;
16816
0
  }
16817
16818
0
  *xpp = (const void *)xp;
16819
0
  return status;
16820
0
#endif
16821
0
}
16822
16823
int
16824
ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp)
16825
0
{
16826
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16827
16828
 /* basic algorithm is:
16829
  *   - ensure sane alignment of input data
16830
  *   - copy (conversion happens automatically) input data
16831
  *     to output
16832
  *   - update xpp to point at next unconverted input, and tp to point
16833
  *     at next location for converted output
16834
  */
16835
  long i, j, ni;
16836
  double tmp[LOOPCNT];        /* in case input is misaligned */
16837
  double *xp;
16838
  int nrange = 0;         /* number of range errors */
16839
  int realign = 0;        /* "do we need to fix input data alignment?" */
16840
  long cxp = (long) *((char**)xpp);
16841
16842
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16843
  /* sjl: manually stripmine so we can limit amount of
16844
   * vector work space reserved to LOOPCNT elements. Also
16845
   * makes vectorisation easy */
16846
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16847
    ni=Min(nelems-j,LOOPCNT);
16848
    if (realign) {
16849
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16850
      xp = tmp;
16851
    } else {
16852
      xp = (double *) *xpp;
16853
    }
16854
   /* copy the next block */
16855
#pragma cdir loopcnt=LOOPCNT
16856
#pragma cdir shortloop
16857
    for (i=0; i<ni; i++) {
16858
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
16859
     /* test for range errors (not always needed but do it anyway) */
16860
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16861
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16862
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
16863
    }
16864
   /* update xpp and tp */
16865
    if (realign) xp = (double *) *xpp;
16866
    xp += ni;
16867
    tp += ni;
16868
    *xpp = (void*)xp;
16869
  }
16870
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16871
16872
#else   /* not SX */
16873
0
  const char *xp = (const char *) *xpp;
16874
0
  int status = NC_NOERR;
16875
16876
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16877
0
  {
16878
0
    const int lstatus = ncx_get_double_uint(xp, tp);
16879
0
    if (status == NC_NOERR) /* report the first encountered error */
16880
0
      status = lstatus;
16881
0
  }
16882
16883
0
  *xpp = (const void *)xp;
16884
0
  return status;
16885
0
#endif
16886
0
}
16887
16888
int
16889
ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
16890
0
{
16891
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16892
16893
 /* basic algorithm is:
16894
  *   - ensure sane alignment of input data
16895
  *   - copy (conversion happens automatically) input data
16896
  *     to output
16897
  *   - update xpp to point at next unconverted input, and tp to point
16898
  *     at next location for converted output
16899
  */
16900
  long i, j, ni;
16901
  double tmp[LOOPCNT];        /* in case input is misaligned */
16902
  double *xp;
16903
  int nrange = 0;         /* number of range errors */
16904
  int realign = 0;        /* "do we need to fix input data alignment?" */
16905
  long cxp = (long) *((char**)xpp);
16906
16907
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16908
  /* sjl: manually stripmine so we can limit amount of
16909
   * vector work space reserved to LOOPCNT elements. Also
16910
   * makes vectorisation easy */
16911
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16912
    ni=Min(nelems-j,LOOPCNT);
16913
    if (realign) {
16914
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16915
      xp = tmp;
16916
    } else {
16917
      xp = (double *) *xpp;
16918
    }
16919
   /* copy the next block */
16920
#pragma cdir loopcnt=LOOPCNT
16921
#pragma cdir shortloop
16922
    for (i=0; i<ni; i++) {
16923
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
16924
     /* test for range errors (not always needed but do it anyway) */
16925
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16926
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16927
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
16928
    }
16929
   /* update xpp and tp */
16930
    if (realign) xp = (double *) *xpp;
16931
    xp += ni;
16932
    tp += ni;
16933
    *xpp = (void*)xp;
16934
  }
16935
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16936
16937
#else   /* not SX */
16938
0
  const char *xp = (const char *) *xpp;
16939
0
  int status = NC_NOERR;
16940
16941
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16942
0
  {
16943
0
    const int lstatus = ncx_get_double_ulonglong(xp, tp);
16944
0
    if (status == NC_NOERR) /* report the first encountered error */
16945
0
      status = lstatus;
16946
0
  }
16947
16948
0
  *xpp = (const void *)xp;
16949
0
  return status;
16950
0
#endif
16951
0
}
16952
16953
16954
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16955
/* optimized version */
16956
int
16957
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
16958
0
{
16959
#ifdef WORDS_BIGENDIAN
16960
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
16961
# else
16962
0
  swapn8b(*xpp, tp, nelems);
16963
0
# endif
16964
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16965
0
  return NC_NOERR;
16966
0
}
16967
#elif defined(vax) && vax != 0
16968
int
16969
ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip, void *fillp)
16970
{
16971
  const double *const end = ip + ndoubles;
16972
16973
  while (ip < end)
16974
  {
16975
  const struct vax_double *const vdp =
16976
      (const struct vax_double *)ip;
16977
  struct ieee_double *const idp =
16978
       (struct ieee_double *) (*xpp);
16979
16980
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
16981
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
16982
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
16983
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
16984
    (vdp->exp == dbl_limits[0].d.exp))
16985
  {
16986
    *idp = dbl_limits[0].ieee;
16987
    goto shipit;
16988
  }
16989
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
16990
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
16991
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
16992
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
16993
    (vdp->exp == dbl_limits[1].d.exp))
16994
  {
16995
    *idp = dbl_limits[1].ieee;
16996
    goto shipit;
16997
  }
16998
16999
  {
17000
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
17001
17002
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
17003
      (vdp->mantissa3 << 13) |
17004
      ((vdp->mantissa4 >> 3) & MASK(13));
17005
17006
    unsigned mant_hi = (vdp->mantissa1 << 13)
17007
         | (vdp->mantissa2 >> 3);
17008
17009
    if ((vdp->mantissa4 & 7) > 4)
17010
    {
17011
      /* round up */
17012
      mant_lo++;
17013
      if (mant_lo == 0)
17014
      {
17015
        mant_hi++;
17016
        if (mant_hi > 0xffffff)
17017
        {
17018
          mant_hi = 0;
17019
          exp++;
17020
        }
17021
      }
17022
    }
17023
17024
    idp->mant_lo = SWAP4(mant_lo);
17025
    idp->mant_6 = mant_hi >> 16;
17026
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
17027
    idp->mant_4 = mant_hi;
17028
    idp->exp_hi = exp >> 4;
17029
    idp->exp_lo = exp;
17030
  }
17031
17032
  shipit:
17033
    idp->sign = vdp->sign;
17034
17035
    ip++;
17036
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
17037
  }
17038
  return NC_NOERR;
17039
}
17040
  /* vax */
17041
#else
17042
int
17043
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17044
{
17045
  char *xp = *xpp;
17046
  int status = NC_NOERR;
17047
17048
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17049
  {
17050
    int lstatus = ncx_put_double_double(xp, tp, fillp);
17051
    if (status == NC_NOERR) /* report the first encountered error */
17052
      status = lstatus;
17053
  }
17054
17055
  *xpp = (void *)xp;
17056
  return status;
17057
}
17058
#endif
17059
int
17060
ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
17061
0
{
17062
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17063
17064
 /* basic algorithm is:
17065
  *   - ensure sane alignment of output data
17066
  *   - copy (conversion happens automatically) input data
17067
  *     to output
17068
  *   - update tp to point at next unconverted input, and xpp to point
17069
  *     at next location for converted output
17070
  */
17071
  long i, j, ni;
17072
  double tmp[LOOPCNT];        /* in case input is misaligned */
17073
  double *xp;
17074
  int nrange = 0;         /* number of range errors */
17075
  int realign = 0;        /* "do we need to fix input data alignment?" */
17076
  long cxp = (long) *((char**)xpp);
17077
17078
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17079
  /* sjl: manually stripmine so we can limit amount of
17080
   * vector work space reserved to LOOPCNT elements. Also
17081
   * makes vectorisation easy */
17082
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17083
    ni=Min(nelems-j,LOOPCNT);
17084
    if (realign) {
17085
      xp = tmp;
17086
    } else {
17087
      xp = (double *) *xpp;
17088
    }
17089
   /* copy the next block */
17090
#pragma cdir loopcnt=LOOPCNT
17091
#pragma cdir shortloop
17092
    for (i=0; i<ni; i++) {
17093
      /* the normal case: */
17094
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17095
     /* test for range errors (not always needed but do it anyway) */
17096
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17097
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17098
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17099
    }
17100
   /* copy workspace back if necessary */
17101
    if (realign) {
17102
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17103
      xp = (double *) *xpp;
17104
    }
17105
   /* update xpp and tp */
17106
    xp += ni;
17107
    tp += ni;
17108
    *xpp = (void*)xp;
17109
  }
17110
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17111
17112
#else   /* not SX */
17113
17114
0
  char *xp = (char *) *xpp;
17115
0
  int status = NC_NOERR;
17116
17117
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17118
0
  {
17119
0
    int lstatus = ncx_put_double_schar(xp, tp, fillp);
17120
0
    if (status == NC_NOERR) /* report the first encountered error */
17121
0
      status = lstatus;
17122
0
  }
17123
17124
0
  *xpp = (void *)xp;
17125
0
  return status;
17126
0
#endif
17127
0
}
17128
17129
int
17130
ncx_putn_double_short(void **xpp, size_t nelems, const short *tp, void *fillp)
17131
0
{
17132
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17133
17134
 /* basic algorithm is:
17135
  *   - ensure sane alignment of output data
17136
  *   - copy (conversion happens automatically) input data
17137
  *     to output
17138
  *   - update tp to point at next unconverted input, and xpp to point
17139
  *     at next location for converted output
17140
  */
17141
  long i, j, ni;
17142
  double tmp[LOOPCNT];        /* in case input is misaligned */
17143
  double *xp;
17144
  int nrange = 0;         /* number of range errors */
17145
  int realign = 0;        /* "do we need to fix input data alignment?" */
17146
  long cxp = (long) *((char**)xpp);
17147
17148
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17149
  /* sjl: manually stripmine so we can limit amount of
17150
   * vector work space reserved to LOOPCNT elements. Also
17151
   * makes vectorisation easy */
17152
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17153
    ni=Min(nelems-j,LOOPCNT);
17154
    if (realign) {
17155
      xp = tmp;
17156
    } else {
17157
      xp = (double *) *xpp;
17158
    }
17159
   /* copy the next block */
17160
#pragma cdir loopcnt=LOOPCNT
17161
#pragma cdir shortloop
17162
    for (i=0; i<ni; i++) {
17163
      /* the normal case: */
17164
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17165
     /* test for range errors (not always needed but do it anyway) */
17166
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17167
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17168
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17169
    }
17170
   /* copy workspace back if necessary */
17171
    if (realign) {
17172
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17173
      xp = (double *) *xpp;
17174
    }
17175
   /* update xpp and tp */
17176
    xp += ni;
17177
    tp += ni;
17178
    *xpp = (void*)xp;
17179
  }
17180
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17181
17182
#else   /* not SX */
17183
17184
0
  char *xp = (char *) *xpp;
17185
0
  int status = NC_NOERR;
17186
17187
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17188
0
  {
17189
0
    int lstatus = ncx_put_double_short(xp, tp, fillp);
17190
0
    if (status == NC_NOERR) /* report the first encountered error */
17191
0
      status = lstatus;
17192
0
  }
17193
17194
0
  *xpp = (void *)xp;
17195
0
  return status;
17196
0
#endif
17197
0
}
17198
17199
int
17200
ncx_putn_double_int(void **xpp, size_t nelems, const int *tp, void *fillp)
17201
0
{
17202
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17203
17204
 /* basic algorithm is:
17205
  *   - ensure sane alignment of output data
17206
  *   - copy (conversion happens automatically) input data
17207
  *     to output
17208
  *   - update tp to point at next unconverted input, and xpp to point
17209
  *     at next location for converted output
17210
  */
17211
  long i, j, ni;
17212
  double tmp[LOOPCNT];        /* in case input is misaligned */
17213
  double *xp;
17214
  int nrange = 0;         /* number of range errors */
17215
  int realign = 0;        /* "do we need to fix input data alignment?" */
17216
  long cxp = (long) *((char**)xpp);
17217
17218
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17219
  /* sjl: manually stripmine so we can limit amount of
17220
   * vector work space reserved to LOOPCNT elements. Also
17221
   * makes vectorisation easy */
17222
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17223
    ni=Min(nelems-j,LOOPCNT);
17224
    if (realign) {
17225
      xp = tmp;
17226
    } else {
17227
      xp = (double *) *xpp;
17228
    }
17229
   /* copy the next block */
17230
#pragma cdir loopcnt=LOOPCNT
17231
#pragma cdir shortloop
17232
    for (i=0; i<ni; i++) {
17233
      /* the normal case: */
17234
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17235
     /* test for range errors (not always needed but do it anyway) */
17236
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17237
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17238
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17239
    }
17240
   /* copy workspace back if necessary */
17241
    if (realign) {
17242
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17243
      xp = (double *) *xpp;
17244
    }
17245
   /* update xpp and tp */
17246
    xp += ni;
17247
    tp += ni;
17248
    *xpp = (void*)xp;
17249
  }
17250
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17251
17252
#else   /* not SX */
17253
17254
0
  char *xp = (char *) *xpp;
17255
0
  int status = NC_NOERR;
17256
17257
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17258
0
  {
17259
0
    int lstatus = ncx_put_double_int(xp, tp, fillp);
17260
0
    if (status == NC_NOERR) /* report the first encountered error */
17261
0
      status = lstatus;
17262
0
  }
17263
17264
0
  *xpp = (void *)xp;
17265
0
  return status;
17266
0
#endif
17267
0
}
17268
17269
int
17270
ncx_putn_double_long(void **xpp, size_t nelems, const long *tp, void *fillp)
17271
0
{
17272
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17273
17274
 /* basic algorithm is:
17275
  *   - ensure sane alignment of output data
17276
  *   - copy (conversion happens automatically) input data
17277
  *     to output
17278
  *   - update tp to point at next unconverted input, and xpp to point
17279
  *     at next location for converted output
17280
  */
17281
  long i, j, ni;
17282
  double tmp[LOOPCNT];        /* in case input is misaligned */
17283
  double *xp;
17284
  int nrange = 0;         /* number of range errors */
17285
  int realign = 0;        /* "do we need to fix input data alignment?" */
17286
  long cxp = (long) *((char**)xpp);
17287
17288
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17289
  /* sjl: manually stripmine so we can limit amount of
17290
   * vector work space reserved to LOOPCNT elements. Also
17291
   * makes vectorisation easy */
17292
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17293
    ni=Min(nelems-j,LOOPCNT);
17294
    if (realign) {
17295
      xp = tmp;
17296
    } else {
17297
      xp = (double *) *xpp;
17298
    }
17299
   /* copy the next block */
17300
#pragma cdir loopcnt=LOOPCNT
17301
#pragma cdir shortloop
17302
    for (i=0; i<ni; i++) {
17303
      /* the normal case: */
17304
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17305
     /* test for range errors (not always needed but do it anyway) */
17306
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17307
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17308
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17309
    }
17310
   /* copy workspace back if necessary */
17311
    if (realign) {
17312
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17313
      xp = (double *) *xpp;
17314
    }
17315
   /* update xpp and tp */
17316
    xp += ni;
17317
    tp += ni;
17318
    *xpp = (void*)xp;
17319
  }
17320
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17321
17322
#else   /* not SX */
17323
17324
0
  char *xp = (char *) *xpp;
17325
0
  int status = NC_NOERR;
17326
17327
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17328
0
  {
17329
0
    int lstatus = ncx_put_double_long(xp, tp, fillp);
17330
0
    if (status == NC_NOERR) /* report the first encountered error */
17331
0
      status = lstatus;
17332
0
  }
17333
17334
0
  *xpp = (void *)xp;
17335
0
  return status;
17336
0
#endif
17337
0
}
17338
17339
int
17340
ncx_putn_double_float(void **xpp, size_t nelems, const float *tp, void *fillp)
17341
0
{
17342
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17343
17344
 /* basic algorithm is:
17345
  *   - ensure sane alignment of output data
17346
  *   - copy (conversion happens automatically) input data
17347
  *     to output
17348
  *   - update tp to point at next unconverted input, and xpp to point
17349
  *     at next location for converted output
17350
  */
17351
  long i, j, ni;
17352
  double tmp[LOOPCNT];        /* in case input is misaligned */
17353
  double *xp;
17354
  int nrange = 0;         /* number of range errors */
17355
  int realign = 0;        /* "do we need to fix input data alignment?" */
17356
  long cxp = (long) *((char**)xpp);
17357
17358
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17359
  /* sjl: manually stripmine so we can limit amount of
17360
   * vector work space reserved to LOOPCNT elements. Also
17361
   * makes vectorisation easy */
17362
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17363
    ni=Min(nelems-j,LOOPCNT);
17364
    if (realign) {
17365
      xp = tmp;
17366
    } else {
17367
      xp = (double *) *xpp;
17368
    }
17369
   /* copy the next block */
17370
#pragma cdir loopcnt=LOOPCNT
17371
#pragma cdir shortloop
17372
    for (i=0; i<ni; i++) {
17373
      /* the normal case: */
17374
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17375
     /* test for range errors (not always needed but do it anyway) */
17376
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17377
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17378
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17379
    }
17380
   /* copy workspace back if necessary */
17381
    if (realign) {
17382
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17383
      xp = (double *) *xpp;
17384
    }
17385
   /* update xpp and tp */
17386
    xp += ni;
17387
    tp += ni;
17388
    *xpp = (void*)xp;
17389
  }
17390
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17391
17392
#else   /* not SX */
17393
17394
0
  char *xp = (char *) *xpp;
17395
0
  int status = NC_NOERR;
17396
17397
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17398
0
  {
17399
0
    int lstatus = ncx_put_double_float(xp, tp, fillp);
17400
0
    if (status == NC_NOERR) /* report the first encountered error */
17401
0
      status = lstatus;
17402
0
  }
17403
17404
0
  *xpp = (void *)xp;
17405
0
  return status;
17406
0
#endif
17407
0
}
17408
17409
int
17410
ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
17411
0
{
17412
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17413
17414
 /* basic algorithm is:
17415
  *   - ensure sane alignment of output data
17416
  *   - copy (conversion happens automatically) input data
17417
  *     to output
17418
  *   - update tp to point at next unconverted input, and xpp to point
17419
  *     at next location for converted output
17420
  */
17421
  long i, j, ni;
17422
  double tmp[LOOPCNT];        /* in case input is misaligned */
17423
  double *xp;
17424
  int nrange = 0;         /* number of range errors */
17425
  int realign = 0;        /* "do we need to fix input data alignment?" */
17426
  long cxp = (long) *((char**)xpp);
17427
17428
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17429
  /* sjl: manually stripmine so we can limit amount of
17430
   * vector work space reserved to LOOPCNT elements. Also
17431
   * makes vectorisation easy */
17432
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17433
    ni=Min(nelems-j,LOOPCNT);
17434
    if (realign) {
17435
      xp = tmp;
17436
    } else {
17437
      xp = (double *) *xpp;
17438
    }
17439
   /* copy the next block */
17440
#pragma cdir loopcnt=LOOPCNT
17441
#pragma cdir shortloop
17442
    for (i=0; i<ni; i++) {
17443
      /* the normal case: */
17444
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17445
     /* test for range errors (not always needed but do it anyway) */
17446
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17447
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17448
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17449
    }
17450
   /* copy workspace back if necessary */
17451
    if (realign) {
17452
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17453
      xp = (double *) *xpp;
17454
    }
17455
   /* update xpp and tp */
17456
    xp += ni;
17457
    tp += ni;
17458
    *xpp = (void*)xp;
17459
  }
17460
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17461
17462
#else   /* not SX */
17463
17464
0
  char *xp = (char *) *xpp;
17465
0
  int status = NC_NOERR;
17466
17467
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17468
0
  {
17469
0
    int lstatus = ncx_put_double_longlong(xp, tp, fillp);
17470
0
    if (status == NC_NOERR) /* report the first encountered error */
17471
0
      status = lstatus;
17472
0
  }
17473
17474
0
  *xpp = (void *)xp;
17475
0
  return status;
17476
0
#endif
17477
0
}
17478
17479
int
17480
ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
17481
0
{
17482
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17483
17484
 /* basic algorithm is:
17485
  *   - ensure sane alignment of output data
17486
  *   - copy (conversion happens automatically) input data
17487
  *     to output
17488
  *   - update tp to point at next unconverted input, and xpp to point
17489
  *     at next location for converted output
17490
  */
17491
  long i, j, ni;
17492
  double tmp[LOOPCNT];        /* in case input is misaligned */
17493
  double *xp;
17494
  int nrange = 0;         /* number of range errors */
17495
  int realign = 0;        /* "do we need to fix input data alignment?" */
17496
  long cxp = (long) *((char**)xpp);
17497
17498
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17499
  /* sjl: manually stripmine so we can limit amount of
17500
   * vector work space reserved to LOOPCNT elements. Also
17501
   * makes vectorisation easy */
17502
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17503
    ni=Min(nelems-j,LOOPCNT);
17504
    if (realign) {
17505
      xp = tmp;
17506
    } else {
17507
      xp = (double *) *xpp;
17508
    }
17509
   /* copy the next block */
17510
#pragma cdir loopcnt=LOOPCNT
17511
#pragma cdir shortloop
17512
    for (i=0; i<ni; i++) {
17513
      /* the normal case: */
17514
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17515
     /* test for range errors (not always needed but do it anyway) */
17516
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17517
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17518
      nrange += tp[i] > X_DOUBLE_MAX ;
17519
    }
17520
   /* copy workspace back if necessary */
17521
    if (realign) {
17522
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17523
      xp = (double *) *xpp;
17524
    }
17525
   /* update xpp and tp */
17526
    xp += ni;
17527
    tp += ni;
17528
    *xpp = (void*)xp;
17529
  }
17530
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17531
17532
#else   /* not SX */
17533
17534
0
  char *xp = (char *) *xpp;
17535
0
  int status = NC_NOERR;
17536
17537
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17538
0
  {
17539
0
    int lstatus = ncx_put_double_uchar(xp, tp, fillp);
17540
0
    if (status == NC_NOERR) /* report the first encountered error */
17541
0
      status = lstatus;
17542
0
  }
17543
17544
0
  *xpp = (void *)xp;
17545
0
  return status;
17546
0
#endif
17547
0
}
17548
17549
int
17550
ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
17551
0
{
17552
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17553
17554
 /* basic algorithm is:
17555
  *   - ensure sane alignment of output data
17556
  *   - copy (conversion happens automatically) input data
17557
  *     to output
17558
  *   - update tp to point at next unconverted input, and xpp to point
17559
  *     at next location for converted output
17560
  */
17561
  long i, j, ni;
17562
  double tmp[LOOPCNT];        /* in case input is misaligned */
17563
  double *xp;
17564
  int nrange = 0;         /* number of range errors */
17565
  int realign = 0;        /* "do we need to fix input data alignment?" */
17566
  long cxp = (long) *((char**)xpp);
17567
17568
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17569
  /* sjl: manually stripmine so we can limit amount of
17570
   * vector work space reserved to LOOPCNT elements. Also
17571
   * makes vectorisation easy */
17572
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17573
    ni=Min(nelems-j,LOOPCNT);
17574
    if (realign) {
17575
      xp = tmp;
17576
    } else {
17577
      xp = (double *) *xpp;
17578
    }
17579
   /* copy the next block */
17580
#pragma cdir loopcnt=LOOPCNT
17581
#pragma cdir shortloop
17582
    for (i=0; i<ni; i++) {
17583
      /* the normal case: */
17584
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17585
     /* test for range errors (not always needed but do it anyway) */
17586
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17587
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17588
      nrange += tp[i] > X_DOUBLE_MAX ;
17589
    }
17590
   /* copy workspace back if necessary */
17591
    if (realign) {
17592
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17593
      xp = (double *) *xpp;
17594
    }
17595
   /* update xpp and tp */
17596
    xp += ni;
17597
    tp += ni;
17598
    *xpp = (void*)xp;
17599
  }
17600
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17601
17602
#else   /* not SX */
17603
17604
0
  char *xp = (char *) *xpp;
17605
0
  int status = NC_NOERR;
17606
17607
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17608
0
  {
17609
0
    int lstatus = ncx_put_double_ushort(xp, tp, fillp);
17610
0
    if (status == NC_NOERR) /* report the first encountered error */
17611
0
      status = lstatus;
17612
0
  }
17613
17614
0
  *xpp = (void *)xp;
17615
0
  return status;
17616
0
#endif
17617
0
}
17618
17619
int
17620
ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
17621
0
{
17622
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17623
17624
 /* basic algorithm is:
17625
  *   - ensure sane alignment of output data
17626
  *   - copy (conversion happens automatically) input data
17627
  *     to output
17628
  *   - update tp to point at next unconverted input, and xpp to point
17629
  *     at next location for converted output
17630
  */
17631
  long i, j, ni;
17632
  double tmp[LOOPCNT];        /* in case input is misaligned */
17633
  double *xp;
17634
  int nrange = 0;         /* number of range errors */
17635
  int realign = 0;        /* "do we need to fix input data alignment?" */
17636
  long cxp = (long) *((char**)xpp);
17637
17638
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17639
  /* sjl: manually stripmine so we can limit amount of
17640
   * vector work space reserved to LOOPCNT elements. Also
17641
   * makes vectorisation easy */
17642
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17643
    ni=Min(nelems-j,LOOPCNT);
17644
    if (realign) {
17645
      xp = tmp;
17646
    } else {
17647
      xp = (double *) *xpp;
17648
    }
17649
   /* copy the next block */
17650
#pragma cdir loopcnt=LOOPCNT
17651
#pragma cdir shortloop
17652
    for (i=0; i<ni; i++) {
17653
      /* the normal case: */
17654
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17655
     /* test for range errors (not always needed but do it anyway) */
17656
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17657
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17658
      nrange += tp[i] > X_DOUBLE_MAX ;
17659
    }
17660
   /* copy workspace back if necessary */
17661
    if (realign) {
17662
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17663
      xp = (double *) *xpp;
17664
    }
17665
   /* update xpp and tp */
17666
    xp += ni;
17667
    tp += ni;
17668
    *xpp = (void*)xp;
17669
  }
17670
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17671
17672
#else   /* not SX */
17673
17674
0
  char *xp = (char *) *xpp;
17675
0
  int status = NC_NOERR;
17676
17677
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17678
0
  {
17679
0
    int lstatus = ncx_put_double_uint(xp, tp, fillp);
17680
0
    if (status == NC_NOERR) /* report the first encountered error */
17681
0
      status = lstatus;
17682
0
  }
17683
17684
0
  *xpp = (void *)xp;
17685
0
  return status;
17686
0
#endif
17687
0
}
17688
17689
int
17690
ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
17691
0
{
17692
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17693
17694
 /* basic algorithm is:
17695
  *   - ensure sane alignment of output data
17696
  *   - copy (conversion happens automatically) input data
17697
  *     to output
17698
  *   - update tp to point at next unconverted input, and xpp to point
17699
  *     at next location for converted output
17700
  */
17701
  long i, j, ni;
17702
  double tmp[LOOPCNT];        /* in case input is misaligned */
17703
  double *xp;
17704
  int nrange = 0;         /* number of range errors */
17705
  int realign = 0;        /* "do we need to fix input data alignment?" */
17706
  long cxp = (long) *((char**)xpp);
17707
17708
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17709
  /* sjl: manually stripmine so we can limit amount of
17710
   * vector work space reserved to LOOPCNT elements. Also
17711
   * makes vectorisation easy */
17712
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17713
    ni=Min(nelems-j,LOOPCNT);
17714
    if (realign) {
17715
      xp = tmp;
17716
    } else {
17717
      xp = (double *) *xpp;
17718
    }
17719
   /* copy the next block */
17720
#pragma cdir loopcnt=LOOPCNT
17721
#pragma cdir shortloop
17722
    for (i=0; i<ni; i++) {
17723
      /* the normal case: */
17724
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17725
     /* test for range errors (not always needed but do it anyway) */
17726
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17727
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17728
      nrange += tp[i] > X_DOUBLE_MAX ;
17729
    }
17730
   /* copy workspace back if necessary */
17731
    if (realign) {
17732
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17733
      xp = (double *) *xpp;
17734
    }
17735
   /* update xpp and tp */
17736
    xp += ni;
17737
    tp += ni;
17738
    *xpp = (void*)xp;
17739
  }
17740
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17741
17742
#else   /* not SX */
17743
17744
0
  char *xp = (char *) *xpp;
17745
0
  int status = NC_NOERR;
17746
17747
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17748
0
  {
17749
0
    int lstatus = ncx_put_double_ulonglong(xp, tp, fillp);
17750
0
    if (status == NC_NOERR) /* report the first encountered error */
17751
0
      status = lstatus;
17752
0
  }
17753
17754
0
  *xpp = (void *)xp;
17755
0
  return status;
17756
0
#endif
17757
0
}
17758
17759
17760
17761
/* longlong ------------------------------------------------------------------*/
17762
17763
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
17764
/* optimized version */
17765
int
17766
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
17767
0
{
17768
#ifdef WORDS_BIGENDIAN
17769
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
17770
# else
17771
0
  swapn8b(tp, *xpp, nelems);
17772
0
# endif
17773
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
17774
0
  return NC_NOERR;
17775
0
}
17776
#else
17777
int
17778
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, longlong *tp)
17779
{
17780
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17781
17782
 /* basic algorithm is:
17783
  *   - ensure sane alignment of input data
17784
  *   - copy (conversion happens automatically) input data
17785
  *     to output
17786
  *   - update xpp to point at next unconverted input, and tp to point
17787
  *     at next location for converted output
17788
  */
17789
  long i, j, ni;
17790
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17791
  int64 *xp;
17792
  int nrange = 0;         /* number of range errors */
17793
  int realign = 0;        /* "do we need to fix input data alignment?" */
17794
  long cxp = (long) *((char**)xpp);
17795
17796
  realign = (cxp & 7) % SIZEOF_INT64;
17797
  /* sjl: manually stripmine so we can limit amount of
17798
   * vector work space reserved to LOOPCNT elements. Also
17799
   * makes vectorisation easy */
17800
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17801
    ni=Min(nelems-j,LOOPCNT);
17802
    if (realign) {
17803
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17804
      xp = tmp;
17805
    } else {
17806
      xp = (int64 *) *xpp;
17807
    }
17808
   /* copy the next block */
17809
#pragma cdir loopcnt=LOOPCNT
17810
#pragma cdir shortloop
17811
    for (i=0; i<ni; i++) {
17812
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
17813
     /* test for range errors (not always needed but do it anyway) */
17814
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17815
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17816
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
17817
    }
17818
   /* update xpp and tp */
17819
    if (realign) xp = (int64 *) *xpp;
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
  const char *xp = (const char *) *xpp;
17828
  int status = NC_NOERR;
17829
17830
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
17831
  {
17832
    const int lstatus = ncx_get_longlong_longlong(xp, tp);
17833
    if (status == NC_NOERR) /* report the first encountered error */
17834
      status = lstatus;
17835
  }
17836
17837
  *xpp = (const void *)xp;
17838
  return status;
17839
#endif
17840
}
17841
17842
#endif
17843
int
17844
ncx_getn_longlong_schar(const void **xpp, size_t nelems, schar *tp)
17845
0
{
17846
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17847
17848
 /* basic algorithm is:
17849
  *   - ensure sane alignment of input data
17850
  *   - copy (conversion happens automatically) input data
17851
  *     to output
17852
  *   - update xpp to point at next unconverted input, and tp to point
17853
  *     at next location for converted output
17854
  */
17855
  long i, j, ni;
17856
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17857
  int64 *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_INT64;
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
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17870
      xp = tmp;
17871
    } else {
17872
      xp = (int64 *) *xpp;
17873
    }
17874
   /* copy the next block */
17875
#pragma cdir loopcnt=LOOPCNT
17876
#pragma cdir shortloop
17877
    for (i=0; i<ni; i++) {
17878
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
17879
     /* test for range errors (not always needed but do it anyway) */
17880
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17881
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17882
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
17883
    }
17884
   /* update xpp and tp */
17885
    if (realign) xp = (int64 *) *xpp;
17886
    xp += ni;
17887
    tp += ni;
17888
    *xpp = (void*)xp;
17889
  }
17890
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17891
17892
#else   /* not SX */
17893
0
  const char *xp = (const char *) *xpp;
17894
0
  int status = NC_NOERR;
17895
17896
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
17897
0
  {
17898
0
    const int lstatus = ncx_get_longlong_schar(xp, tp);
17899
0
    if (status == NC_NOERR) /* report the first encountered error */
17900
0
      status = lstatus;
17901
0
  }
17902
17903
0
  *xpp = (const void *)xp;
17904
0
  return status;
17905
0
#endif
17906
0
}
17907
17908
int
17909
ncx_getn_longlong_short(const void **xpp, size_t nelems, short *tp)
17910
0
{
17911
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17912
17913
 /* basic algorithm is:
17914
  *   - ensure sane alignment of input data
17915
  *   - copy (conversion happens automatically) input data
17916
  *     to output
17917
  *   - update xpp to point at next unconverted input, and tp to point
17918
  *     at next location for converted output
17919
  */
17920
  long i, j, ni;
17921
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17922
  int64 *xp;
17923
  int nrange = 0;         /* number of range errors */
17924
  int realign = 0;        /* "do we need to fix input data alignment?" */
17925
  long cxp = (long) *((char**)xpp);
17926
17927
  realign = (cxp & 7) % SIZEOF_INT64;
17928
  /* sjl: manually stripmine so we can limit amount of
17929
   * vector work space reserved to LOOPCNT elements. Also
17930
   * makes vectorisation easy */
17931
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17932
    ni=Min(nelems-j,LOOPCNT);
17933
    if (realign) {
17934
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17935
      xp = tmp;
17936
    } else {
17937
      xp = (int64 *) *xpp;
17938
    }
17939
   /* copy the next block */
17940
#pragma cdir loopcnt=LOOPCNT
17941
#pragma cdir shortloop
17942
    for (i=0; i<ni; i++) {
17943
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
17944
     /* test for range errors (not always needed but do it anyway) */
17945
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17946
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17947
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
17948
    }
17949
   /* update xpp and tp */
17950
    if (realign) xp = (int64 *) *xpp;
17951
    xp += ni;
17952
    tp += ni;
17953
    *xpp = (void*)xp;
17954
  }
17955
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17956
17957
#else   /* not SX */
17958
0
  const char *xp = (const char *) *xpp;
17959
0
  int status = NC_NOERR;
17960
17961
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
17962
0
  {
17963
0
    const int lstatus = ncx_get_longlong_short(xp, tp);
17964
0
    if (status == NC_NOERR) /* report the first encountered error */
17965
0
      status = lstatus;
17966
0
  }
17967
17968
0
  *xpp = (const void *)xp;
17969
0
  return status;
17970
0
#endif
17971
0
}
17972
17973
int
17974
ncx_getn_longlong_int(const void **xpp, size_t nelems, int *tp)
17975
0
{
17976
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17977
17978
 /* basic algorithm is:
17979
  *   - ensure sane alignment of input data
17980
  *   - copy (conversion happens automatically) input data
17981
  *     to output
17982
  *   - update xpp to point at next unconverted input, and tp to point
17983
  *     at next location for converted output
17984
  */
17985
  long i, j, ni;
17986
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17987
  int64 *xp;
17988
  int nrange = 0;         /* number of range errors */
17989
  int realign = 0;        /* "do we need to fix input data alignment?" */
17990
  long cxp = (long) *((char**)xpp);
17991
17992
  realign = (cxp & 7) % SIZEOF_INT64;
17993
  /* sjl: manually stripmine so we can limit amount of
17994
   * vector work space reserved to LOOPCNT elements. Also
17995
   * makes vectorisation easy */
17996
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17997
    ni=Min(nelems-j,LOOPCNT);
17998
    if (realign) {
17999
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18000
      xp = tmp;
18001
    } else {
18002
      xp = (int64 *) *xpp;
18003
    }
18004
   /* copy the next block */
18005
#pragma cdir loopcnt=LOOPCNT
18006
#pragma cdir shortloop
18007
    for (i=0; i<ni; i++) {
18008
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
18009
     /* test for range errors (not always needed but do it anyway) */
18010
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18011
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18012
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
18013
    }
18014
   /* update xpp and tp */
18015
    if (realign) xp = (int64 *) *xpp;
18016
    xp += ni;
18017
    tp += ni;
18018
    *xpp = (void*)xp;
18019
  }
18020
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18021
18022
#else   /* not SX */
18023
0
  const char *xp = (const char *) *xpp;
18024
0
  int status = NC_NOERR;
18025
18026
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18027
0
  {
18028
0
    const int lstatus = ncx_get_longlong_int(xp, tp);
18029
0
    if (status == NC_NOERR) /* report the first encountered error */
18030
0
      status = lstatus;
18031
0
  }
18032
18033
0
  *xpp = (const void *)xp;
18034
0
  return status;
18035
0
#endif
18036
0
}
18037
18038
int
18039
ncx_getn_longlong_long(const void **xpp, size_t nelems, long *tp)
18040
0
{
18041
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18042
18043
 /* basic algorithm is:
18044
  *   - ensure sane alignment of input data
18045
  *   - copy (conversion happens automatically) input data
18046
  *     to output
18047
  *   - update xpp to point at next unconverted input, and tp to point
18048
  *     at next location for converted output
18049
  */
18050
  long i, j, ni;
18051
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18052
  int64 *xp;
18053
  int nrange = 0;         /* number of range errors */
18054
  int realign = 0;        /* "do we need to fix input data alignment?" */
18055
  long cxp = (long) *((char**)xpp);
18056
18057
  realign = (cxp & 7) % SIZEOF_INT64;
18058
  /* sjl: manually stripmine so we can limit amount of
18059
   * vector work space reserved to LOOPCNT elements. Also
18060
   * makes vectorisation easy */
18061
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18062
    ni=Min(nelems-j,LOOPCNT);
18063
    if (realign) {
18064
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18065
      xp = tmp;
18066
    } else {
18067
      xp = (int64 *) *xpp;
18068
    }
18069
   /* copy the next block */
18070
#pragma cdir loopcnt=LOOPCNT
18071
#pragma cdir shortloop
18072
    for (i=0; i<ni; i++) {
18073
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
18074
     /* test for range errors (not always needed but do it anyway) */
18075
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18076
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18077
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
18078
    }
18079
   /* update xpp and tp */
18080
    if (realign) xp = (int64 *) *xpp;
18081
    xp += ni;
18082
    tp += ni;
18083
    *xpp = (void*)xp;
18084
  }
18085
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18086
18087
#else   /* not SX */
18088
0
  const char *xp = (const char *) *xpp;
18089
0
  int status = NC_NOERR;
18090
18091
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18092
0
  {
18093
0
    const int lstatus = ncx_get_longlong_long(xp, tp);
18094
0
    if (status == NC_NOERR) /* report the first encountered error */
18095
0
      status = lstatus;
18096
0
  }
18097
18098
0
  *xpp = (const void *)xp;
18099
0
  return status;
18100
0
#endif
18101
0
}
18102
18103
int
18104
ncx_getn_longlong_float(const void **xpp, size_t nelems, float *tp)
18105
0
{
18106
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18107
18108
 /* basic algorithm is:
18109
  *   - ensure sane alignment of input data
18110
  *   - copy (conversion happens automatically) input data
18111
  *     to output
18112
  *   - update xpp to point at next unconverted input, and tp to point
18113
  *     at next location for converted output
18114
  */
18115
  long i, j, ni;
18116
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18117
  int64 *xp;
18118
  int nrange = 0;         /* number of range errors */
18119
  int realign = 0;        /* "do we need to fix input data alignment?" */
18120
  long cxp = (long) *((char**)xpp);
18121
18122
  realign = (cxp & 7) % SIZEOF_INT64;
18123
  /* sjl: manually stripmine so we can limit amount of
18124
   * vector work space reserved to LOOPCNT elements. Also
18125
   * makes vectorisation easy */
18126
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18127
    ni=Min(nelems-j,LOOPCNT);
18128
    if (realign) {
18129
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18130
      xp = tmp;
18131
    } else {
18132
      xp = (int64 *) *xpp;
18133
    }
18134
   /* copy the next block */
18135
#pragma cdir loopcnt=LOOPCNT
18136
#pragma cdir shortloop
18137
    for (i=0; i<ni; i++) {
18138
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
18139
     /* test for range errors (not always needed but do it anyway) */
18140
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18141
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18142
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
18143
    }
18144
   /* update xpp and tp */
18145
    if (realign) xp = (int64 *) *xpp;
18146
    xp += ni;
18147
    tp += ni;
18148
    *xpp = (void*)xp;
18149
  }
18150
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18151
18152
#else   /* not SX */
18153
0
  const char *xp = (const char *) *xpp;
18154
0
  int status = NC_NOERR;
18155
18156
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18157
0
  {
18158
0
    const int lstatus = ncx_get_longlong_float(xp, tp);
18159
0
    if (status == NC_NOERR) /* report the first encountered error */
18160
0
      status = lstatus;
18161
0
  }
18162
18163
0
  *xpp = (const void *)xp;
18164
0
  return status;
18165
0
#endif
18166
0
}
18167
18168
int
18169
ncx_getn_longlong_double(const void **xpp, size_t nelems, double *tp)
18170
0
{
18171
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18172
18173
 /* basic algorithm is:
18174
  *   - ensure sane alignment of input data
18175
  *   - copy (conversion happens automatically) input data
18176
  *     to output
18177
  *   - update xpp to point at next unconverted input, and tp to point
18178
  *     at next location for converted output
18179
  */
18180
  long i, j, ni;
18181
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18182
  int64 *xp;
18183
  int nrange = 0;         /* number of range errors */
18184
  int realign = 0;        /* "do we need to fix input data alignment?" */
18185
  long cxp = (long) *((char**)xpp);
18186
18187
  realign = (cxp & 7) % SIZEOF_INT64;
18188
  /* sjl: manually stripmine so we can limit amount of
18189
   * vector work space reserved to LOOPCNT elements. Also
18190
   * makes vectorisation easy */
18191
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18192
    ni=Min(nelems-j,LOOPCNT);
18193
    if (realign) {
18194
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18195
      xp = tmp;
18196
    } else {
18197
      xp = (int64 *) *xpp;
18198
    }
18199
   /* copy the next block */
18200
#pragma cdir loopcnt=LOOPCNT
18201
#pragma cdir shortloop
18202
    for (i=0; i<ni; i++) {
18203
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
18204
     /* test for range errors (not always needed but do it anyway) */
18205
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18206
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18207
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
18208
    }
18209
   /* update xpp and tp */
18210
    if (realign) xp = (int64 *) *xpp;
18211
    xp += ni;
18212
    tp += ni;
18213
    *xpp = (void*)xp;
18214
  }
18215
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18216
18217
#else   /* not SX */
18218
0
  const char *xp = (const char *) *xpp;
18219
0
  int status = NC_NOERR;
18220
18221
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18222
0
  {
18223
0
    const int lstatus = ncx_get_longlong_double(xp, tp);
18224
0
    if (status == NC_NOERR) /* report the first encountered error */
18225
0
      status = lstatus;
18226
0
  }
18227
18228
0
  *xpp = (const void *)xp;
18229
0
  return status;
18230
0
#endif
18231
0
}
18232
18233
int
18234
ncx_getn_longlong_uchar(const void **xpp, size_t nelems, uchar *tp)
18235
0
{
18236
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18237
18238
 /* basic algorithm is:
18239
  *   - ensure sane alignment of input data
18240
  *   - copy (conversion happens automatically) input data
18241
  *     to output
18242
  *   - update xpp to point at next unconverted input, and tp to point
18243
  *     at next location for converted output
18244
  */
18245
  long i, j, ni;
18246
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18247
  int64 *xp;
18248
  int nrange = 0;         /* number of range errors */
18249
  int realign = 0;        /* "do we need to fix input data alignment?" */
18250
  long cxp = (long) *((char**)xpp);
18251
18252
  realign = (cxp & 7) % SIZEOF_INT64;
18253
  /* sjl: manually stripmine so we can limit amount of
18254
   * vector work space reserved to LOOPCNT elements. Also
18255
   * makes vectorisation easy */
18256
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18257
    ni=Min(nelems-j,LOOPCNT);
18258
    if (realign) {
18259
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18260
      xp = tmp;
18261
    } else {
18262
      xp = (int64 *) *xpp;
18263
    }
18264
   /* copy the next block */
18265
#pragma cdir loopcnt=LOOPCNT
18266
#pragma cdir shortloop
18267
    for (i=0; i<ni; i++) {
18268
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
18269
     /* test for range errors (not always needed but do it anyway) */
18270
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18271
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18272
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
18273
    }
18274
   /* update xpp and tp */
18275
    if (realign) xp = (int64 *) *xpp;
18276
    xp += ni;
18277
    tp += ni;
18278
    *xpp = (void*)xp;
18279
  }
18280
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18281
18282
#else   /* not SX */
18283
0
  const char *xp = (const char *) *xpp;
18284
0
  int status = NC_NOERR;
18285
18286
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18287
0
  {
18288
0
    const int lstatus = ncx_get_longlong_uchar(xp, tp);
18289
0
    if (status == NC_NOERR) /* report the first encountered error */
18290
0
      status = lstatus;
18291
0
  }
18292
18293
0
  *xpp = (const void *)xp;
18294
0
  return status;
18295
0
#endif
18296
0
}
18297
18298
int
18299
ncx_getn_longlong_ushort(const void **xpp, size_t nelems, ushort *tp)
18300
0
{
18301
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18302
18303
 /* basic algorithm is:
18304
  *   - ensure sane alignment of input data
18305
  *   - copy (conversion happens automatically) input data
18306
  *     to output
18307
  *   - update xpp to point at next unconverted input, and tp to point
18308
  *     at next location for converted output
18309
  */
18310
  long i, j, ni;
18311
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18312
  int64 *xp;
18313
  int nrange = 0;         /* number of range errors */
18314
  int realign = 0;        /* "do we need to fix input data alignment?" */
18315
  long cxp = (long) *((char**)xpp);
18316
18317
  realign = (cxp & 7) % SIZEOF_INT64;
18318
  /* sjl: manually stripmine so we can limit amount of
18319
   * vector work space reserved to LOOPCNT elements. Also
18320
   * makes vectorisation easy */
18321
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18322
    ni=Min(nelems-j,LOOPCNT);
18323
    if (realign) {
18324
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18325
      xp = tmp;
18326
    } else {
18327
      xp = (int64 *) *xpp;
18328
    }
18329
   /* copy the next block */
18330
#pragma cdir loopcnt=LOOPCNT
18331
#pragma cdir shortloop
18332
    for (i=0; i<ni; i++) {
18333
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
18334
     /* test for range errors (not always needed but do it anyway) */
18335
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18336
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18337
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
18338
    }
18339
   /* update xpp and tp */
18340
    if (realign) xp = (int64 *) *xpp;
18341
    xp += ni;
18342
    tp += ni;
18343
    *xpp = (void*)xp;
18344
  }
18345
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18346
18347
#else   /* not SX */
18348
0
  const char *xp = (const char *) *xpp;
18349
0
  int status = NC_NOERR;
18350
18351
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18352
0
  {
18353
0
    const int lstatus = ncx_get_longlong_ushort(xp, tp);
18354
0
    if (status == NC_NOERR) /* report the first encountered error */
18355
0
      status = lstatus;
18356
0
  }
18357
18358
0
  *xpp = (const void *)xp;
18359
0
  return status;
18360
0
#endif
18361
0
}
18362
18363
int
18364
ncx_getn_longlong_uint(const void **xpp, size_t nelems, uint *tp)
18365
0
{
18366
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18367
18368
 /* basic algorithm is:
18369
  *   - ensure sane alignment of input data
18370
  *   - copy (conversion happens automatically) input data
18371
  *     to output
18372
  *   - update xpp to point at next unconverted input, and tp to point
18373
  *     at next location for converted output
18374
  */
18375
  long i, j, ni;
18376
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18377
  int64 *xp;
18378
  int nrange = 0;         /* number of range errors */
18379
  int realign = 0;        /* "do we need to fix input data alignment?" */
18380
  long cxp = (long) *((char**)xpp);
18381
18382
  realign = (cxp & 7) % SIZEOF_INT64;
18383
  /* sjl: manually stripmine so we can limit amount of
18384
   * vector work space reserved to LOOPCNT elements. Also
18385
   * makes vectorisation easy */
18386
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18387
    ni=Min(nelems-j,LOOPCNT);
18388
    if (realign) {
18389
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18390
      xp = tmp;
18391
    } else {
18392
      xp = (int64 *) *xpp;
18393
    }
18394
   /* copy the next block */
18395
#pragma cdir loopcnt=LOOPCNT
18396
#pragma cdir shortloop
18397
    for (i=0; i<ni; i++) {
18398
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
18399
     /* test for range errors (not always needed but do it anyway) */
18400
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18401
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18402
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
18403
    }
18404
   /* update xpp and tp */
18405
    if (realign) xp = (int64 *) *xpp;
18406
    xp += ni;
18407
    tp += ni;
18408
    *xpp = (void*)xp;
18409
  }
18410
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18411
18412
#else   /* not SX */
18413
0
  const char *xp = (const char *) *xpp;
18414
0
  int status = NC_NOERR;
18415
18416
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18417
0
  {
18418
0
    const int lstatus = ncx_get_longlong_uint(xp, tp);
18419
0
    if (status == NC_NOERR) /* report the first encountered error */
18420
0
      status = lstatus;
18421
0
  }
18422
18423
0
  *xpp = (const void *)xp;
18424
0
  return status;
18425
0
#endif
18426
0
}
18427
18428
int
18429
ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
18430
0
{
18431
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18432
18433
 /* basic algorithm is:
18434
  *   - ensure sane alignment of input data
18435
  *   - copy (conversion happens automatically) input data
18436
  *     to output
18437
  *   - update xpp to point at next unconverted input, and tp to point
18438
  *     at next location for converted output
18439
  */
18440
  long i, j, ni;
18441
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18442
  int64 *xp;
18443
  int nrange = 0;         /* number of range errors */
18444
  int realign = 0;        /* "do we need to fix input data alignment?" */
18445
  long cxp = (long) *((char**)xpp);
18446
18447
  realign = (cxp & 7) % SIZEOF_INT64;
18448
  /* sjl: manually stripmine so we can limit amount of
18449
   * vector work space reserved to LOOPCNT elements. Also
18450
   * makes vectorisation easy */
18451
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18452
    ni=Min(nelems-j,LOOPCNT);
18453
    if (realign) {
18454
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18455
      xp = tmp;
18456
    } else {
18457
      xp = (int64 *) *xpp;
18458
    }
18459
   /* copy the next block */
18460
#pragma cdir loopcnt=LOOPCNT
18461
#pragma cdir shortloop
18462
    for (i=0; i<ni; i++) {
18463
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
18464
     /* test for range errors (not always needed but do it anyway) */
18465
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18466
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18467
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
18468
    }
18469
   /* update xpp and tp */
18470
    if (realign) xp = (int64 *) *xpp;
18471
    xp += ni;
18472
    tp += ni;
18473
    *xpp = (void*)xp;
18474
  }
18475
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18476
18477
#else   /* not SX */
18478
0
  const char *xp = (const char *) *xpp;
18479
0
  int status = NC_NOERR;
18480
18481
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18482
0
  {
18483
0
    const int lstatus = ncx_get_longlong_ulonglong(xp, tp);
18484
0
    if (status == NC_NOERR) /* report the first encountered error */
18485
0
      status = lstatus;
18486
0
  }
18487
18488
0
  *xpp = (const void *)xp;
18489
0
  return status;
18490
0
#endif
18491
0
}
18492
18493
18494
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
18495
/* optimized version */
18496
int
18497
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp, void *fillp)
18498
0
{
18499
#ifdef WORDS_BIGENDIAN
18500
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
18501
# else
18502
0
  swapn8b(*xpp, tp, nelems);
18503
0
# endif
18504
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
18505
0
  return NC_NOERR;
18506
0
}
18507
#else
18508
int
18509
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
18510
{
18511
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18512
18513
 /* basic algorithm is:
18514
  *   - ensure sane alignment of output data
18515
  *   - copy (conversion happens automatically) input data
18516
  *     to output
18517
  *   - update tp to point at next unconverted input, and xpp to point
18518
  *     at next location for converted output
18519
  */
18520
  long i, j, ni;
18521
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18522
  int64 *xp;
18523
  int nrange = 0;         /* number of range errors */
18524
  int realign = 0;        /* "do we need to fix input data alignment?" */
18525
  long cxp = (long) *((char**)xpp);
18526
18527
  realign = (cxp & 7) % SIZEOF_INT64;
18528
  /* sjl: manually stripmine so we can limit amount of
18529
   * vector work space reserved to LOOPCNT elements. Also
18530
   * makes vectorisation easy */
18531
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18532
    ni=Min(nelems-j,LOOPCNT);
18533
    if (realign) {
18534
      xp = tmp;
18535
    } else {
18536
      xp = (int64 *) *xpp;
18537
    }
18538
   /* copy the next block */
18539
#pragma cdir loopcnt=LOOPCNT
18540
#pragma cdir shortloop
18541
    for (i=0; i<ni; i++) {
18542
      /* the normal case: */
18543
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18544
     /* test for range errors (not always needed but do it anyway) */
18545
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18546
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18547
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18548
    }
18549
   /* copy workspace back if necessary */
18550
    if (realign) {
18551
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18552
      xp = (int64 *) *xpp;
18553
    }
18554
   /* update xpp and tp */
18555
    xp += ni;
18556
    tp += ni;
18557
    *xpp = (void*)xp;
18558
  }
18559
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18560
18561
#else   /* not SX */
18562
18563
  char *xp = (char *) *xpp;
18564
  int status = NC_NOERR;
18565
18566
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18567
  {
18568
    int lstatus = ncx_put_longlong_longlong(xp, tp, fillp);
18569
    if (status == NC_NOERR) /* report the first encountered error */
18570
      status = lstatus;
18571
  }
18572
18573
  *xpp = (void *)xp;
18574
  return status;
18575
#endif
18576
}
18577
18578
#endif
18579
int
18580
ncx_putn_longlong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
18581
0
{
18582
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18583
18584
 /* basic algorithm is:
18585
  *   - ensure sane alignment of output data
18586
  *   - copy (conversion happens automatically) input data
18587
  *     to output
18588
  *   - update tp to point at next unconverted input, and xpp to point
18589
  *     at next location for converted output
18590
  */
18591
  long i, j, ni;
18592
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18593
  int64 *xp;
18594
  int nrange = 0;         /* number of range errors */
18595
  int realign = 0;        /* "do we need to fix input data alignment?" */
18596
  long cxp = (long) *((char**)xpp);
18597
18598
  realign = (cxp & 7) % SIZEOF_INT64;
18599
  /* sjl: manually stripmine so we can limit amount of
18600
   * vector work space reserved to LOOPCNT elements. Also
18601
   * makes vectorisation easy */
18602
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18603
    ni=Min(nelems-j,LOOPCNT);
18604
    if (realign) {
18605
      xp = tmp;
18606
    } else {
18607
      xp = (int64 *) *xpp;
18608
    }
18609
   /* copy the next block */
18610
#pragma cdir loopcnt=LOOPCNT
18611
#pragma cdir shortloop
18612
    for (i=0; i<ni; i++) {
18613
      /* the normal case: */
18614
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18615
     /* test for range errors (not always needed but do it anyway) */
18616
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18617
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18618
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18619
    }
18620
   /* copy workspace back if necessary */
18621
    if (realign) {
18622
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18623
      xp = (int64 *) *xpp;
18624
    }
18625
   /* update xpp and tp */
18626
    xp += ni;
18627
    tp += ni;
18628
    *xpp = (void*)xp;
18629
  }
18630
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18631
18632
#else   /* not SX */
18633
18634
0
  char *xp = (char *) *xpp;
18635
0
  int status = NC_NOERR;
18636
18637
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18638
0
  {
18639
0
    int lstatus = ncx_put_longlong_schar(xp, tp, fillp);
18640
0
    if (status == NC_NOERR) /* report the first encountered error */
18641
0
      status = lstatus;
18642
0
  }
18643
18644
0
  *xpp = (void *)xp;
18645
0
  return status;
18646
0
#endif
18647
0
}
18648
18649
int
18650
ncx_putn_longlong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
18651
0
{
18652
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18653
18654
 /* basic algorithm is:
18655
  *   - ensure sane alignment of output data
18656
  *   - copy (conversion happens automatically) input data
18657
  *     to output
18658
  *   - update tp to point at next unconverted input, and xpp to point
18659
  *     at next location for converted output
18660
  */
18661
  long i, j, ni;
18662
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18663
  int64 *xp;
18664
  int nrange = 0;         /* number of range errors */
18665
  int realign = 0;        /* "do we need to fix input data alignment?" */
18666
  long cxp = (long) *((char**)xpp);
18667
18668
  realign = (cxp & 7) % SIZEOF_INT64;
18669
  /* sjl: manually stripmine so we can limit amount of
18670
   * vector work space reserved to LOOPCNT elements. Also
18671
   * makes vectorisation easy */
18672
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18673
    ni=Min(nelems-j,LOOPCNT);
18674
    if (realign) {
18675
      xp = tmp;
18676
    } else {
18677
      xp = (int64 *) *xpp;
18678
    }
18679
   /* copy the next block */
18680
#pragma cdir loopcnt=LOOPCNT
18681
#pragma cdir shortloop
18682
    for (i=0; i<ni; i++) {
18683
      /* the normal case: */
18684
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18685
     /* test for range errors (not always needed but do it anyway) */
18686
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18687
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18688
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18689
    }
18690
   /* copy workspace back if necessary */
18691
    if (realign) {
18692
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18693
      xp = (int64 *) *xpp;
18694
    }
18695
   /* update xpp and tp */
18696
    xp += ni;
18697
    tp += ni;
18698
    *xpp = (void*)xp;
18699
  }
18700
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18701
18702
#else   /* not SX */
18703
18704
0
  char *xp = (char *) *xpp;
18705
0
  int status = NC_NOERR;
18706
18707
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18708
0
  {
18709
0
    int lstatus = ncx_put_longlong_short(xp, tp, fillp);
18710
0
    if (status == NC_NOERR) /* report the first encountered error */
18711
0
      status = lstatus;
18712
0
  }
18713
18714
0
  *xpp = (void *)xp;
18715
0
  return status;
18716
0
#endif
18717
0
}
18718
18719
int
18720
ncx_putn_longlong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
18721
0
{
18722
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18723
18724
 /* basic algorithm is:
18725
  *   - ensure sane alignment of output data
18726
  *   - copy (conversion happens automatically) input data
18727
  *     to output
18728
  *   - update tp to point at next unconverted input, and xpp to point
18729
  *     at next location for converted output
18730
  */
18731
  long i, j, ni;
18732
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18733
  int64 *xp;
18734
  int nrange = 0;         /* number of range errors */
18735
  int realign = 0;        /* "do we need to fix input data alignment?" */
18736
  long cxp = (long) *((char**)xpp);
18737
18738
  realign = (cxp & 7) % SIZEOF_INT64;
18739
  /* sjl: manually stripmine so we can limit amount of
18740
   * vector work space reserved to LOOPCNT elements. Also
18741
   * makes vectorisation easy */
18742
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18743
    ni=Min(nelems-j,LOOPCNT);
18744
    if (realign) {
18745
      xp = tmp;
18746
    } else {
18747
      xp = (int64 *) *xpp;
18748
    }
18749
   /* copy the next block */
18750
#pragma cdir loopcnt=LOOPCNT
18751
#pragma cdir shortloop
18752
    for (i=0; i<ni; i++) {
18753
      /* the normal case: */
18754
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18755
     /* test for range errors (not always needed but do it anyway) */
18756
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18757
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18758
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18759
    }
18760
   /* copy workspace back if necessary */
18761
    if (realign) {
18762
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18763
      xp = (int64 *) *xpp;
18764
    }
18765
   /* update xpp and tp */
18766
    xp += ni;
18767
    tp += ni;
18768
    *xpp = (void*)xp;
18769
  }
18770
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18771
18772
#else   /* not SX */
18773
18774
0
  char *xp = (char *) *xpp;
18775
0
  int status = NC_NOERR;
18776
18777
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18778
0
  {
18779
0
    int lstatus = ncx_put_longlong_int(xp, tp, fillp);
18780
0
    if (status == NC_NOERR) /* report the first encountered error */
18781
0
      status = lstatus;
18782
0
  }
18783
18784
0
  *xpp = (void *)xp;
18785
0
  return status;
18786
0
#endif
18787
0
}
18788
18789
int
18790
ncx_putn_longlong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
18791
0
{
18792
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18793
18794
 /* basic algorithm is:
18795
  *   - ensure sane alignment of output data
18796
  *   - copy (conversion happens automatically) input data
18797
  *     to output
18798
  *   - update tp to point at next unconverted input, and xpp to point
18799
  *     at next location for converted output
18800
  */
18801
  long i, j, ni;
18802
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18803
  int64 *xp;
18804
  int nrange = 0;         /* number of range errors */
18805
  int realign = 0;        /* "do we need to fix input data alignment?" */
18806
  long cxp = (long) *((char**)xpp);
18807
18808
  realign = (cxp & 7) % SIZEOF_INT64;
18809
  /* sjl: manually stripmine so we can limit amount of
18810
   * vector work space reserved to LOOPCNT elements. Also
18811
   * makes vectorisation easy */
18812
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18813
    ni=Min(nelems-j,LOOPCNT);
18814
    if (realign) {
18815
      xp = tmp;
18816
    } else {
18817
      xp = (int64 *) *xpp;
18818
    }
18819
   /* copy the next block */
18820
#pragma cdir loopcnt=LOOPCNT
18821
#pragma cdir shortloop
18822
    for (i=0; i<ni; i++) {
18823
      /* the normal case: */
18824
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18825
     /* test for range errors (not always needed but do it anyway) */
18826
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18827
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18828
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18829
    }
18830
   /* copy workspace back if necessary */
18831
    if (realign) {
18832
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18833
      xp = (int64 *) *xpp;
18834
    }
18835
   /* update xpp and tp */
18836
    xp += ni;
18837
    tp += ni;
18838
    *xpp = (void*)xp;
18839
  }
18840
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18841
18842
#else   /* not SX */
18843
18844
0
  char *xp = (char *) *xpp;
18845
0
  int status = NC_NOERR;
18846
18847
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18848
0
  {
18849
0
    int lstatus = ncx_put_longlong_long(xp, tp, fillp);
18850
0
    if (status == NC_NOERR) /* report the first encountered error */
18851
0
      status = lstatus;
18852
0
  }
18853
18854
0
  *xpp = (void *)xp;
18855
0
  return status;
18856
0
#endif
18857
0
}
18858
18859
int
18860
ncx_putn_longlong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
18861
0
{
18862
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18863
18864
 /* basic algorithm is:
18865
  *   - ensure sane alignment of output data
18866
  *   - copy (conversion happens automatically) input data
18867
  *     to output
18868
  *   - update tp to point at next unconverted input, and xpp to point
18869
  *     at next location for converted output
18870
  */
18871
  long i, j, ni;
18872
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18873
  int64 *xp;
18874
  int nrange = 0;         /* number of range errors */
18875
  int realign = 0;        /* "do we need to fix input data alignment?" */
18876
  long cxp = (long) *((char**)xpp);
18877
18878
  realign = (cxp & 7) % SIZEOF_INT64;
18879
  /* sjl: manually stripmine so we can limit amount of
18880
   * vector work space reserved to LOOPCNT elements. Also
18881
   * makes vectorisation easy */
18882
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18883
    ni=Min(nelems-j,LOOPCNT);
18884
    if (realign) {
18885
      xp = tmp;
18886
    } else {
18887
      xp = (int64 *) *xpp;
18888
    }
18889
   /* copy the next block */
18890
#pragma cdir loopcnt=LOOPCNT
18891
#pragma cdir shortloop
18892
    for (i=0; i<ni; i++) {
18893
      /* the normal case: */
18894
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18895
     /* test for range errors (not always needed but do it anyway) */
18896
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18897
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18898
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18899
    }
18900
   /* copy workspace back if necessary */
18901
    if (realign) {
18902
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18903
      xp = (int64 *) *xpp;
18904
    }
18905
   /* update xpp and tp */
18906
    xp += ni;
18907
    tp += ni;
18908
    *xpp = (void*)xp;
18909
  }
18910
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18911
18912
#else   /* not SX */
18913
18914
0
  char *xp = (char *) *xpp;
18915
0
  int status = NC_NOERR;
18916
18917
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18918
0
  {
18919
0
    int lstatus = ncx_put_longlong_float(xp, tp, fillp);
18920
0
    if (status == NC_NOERR) /* report the first encountered error */
18921
0
      status = lstatus;
18922
0
  }
18923
18924
0
  *xpp = (void *)xp;
18925
0
  return status;
18926
0
#endif
18927
0
}
18928
18929
int
18930
ncx_putn_longlong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
18931
0
{
18932
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18933
18934
 /* basic algorithm is:
18935
  *   - ensure sane alignment of output data
18936
  *   - copy (conversion happens automatically) input data
18937
  *     to output
18938
  *   - update tp to point at next unconverted input, and xpp to point
18939
  *     at next location for converted output
18940
  */
18941
  long i, j, ni;
18942
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18943
  int64 *xp;
18944
  int nrange = 0;         /* number of range errors */
18945
  int realign = 0;        /* "do we need to fix input data alignment?" */
18946
  long cxp = (long) *((char**)xpp);
18947
18948
  realign = (cxp & 7) % SIZEOF_INT64;
18949
  /* sjl: manually stripmine so we can limit amount of
18950
   * vector work space reserved to LOOPCNT elements. Also
18951
   * makes vectorisation easy */
18952
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18953
    ni=Min(nelems-j,LOOPCNT);
18954
    if (realign) {
18955
      xp = tmp;
18956
    } else {
18957
      xp = (int64 *) *xpp;
18958
    }
18959
   /* copy the next block */
18960
#pragma cdir loopcnt=LOOPCNT
18961
#pragma cdir shortloop
18962
    for (i=0; i<ni; i++) {
18963
      /* the normal case: */
18964
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18965
     /* test for range errors (not always needed but do it anyway) */
18966
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18967
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18968
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18969
    }
18970
   /* copy workspace back if necessary */
18971
    if (realign) {
18972
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18973
      xp = (int64 *) *xpp;
18974
    }
18975
   /* update xpp and tp */
18976
    xp += ni;
18977
    tp += ni;
18978
    *xpp = (void*)xp;
18979
  }
18980
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18981
18982
#else   /* not SX */
18983
18984
0
  char *xp = (char *) *xpp;
18985
0
  int status = NC_NOERR;
18986
18987
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18988
0
  {
18989
0
    int lstatus = ncx_put_longlong_double(xp, tp, fillp);
18990
0
    if (status == NC_NOERR) /* report the first encountered error */
18991
0
      status = lstatus;
18992
0
  }
18993
18994
0
  *xpp = (void *)xp;
18995
0
  return status;
18996
0
#endif
18997
0
}
18998
18999
int
19000
ncx_putn_longlong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
19001
0
{
19002
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19003
19004
 /* basic algorithm is:
19005
  *   - ensure sane alignment of output data
19006
  *   - copy (conversion happens automatically) input data
19007
  *     to output
19008
  *   - update tp to point at next unconverted input, and xpp to point
19009
  *     at next location for converted output
19010
  */
19011
  long i, j, ni;
19012
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19013
  int64 *xp;
19014
  int nrange = 0;         /* number of range errors */
19015
  int realign = 0;        /* "do we need to fix input data alignment?" */
19016
  long cxp = (long) *((char**)xpp);
19017
19018
  realign = (cxp & 7) % SIZEOF_INT64;
19019
  /* sjl: manually stripmine so we can limit amount of
19020
   * vector work space reserved to LOOPCNT elements. Also
19021
   * makes vectorisation easy */
19022
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19023
    ni=Min(nelems-j,LOOPCNT);
19024
    if (realign) {
19025
      xp = tmp;
19026
    } else {
19027
      xp = (int64 *) *xpp;
19028
    }
19029
   /* copy the next block */
19030
#pragma cdir loopcnt=LOOPCNT
19031
#pragma cdir shortloop
19032
    for (i=0; i<ni; i++) {
19033
      /* the normal case: */
19034
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19035
     /* test for range errors (not always needed but do it anyway) */
19036
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19037
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19038
      nrange += tp[i] > X_INT64_MAX ;
19039
    }
19040
   /* copy workspace back if necessary */
19041
    if (realign) {
19042
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19043
      xp = (int64 *) *xpp;
19044
    }
19045
   /* update xpp and tp */
19046
    xp += ni;
19047
    tp += ni;
19048
    *xpp = (void*)xp;
19049
  }
19050
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19051
19052
#else   /* not SX */
19053
19054
0
  char *xp = (char *) *xpp;
19055
0
  int status = NC_NOERR;
19056
19057
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19058
0
  {
19059
0
    int lstatus = ncx_put_longlong_uchar(xp, tp, fillp);
19060
0
    if (status == NC_NOERR) /* report the first encountered error */
19061
0
      status = lstatus;
19062
0
  }
19063
19064
0
  *xpp = (void *)xp;
19065
0
  return status;
19066
0
#endif
19067
0
}
19068
19069
int
19070
ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
19071
0
{
19072
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19073
19074
 /* basic algorithm is:
19075
  *   - ensure sane alignment of output data
19076
  *   - copy (conversion happens automatically) input data
19077
  *     to output
19078
  *   - update tp to point at next unconverted input, and xpp to point
19079
  *     at next location for converted output
19080
  */
19081
  long i, j, ni;
19082
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19083
  int64 *xp;
19084
  int nrange = 0;         /* number of range errors */
19085
  int realign = 0;        /* "do we need to fix input data alignment?" */
19086
  long cxp = (long) *((char**)xpp);
19087
19088
  realign = (cxp & 7) % SIZEOF_INT64;
19089
  /* sjl: manually stripmine so we can limit amount of
19090
   * vector work space reserved to LOOPCNT elements. Also
19091
   * makes vectorisation easy */
19092
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19093
    ni=Min(nelems-j,LOOPCNT);
19094
    if (realign) {
19095
      xp = tmp;
19096
    } else {
19097
      xp = (int64 *) *xpp;
19098
    }
19099
   /* copy the next block */
19100
#pragma cdir loopcnt=LOOPCNT
19101
#pragma cdir shortloop
19102
    for (i=0; i<ni; i++) {
19103
      /* the normal case: */
19104
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19105
     /* test for range errors (not always needed but do it anyway) */
19106
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19107
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19108
      nrange += tp[i] > X_INT64_MAX ;
19109
    }
19110
   /* copy workspace back if necessary */
19111
    if (realign) {
19112
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19113
      xp = (int64 *) *xpp;
19114
    }
19115
   /* update xpp and tp */
19116
    xp += ni;
19117
    tp += ni;
19118
    *xpp = (void*)xp;
19119
  }
19120
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19121
19122
#else   /* not SX */
19123
19124
0
  char *xp = (char *) *xpp;
19125
0
  int status = NC_NOERR;
19126
19127
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19128
0
  {
19129
0
    int lstatus = ncx_put_longlong_ushort(xp, tp, fillp);
19130
0
    if (status == NC_NOERR) /* report the first encountered error */
19131
0
      status = lstatus;
19132
0
  }
19133
19134
0
  *xpp = (void *)xp;
19135
0
  return status;
19136
0
#endif
19137
0
}
19138
19139
int
19140
ncx_putn_longlong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
19141
0
{
19142
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19143
19144
 /* basic algorithm is:
19145
  *   - ensure sane alignment of output data
19146
  *   - copy (conversion happens automatically) input data
19147
  *     to output
19148
  *   - update tp to point at next unconverted input, and xpp to point
19149
  *     at next location for converted output
19150
  */
19151
  long i, j, ni;
19152
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19153
  int64 *xp;
19154
  int nrange = 0;         /* number of range errors */
19155
  int realign = 0;        /* "do we need to fix input data alignment?" */
19156
  long cxp = (long) *((char**)xpp);
19157
19158
  realign = (cxp & 7) % SIZEOF_INT64;
19159
  /* sjl: manually stripmine so we can limit amount of
19160
   * vector work space reserved to LOOPCNT elements. Also
19161
   * makes vectorisation easy */
19162
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19163
    ni=Min(nelems-j,LOOPCNT);
19164
    if (realign) {
19165
      xp = tmp;
19166
    } else {
19167
      xp = (int64 *) *xpp;
19168
    }
19169
   /* copy the next block */
19170
#pragma cdir loopcnt=LOOPCNT
19171
#pragma cdir shortloop
19172
    for (i=0; i<ni; i++) {
19173
      /* the normal case: */
19174
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19175
     /* test for range errors (not always needed but do it anyway) */
19176
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19177
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19178
      nrange += tp[i] > X_INT64_MAX ;
19179
    }
19180
   /* copy workspace back if necessary */
19181
    if (realign) {
19182
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19183
      xp = (int64 *) *xpp;
19184
    }
19185
   /* update xpp and tp */
19186
    xp += ni;
19187
    tp += ni;
19188
    *xpp = (void*)xp;
19189
  }
19190
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19191
19192
#else   /* not SX */
19193
19194
0
  char *xp = (char *) *xpp;
19195
0
  int status = NC_NOERR;
19196
19197
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19198
0
  {
19199
0
    int lstatus = ncx_put_longlong_uint(xp, tp, fillp);
19200
0
    if (status == NC_NOERR) /* report the first encountered error */
19201
0
      status = lstatus;
19202
0
  }
19203
19204
0
  *xpp = (void *)xp;
19205
0
  return status;
19206
0
#endif
19207
0
}
19208
19209
int
19210
ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
19211
0
{
19212
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19213
19214
 /* basic algorithm is:
19215
  *   - ensure sane alignment of output data
19216
  *   - copy (conversion happens automatically) input data
19217
  *     to output
19218
  *   - update tp to point at next unconverted input, and xpp to point
19219
  *     at next location for converted output
19220
  */
19221
  long i, j, ni;
19222
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19223
  int64 *xp;
19224
  int nrange = 0;         /* number of range errors */
19225
  int realign = 0;        /* "do we need to fix input data alignment?" */
19226
  long cxp = (long) *((char**)xpp);
19227
19228
  realign = (cxp & 7) % SIZEOF_INT64;
19229
  /* sjl: manually stripmine so we can limit amount of
19230
   * vector work space reserved to LOOPCNT elements. Also
19231
   * makes vectorisation easy */
19232
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19233
    ni=Min(nelems-j,LOOPCNT);
19234
    if (realign) {
19235
      xp = tmp;
19236
    } else {
19237
      xp = (int64 *) *xpp;
19238
    }
19239
   /* copy the next block */
19240
#pragma cdir loopcnt=LOOPCNT
19241
#pragma cdir shortloop
19242
    for (i=0; i<ni; i++) {
19243
      /* the normal case: */
19244
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19245
     /* test for range errors (not always needed but do it anyway) */
19246
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19247
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19248
      nrange += tp[i] > X_INT64_MAX ;
19249
    }
19250
   /* copy workspace back if necessary */
19251
    if (realign) {
19252
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19253
      xp = (int64 *) *xpp;
19254
    }
19255
   /* update xpp and tp */
19256
    xp += ni;
19257
    tp += ni;
19258
    *xpp = (void*)xp;
19259
  }
19260
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19261
19262
#else   /* not SX */
19263
19264
0
  char *xp = (char *) *xpp;
19265
0
  int status = NC_NOERR;
19266
19267
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19268
0
  {
19269
0
    int lstatus = ncx_put_longlong_ulonglong(xp, tp, fillp);
19270
0
    if (status == NC_NOERR) /* report the first encountered error */
19271
0
      status = lstatus;
19272
0
  }
19273
19274
0
  *xpp = (void *)xp;
19275
0
  return status;
19276
0
#endif
19277
0
}
19278
19279
19280
/* uint64 --------------------------------------------------------------------*/
19281
19282
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
19283
/* optimized version */
19284
int
19285
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp)
19286
0
{
19287
#ifdef WORDS_BIGENDIAN
19288
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
19289
# else
19290
0
  swapn8b(tp, *xpp, nelems);
19291
0
# endif
19292
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
19293
0
  return NC_NOERR;
19294
0
}
19295
#else
19296
int
19297
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
19298
{
19299
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19300
19301
 /* basic algorithm is:
19302
  *   - ensure sane alignment of input data
19303
  *   - copy (conversion happens automatically) input data
19304
  *     to output
19305
  *   - update xpp to point at next unconverted input, and tp to point
19306
  *     at next location for converted output
19307
  */
19308
  long i, j, ni;
19309
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19310
  uint64 *xp;
19311
  int nrange = 0;         /* number of range errors */
19312
  int realign = 0;        /* "do we need to fix input data alignment?" */
19313
  long cxp = (long) *((char**)xpp);
19314
19315
  realign = (cxp & 7) % SIZEOF_UINT64;
19316
  /* sjl: manually stripmine so we can limit amount of
19317
   * vector work space reserved to LOOPCNT elements. Also
19318
   * makes vectorisation easy */
19319
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19320
    ni=Min(nelems-j,LOOPCNT);
19321
    if (realign) {
19322
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19323
      xp = tmp;
19324
    } else {
19325
      xp = (uint64 *) *xpp;
19326
    }
19327
   /* copy the next block */
19328
#pragma cdir loopcnt=LOOPCNT
19329
#pragma cdir shortloop
19330
    for (i=0; i<ni; i++) {
19331
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
19332
     /* test for range errors (not always needed but do it anyway) */
19333
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19334
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19335
      nrange += xp[i] > ULONGLONG_MAX ;
19336
    }
19337
   /* update xpp and tp */
19338
    if (realign) xp = (uint64 *) *xpp;
19339
    xp += ni;
19340
    tp += ni;
19341
    *xpp = (void*)xp;
19342
  }
19343
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19344
19345
#else   /* not SX */
19346
  const char *xp = (const char *) *xpp;
19347
  int status = NC_NOERR;
19348
19349
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19350
  {
19351
    const int lstatus = ncx_get_ulonglong_ulonglong(xp, tp);
19352
    if (status == NC_NOERR) /* report the first encountered error */
19353
      status = lstatus;
19354
  }
19355
19356
  *xpp = (const void *)xp;
19357
  return status;
19358
#endif
19359
}
19360
19361
#endif
19362
int
19363
ncx_getn_ulonglong_schar(const void **xpp, size_t nelems, schar *tp)
19364
0
{
19365
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19366
19367
 /* basic algorithm is:
19368
  *   - ensure sane alignment of input data
19369
  *   - copy (conversion happens automatically) input data
19370
  *     to output
19371
  *   - update xpp to point at next unconverted input, and tp to point
19372
  *     at next location for converted output
19373
  */
19374
  long i, j, ni;
19375
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19376
  uint64 *xp;
19377
  int nrange = 0;         /* number of range errors */
19378
  int realign = 0;        /* "do we need to fix input data alignment?" */
19379
  long cxp = (long) *((char**)xpp);
19380
19381
  realign = (cxp & 7) % SIZEOF_UINT64;
19382
  /* sjl: manually stripmine so we can limit amount of
19383
   * vector work space reserved to LOOPCNT elements. Also
19384
   * makes vectorisation easy */
19385
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19386
    ni=Min(nelems-j,LOOPCNT);
19387
    if (realign) {
19388
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19389
      xp = tmp;
19390
    } else {
19391
      xp = (uint64 *) *xpp;
19392
    }
19393
   /* copy the next block */
19394
#pragma cdir loopcnt=LOOPCNT
19395
#pragma cdir shortloop
19396
    for (i=0; i<ni; i++) {
19397
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
19398
     /* test for range errors (not always needed but do it anyway) */
19399
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19400
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19401
      nrange += xp[i] > SCHAR_MAX ;
19402
    }
19403
   /* update xpp and tp */
19404
    if (realign) xp = (uint64 *) *xpp;
19405
    xp += ni;
19406
    tp += ni;
19407
    *xpp = (void*)xp;
19408
  }
19409
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19410
19411
#else   /* not SX */
19412
0
  const char *xp = (const char *) *xpp;
19413
0
  int status = NC_NOERR;
19414
19415
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19416
0
  {
19417
0
    const int lstatus = ncx_get_ulonglong_schar(xp, tp);
19418
0
    if (status == NC_NOERR) /* report the first encountered error */
19419
0
      status = lstatus;
19420
0
  }
19421
19422
0
  *xpp = (const void *)xp;
19423
0
  return status;
19424
0
#endif
19425
0
}
19426
19427
int
19428
ncx_getn_ulonglong_short(const void **xpp, size_t nelems, short *tp)
19429
0
{
19430
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19431
19432
 /* basic algorithm is:
19433
  *   - ensure sane alignment of input data
19434
  *   - copy (conversion happens automatically) input data
19435
  *     to output
19436
  *   - update xpp to point at next unconverted input, and tp to point
19437
  *     at next location for converted output
19438
  */
19439
  long i, j, ni;
19440
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19441
  uint64 *xp;
19442
  int nrange = 0;         /* number of range errors */
19443
  int realign = 0;        /* "do we need to fix input data alignment?" */
19444
  long cxp = (long) *((char**)xpp);
19445
19446
  realign = (cxp & 7) % SIZEOF_UINT64;
19447
  /* sjl: manually stripmine so we can limit amount of
19448
   * vector work space reserved to LOOPCNT elements. Also
19449
   * makes vectorisation easy */
19450
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19451
    ni=Min(nelems-j,LOOPCNT);
19452
    if (realign) {
19453
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19454
      xp = tmp;
19455
    } else {
19456
      xp = (uint64 *) *xpp;
19457
    }
19458
   /* copy the next block */
19459
#pragma cdir loopcnt=LOOPCNT
19460
#pragma cdir shortloop
19461
    for (i=0; i<ni; i++) {
19462
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
19463
     /* test for range errors (not always needed but do it anyway) */
19464
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19465
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19466
      nrange += xp[i] > SHORT_MAX ;
19467
    }
19468
   /* update xpp and tp */
19469
    if (realign) xp = (uint64 *) *xpp;
19470
    xp += ni;
19471
    tp += ni;
19472
    *xpp = (void*)xp;
19473
  }
19474
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19475
19476
#else   /* not SX */
19477
0
  const char *xp = (const char *) *xpp;
19478
0
  int status = NC_NOERR;
19479
19480
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19481
0
  {
19482
0
    const int lstatus = ncx_get_ulonglong_short(xp, tp);
19483
0
    if (status == NC_NOERR) /* report the first encountered error */
19484
0
      status = lstatus;
19485
0
  }
19486
19487
0
  *xpp = (const void *)xp;
19488
0
  return status;
19489
0
#endif
19490
0
}
19491
19492
int
19493
ncx_getn_ulonglong_int(const void **xpp, size_t nelems, int *tp)
19494
0
{
19495
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19496
19497
 /* basic algorithm is:
19498
  *   - ensure sane alignment of input data
19499
  *   - copy (conversion happens automatically) input data
19500
  *     to output
19501
  *   - update xpp to point at next unconverted input, and tp to point
19502
  *     at next location for converted output
19503
  */
19504
  long i, j, ni;
19505
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19506
  uint64 *xp;
19507
  int nrange = 0;         /* number of range errors */
19508
  int realign = 0;        /* "do we need to fix input data alignment?" */
19509
  long cxp = (long) *((char**)xpp);
19510
19511
  realign = (cxp & 7) % SIZEOF_UINT64;
19512
  /* sjl: manually stripmine so we can limit amount of
19513
   * vector work space reserved to LOOPCNT elements. Also
19514
   * makes vectorisation easy */
19515
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19516
    ni=Min(nelems-j,LOOPCNT);
19517
    if (realign) {
19518
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19519
      xp = tmp;
19520
    } else {
19521
      xp = (uint64 *) *xpp;
19522
    }
19523
   /* copy the next block */
19524
#pragma cdir loopcnt=LOOPCNT
19525
#pragma cdir shortloop
19526
    for (i=0; i<ni; i++) {
19527
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
19528
     /* test for range errors (not always needed but do it anyway) */
19529
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19530
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19531
      nrange += xp[i] > INT_MAX ;
19532
    }
19533
   /* update xpp and tp */
19534
    if (realign) xp = (uint64 *) *xpp;
19535
    xp += ni;
19536
    tp += ni;
19537
    *xpp = (void*)xp;
19538
  }
19539
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19540
19541
#else   /* not SX */
19542
0
  const char *xp = (const char *) *xpp;
19543
0
  int status = NC_NOERR;
19544
19545
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19546
0
  {
19547
0
    const int lstatus = ncx_get_ulonglong_int(xp, tp);
19548
0
    if (status == NC_NOERR) /* report the first encountered error */
19549
0
      status = lstatus;
19550
0
  }
19551
19552
0
  *xpp = (const void *)xp;
19553
0
  return status;
19554
0
#endif
19555
0
}
19556
19557
int
19558
ncx_getn_ulonglong_long(const void **xpp, size_t nelems, long *tp)
19559
0
{
19560
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19561
19562
 /* basic algorithm is:
19563
  *   - ensure sane alignment of input data
19564
  *   - copy (conversion happens automatically) input data
19565
  *     to output
19566
  *   - update xpp to point at next unconverted input, and tp to point
19567
  *     at next location for converted output
19568
  */
19569
  long i, j, ni;
19570
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19571
  uint64 *xp;
19572
  int nrange = 0;         /* number of range errors */
19573
  int realign = 0;        /* "do we need to fix input data alignment?" */
19574
  long cxp = (long) *((char**)xpp);
19575
19576
  realign = (cxp & 7) % SIZEOF_UINT64;
19577
  /* sjl: manually stripmine so we can limit amount of
19578
   * vector work space reserved to LOOPCNT elements. Also
19579
   * makes vectorisation easy */
19580
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19581
    ni=Min(nelems-j,LOOPCNT);
19582
    if (realign) {
19583
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19584
      xp = tmp;
19585
    } else {
19586
      xp = (uint64 *) *xpp;
19587
    }
19588
   /* copy the next block */
19589
#pragma cdir loopcnt=LOOPCNT
19590
#pragma cdir shortloop
19591
    for (i=0; i<ni; i++) {
19592
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
19593
     /* test for range errors (not always needed but do it anyway) */
19594
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19595
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19596
      nrange += xp[i] > LONG_MAX ;
19597
    }
19598
   /* update xpp and tp */
19599
    if (realign) xp = (uint64 *) *xpp;
19600
    xp += ni;
19601
    tp += ni;
19602
    *xpp = (void*)xp;
19603
  }
19604
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19605
19606
#else   /* not SX */
19607
0
  const char *xp = (const char *) *xpp;
19608
0
  int status = NC_NOERR;
19609
19610
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19611
0
  {
19612
0
    const int lstatus = ncx_get_ulonglong_long(xp, tp);
19613
0
    if (status == NC_NOERR) /* report the first encountered error */
19614
0
      status = lstatus;
19615
0
  }
19616
19617
0
  *xpp = (const void *)xp;
19618
0
  return status;
19619
0
#endif
19620
0
}
19621
19622
int
19623
ncx_getn_ulonglong_float(const void **xpp, size_t nelems, float *tp)
19624
0
{
19625
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19626
19627
 /* basic algorithm is:
19628
  *   - ensure sane alignment of input data
19629
  *   - copy (conversion happens automatically) input data
19630
  *     to output
19631
  *   - update xpp to point at next unconverted input, and tp to point
19632
  *     at next location for converted output
19633
  */
19634
  long i, j, ni;
19635
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19636
  uint64 *xp;
19637
  int nrange = 0;         /* number of range errors */
19638
  int realign = 0;        /* "do we need to fix input data alignment?" */
19639
  long cxp = (long) *((char**)xpp);
19640
19641
  realign = (cxp & 7) % SIZEOF_UINT64;
19642
  /* sjl: manually stripmine so we can limit amount of
19643
   * vector work space reserved to LOOPCNT elements. Also
19644
   * makes vectorisation easy */
19645
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19646
    ni=Min(nelems-j,LOOPCNT);
19647
    if (realign) {
19648
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19649
      xp = tmp;
19650
    } else {
19651
      xp = (uint64 *) *xpp;
19652
    }
19653
   /* copy the next block */
19654
#pragma cdir loopcnt=LOOPCNT
19655
#pragma cdir shortloop
19656
    for (i=0; i<ni; i++) {
19657
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
19658
     /* test for range errors (not always needed but do it anyway) */
19659
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19660
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19661
      nrange += xp[i] > FLOAT_MAX ;
19662
    }
19663
   /* update xpp and tp */
19664
    if (realign) xp = (uint64 *) *xpp;
19665
    xp += ni;
19666
    tp += ni;
19667
    *xpp = (void*)xp;
19668
  }
19669
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19670
19671
#else   /* not SX */
19672
0
  const char *xp = (const char *) *xpp;
19673
0
  int status = NC_NOERR;
19674
19675
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19676
0
  {
19677
0
    const int lstatus = ncx_get_ulonglong_float(xp, tp);
19678
0
    if (status == NC_NOERR) /* report the first encountered error */
19679
0
      status = lstatus;
19680
0
  }
19681
19682
0
  *xpp = (const void *)xp;
19683
0
  return status;
19684
0
#endif
19685
0
}
19686
19687
int
19688
ncx_getn_ulonglong_double(const void **xpp, size_t nelems, double *tp)
19689
0
{
19690
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19691
19692
 /* basic algorithm is:
19693
  *   - ensure sane alignment of input data
19694
  *   - copy (conversion happens automatically) input data
19695
  *     to output
19696
  *   - update xpp to point at next unconverted input, and tp to point
19697
  *     at next location for converted output
19698
  */
19699
  long i, j, ni;
19700
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19701
  uint64 *xp;
19702
  int nrange = 0;         /* number of range errors */
19703
  int realign = 0;        /* "do we need to fix input data alignment?" */
19704
  long cxp = (long) *((char**)xpp);
19705
19706
  realign = (cxp & 7) % SIZEOF_UINT64;
19707
  /* sjl: manually stripmine so we can limit amount of
19708
   * vector work space reserved to LOOPCNT elements. Also
19709
   * makes vectorisation easy */
19710
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19711
    ni=Min(nelems-j,LOOPCNT);
19712
    if (realign) {
19713
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19714
      xp = tmp;
19715
    } else {
19716
      xp = (uint64 *) *xpp;
19717
    }
19718
   /* copy the next block */
19719
#pragma cdir loopcnt=LOOPCNT
19720
#pragma cdir shortloop
19721
    for (i=0; i<ni; i++) {
19722
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
19723
     /* test for range errors (not always needed but do it anyway) */
19724
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19725
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19726
      nrange += xp[i] > DOUBLE_MAX ;
19727
    }
19728
   /* update xpp and tp */
19729
    if (realign) xp = (uint64 *) *xpp;
19730
    xp += ni;
19731
    tp += ni;
19732
    *xpp = (void*)xp;
19733
  }
19734
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19735
19736
#else   /* not SX */
19737
0
  const char *xp = (const char *) *xpp;
19738
0
  int status = NC_NOERR;
19739
19740
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19741
0
  {
19742
0
    const int lstatus = ncx_get_ulonglong_double(xp, tp);
19743
0
    if (status == NC_NOERR) /* report the first encountered error */
19744
0
      status = lstatus;
19745
0
  }
19746
19747
0
  *xpp = (const void *)xp;
19748
0
  return status;
19749
0
#endif
19750
0
}
19751
19752
int
19753
ncx_getn_ulonglong_longlong(const void **xpp, size_t nelems, longlong *tp)
19754
0
{
19755
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19756
19757
 /* basic algorithm is:
19758
  *   - ensure sane alignment of input data
19759
  *   - copy (conversion happens automatically) input data
19760
  *     to output
19761
  *   - update xpp to point at next unconverted input, and tp to point
19762
  *     at next location for converted output
19763
  */
19764
  long i, j, ni;
19765
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19766
  uint64 *xp;
19767
  int nrange = 0;         /* number of range errors */
19768
  int realign = 0;        /* "do we need to fix input data alignment?" */
19769
  long cxp = (long) *((char**)xpp);
19770
19771
  realign = (cxp & 7) % SIZEOF_UINT64;
19772
  /* sjl: manually stripmine so we can limit amount of
19773
   * vector work space reserved to LOOPCNT elements. Also
19774
   * makes vectorisation easy */
19775
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19776
    ni=Min(nelems-j,LOOPCNT);
19777
    if (realign) {
19778
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19779
      xp = tmp;
19780
    } else {
19781
      xp = (uint64 *) *xpp;
19782
    }
19783
   /* copy the next block */
19784
#pragma cdir loopcnt=LOOPCNT
19785
#pragma cdir shortloop
19786
    for (i=0; i<ni; i++) {
19787
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
19788
     /* test for range errors (not always needed but do it anyway) */
19789
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19790
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19791
      nrange += xp[i] > LONGLONG_MAX ;
19792
    }
19793
   /* update xpp and tp */
19794
    if (realign) xp = (uint64 *) *xpp;
19795
    xp += ni;
19796
    tp += ni;
19797
    *xpp = (void*)xp;
19798
  }
19799
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19800
19801
#else   /* not SX */
19802
0
  const char *xp = (const char *) *xpp;
19803
0
  int status = NC_NOERR;
19804
19805
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19806
0
  {
19807
0
    const int lstatus = ncx_get_ulonglong_longlong(xp, tp);
19808
0
    if (status == NC_NOERR) /* report the first encountered error */
19809
0
      status = lstatus;
19810
0
  }
19811
19812
0
  *xpp = (const void *)xp;
19813
0
  return status;
19814
0
#endif
19815
0
}
19816
19817
int
19818
ncx_getn_ulonglong_uchar(const void **xpp, size_t nelems, uchar *tp)
19819
0
{
19820
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19821
19822
 /* basic algorithm is:
19823
  *   - ensure sane alignment of input data
19824
  *   - copy (conversion happens automatically) input data
19825
  *     to output
19826
  *   - update xpp to point at next unconverted input, and tp to point
19827
  *     at next location for converted output
19828
  */
19829
  long i, j, ni;
19830
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19831
  uint64 *xp;
19832
  int nrange = 0;         /* number of range errors */
19833
  int realign = 0;        /* "do we need to fix input data alignment?" */
19834
  long cxp = (long) *((char**)xpp);
19835
19836
  realign = (cxp & 7) % SIZEOF_UINT64;
19837
  /* sjl: manually stripmine so we can limit amount of
19838
   * vector work space reserved to LOOPCNT elements. Also
19839
   * makes vectorisation easy */
19840
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19841
    ni=Min(nelems-j,LOOPCNT);
19842
    if (realign) {
19843
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19844
      xp = tmp;
19845
    } else {
19846
      xp = (uint64 *) *xpp;
19847
    }
19848
   /* copy the next block */
19849
#pragma cdir loopcnt=LOOPCNT
19850
#pragma cdir shortloop
19851
    for (i=0; i<ni; i++) {
19852
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
19853
     /* test for range errors (not always needed but do it anyway) */
19854
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19855
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19856
      nrange += xp[i] > UCHAR_MAX ;
19857
    }
19858
   /* update xpp and tp */
19859
    if (realign) xp = (uint64 *) *xpp;
19860
    xp += ni;
19861
    tp += ni;
19862
    *xpp = (void*)xp;
19863
  }
19864
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19865
19866
#else   /* not SX */
19867
0
  const char *xp = (const char *) *xpp;
19868
0
  int status = NC_NOERR;
19869
19870
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19871
0
  {
19872
0
    const int lstatus = ncx_get_ulonglong_uchar(xp, tp);
19873
0
    if (status == NC_NOERR) /* report the first encountered error */
19874
0
      status = lstatus;
19875
0
  }
19876
19877
0
  *xpp = (const void *)xp;
19878
0
  return status;
19879
0
#endif
19880
0
}
19881
19882
int
19883
ncx_getn_ulonglong_ushort(const void **xpp, size_t nelems, ushort *tp)
19884
0
{
19885
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19886
19887
 /* basic algorithm is:
19888
  *   - ensure sane alignment of input data
19889
  *   - copy (conversion happens automatically) input data
19890
  *     to output
19891
  *   - update xpp to point at next unconverted input, and tp to point
19892
  *     at next location for converted output
19893
  */
19894
  long i, j, ni;
19895
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19896
  uint64 *xp;
19897
  int nrange = 0;         /* number of range errors */
19898
  int realign = 0;        /* "do we need to fix input data alignment?" */
19899
  long cxp = (long) *((char**)xpp);
19900
19901
  realign = (cxp & 7) % SIZEOF_UINT64;
19902
  /* sjl: manually stripmine so we can limit amount of
19903
   * vector work space reserved to LOOPCNT elements. Also
19904
   * makes vectorisation easy */
19905
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19906
    ni=Min(nelems-j,LOOPCNT);
19907
    if (realign) {
19908
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19909
      xp = tmp;
19910
    } else {
19911
      xp = (uint64 *) *xpp;
19912
    }
19913
   /* copy the next block */
19914
#pragma cdir loopcnt=LOOPCNT
19915
#pragma cdir shortloop
19916
    for (i=0; i<ni; i++) {
19917
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
19918
     /* test for range errors (not always needed but do it anyway) */
19919
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19920
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19921
      nrange += xp[i] > USHORT_MAX ;
19922
    }
19923
   /* update xpp and tp */
19924
    if (realign) xp = (uint64 *) *xpp;
19925
    xp += ni;
19926
    tp += ni;
19927
    *xpp = (void*)xp;
19928
  }
19929
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19930
19931
#else   /* not SX */
19932
0
  const char *xp = (const char *) *xpp;
19933
0
  int status = NC_NOERR;
19934
19935
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19936
0
  {
19937
0
    const int lstatus = ncx_get_ulonglong_ushort(xp, tp);
19938
0
    if (status == NC_NOERR) /* report the first encountered error */
19939
0
      status = lstatus;
19940
0
  }
19941
19942
0
  *xpp = (const void *)xp;
19943
0
  return status;
19944
0
#endif
19945
0
}
19946
19947
int
19948
ncx_getn_ulonglong_uint(const void **xpp, size_t nelems, uint *tp)
19949
0
{
19950
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19951
19952
 /* basic algorithm is:
19953
  *   - ensure sane alignment of input data
19954
  *   - copy (conversion happens automatically) input data
19955
  *     to output
19956
  *   - update xpp to point at next unconverted input, and tp to point
19957
  *     at next location for converted output
19958
  */
19959
  long i, j, ni;
19960
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19961
  uint64 *xp;
19962
  int nrange = 0;         /* number of range errors */
19963
  int realign = 0;        /* "do we need to fix input data alignment?" */
19964
  long cxp = (long) *((char**)xpp);
19965
19966
  realign = (cxp & 7) % SIZEOF_UINT64;
19967
  /* sjl: manually stripmine so we can limit amount of
19968
   * vector work space reserved to LOOPCNT elements. Also
19969
   * makes vectorisation easy */
19970
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19971
    ni=Min(nelems-j,LOOPCNT);
19972
    if (realign) {
19973
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19974
      xp = tmp;
19975
    } else {
19976
      xp = (uint64 *) *xpp;
19977
    }
19978
   /* copy the next block */
19979
#pragma cdir loopcnt=LOOPCNT
19980
#pragma cdir shortloop
19981
    for (i=0; i<ni; i++) {
19982
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
19983
     /* test for range errors (not always needed but do it anyway) */
19984
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19985
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19986
      nrange += xp[i] > UINT_MAX ;
19987
    }
19988
   /* update xpp and tp */
19989
    if (realign) xp = (uint64 *) *xpp;
19990
    xp += ni;
19991
    tp += ni;
19992
    *xpp = (void*)xp;
19993
  }
19994
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19995
19996
#else   /* not SX */
19997
0
  const char *xp = (const char *) *xpp;
19998
0
  int status = NC_NOERR;
19999
20000
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20001
0
  {
20002
0
    const int lstatus = ncx_get_ulonglong_uint(xp, tp);
20003
0
    if (status == NC_NOERR) /* report the first encountered error */
20004
0
      status = lstatus;
20005
0
  }
20006
20007
0
  *xpp = (const void *)xp;
20008
0
  return status;
20009
0
#endif
20010
0
}
20011
20012
20013
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
20014
/* optimized version */
20015
int
20016
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp, void *fillp)
20017
0
{
20018
#ifdef WORDS_BIGENDIAN
20019
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
20020
# else
20021
0
  swapn8b(*xpp, tp, nelems);
20022
0
# endif
20023
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
20024
0
  return NC_NOERR;
20025
0
}
20026
#else
20027
int
20028
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
20029
{
20030
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20031
20032
 /* basic algorithm is:
20033
  *   - ensure sane alignment of output data
20034
  *   - copy (conversion happens automatically) input data
20035
  *     to output
20036
  *   - update tp to point at next unconverted input, and xpp to point
20037
  *     at next location for converted output
20038
  */
20039
  long i, j, ni;
20040
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20041
  uint64 *xp;
20042
  int nrange = 0;         /* number of range errors */
20043
  int realign = 0;        /* "do we need to fix input data alignment?" */
20044
  long cxp = (long) *((char**)xpp);
20045
20046
  realign = (cxp & 7) % SIZEOF_UINT64;
20047
  /* sjl: manually stripmine so we can limit amount of
20048
   * vector work space reserved to LOOPCNT elements. Also
20049
   * makes vectorisation easy */
20050
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20051
    ni=Min(nelems-j,LOOPCNT);
20052
    if (realign) {
20053
      xp = tmp;
20054
    } else {
20055
      xp = (uint64 *) *xpp;
20056
    }
20057
   /* copy the next block */
20058
#pragma cdir loopcnt=LOOPCNT
20059
#pragma cdir shortloop
20060
    for (i=0; i<ni; i++) {
20061
      /* the normal case: */
20062
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20063
     /* test for range errors (not always needed but do it anyway) */
20064
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20065
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20066
      nrange += tp[i] > X_UINT64_MAX ;
20067
    }
20068
   /* copy workspace back if necessary */
20069
    if (realign) {
20070
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20071
      xp = (uint64 *) *xpp;
20072
    }
20073
   /* update xpp and tp */
20074
    xp += ni;
20075
    tp += ni;
20076
    *xpp = (void*)xp;
20077
  }
20078
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20079
20080
#else   /* not SX */
20081
20082
  char *xp = (char *) *xpp;
20083
  int status = NC_NOERR;
20084
20085
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20086
  {
20087
    int lstatus = ncx_put_ulonglong_ulonglong(xp, tp, fillp);
20088
    if (status == NC_NOERR) /* report the first encountered error */
20089
      status = lstatus;
20090
  }
20091
20092
  *xpp = (void *)xp;
20093
  return status;
20094
#endif
20095
}
20096
20097
#endif
20098
int
20099
ncx_putn_ulonglong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
20100
0
{
20101
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20102
20103
 /* basic algorithm is:
20104
  *   - ensure sane alignment of output data
20105
  *   - copy (conversion happens automatically) input data
20106
  *     to output
20107
  *   - update tp to point at next unconverted input, and xpp to point
20108
  *     at next location for converted output
20109
  */
20110
  long i, j, ni;
20111
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20112
  uint64 *xp;
20113
  int nrange = 0;         /* number of range errors */
20114
  int realign = 0;        /* "do we need to fix input data alignment?" */
20115
  long cxp = (long) *((char**)xpp);
20116
20117
  realign = (cxp & 7) % SIZEOF_UINT64;
20118
  /* sjl: manually stripmine so we can limit amount of
20119
   * vector work space reserved to LOOPCNT elements. Also
20120
   * makes vectorisation easy */
20121
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20122
    ni=Min(nelems-j,LOOPCNT);
20123
    if (realign) {
20124
      xp = tmp;
20125
    } else {
20126
      xp = (uint64 *) *xpp;
20127
    }
20128
   /* copy the next block */
20129
#pragma cdir loopcnt=LOOPCNT
20130
#pragma cdir shortloop
20131
    for (i=0; i<ni; i++) {
20132
      /* the normal case: */
20133
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20134
     /* test for range errors (not always needed but do it anyway) */
20135
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20136
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20137
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20138
    }
20139
   /* copy workspace back if necessary */
20140
    if (realign) {
20141
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20142
      xp = (uint64 *) *xpp;
20143
    }
20144
   /* update xpp and tp */
20145
    xp += ni;
20146
    tp += ni;
20147
    *xpp = (void*)xp;
20148
  }
20149
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20150
20151
#else   /* not SX */
20152
20153
0
  char *xp = (char *) *xpp;
20154
0
  int status = NC_NOERR;
20155
20156
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20157
0
  {
20158
0
    int lstatus = ncx_put_ulonglong_schar(xp, tp, fillp);
20159
0
    if (status == NC_NOERR) /* report the first encountered error */
20160
0
      status = lstatus;
20161
0
  }
20162
20163
0
  *xpp = (void *)xp;
20164
0
  return status;
20165
0
#endif
20166
0
}
20167
20168
int
20169
ncx_putn_ulonglong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
20170
0
{
20171
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20172
20173
 /* basic algorithm is:
20174
  *   - ensure sane alignment of output data
20175
  *   - copy (conversion happens automatically) input data
20176
  *     to output
20177
  *   - update tp to point at next unconverted input, and xpp to point
20178
  *     at next location for converted output
20179
  */
20180
  long i, j, ni;
20181
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20182
  uint64 *xp;
20183
  int nrange = 0;         /* number of range errors */
20184
  int realign = 0;        /* "do we need to fix input data alignment?" */
20185
  long cxp = (long) *((char**)xpp);
20186
20187
  realign = (cxp & 7) % SIZEOF_UINT64;
20188
  /* sjl: manually stripmine so we can limit amount of
20189
   * vector work space reserved to LOOPCNT elements. Also
20190
   * makes vectorisation easy */
20191
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20192
    ni=Min(nelems-j,LOOPCNT);
20193
    if (realign) {
20194
      xp = tmp;
20195
    } else {
20196
      xp = (uint64 *) *xpp;
20197
    }
20198
   /* copy the next block */
20199
#pragma cdir loopcnt=LOOPCNT
20200
#pragma cdir shortloop
20201
    for (i=0; i<ni; i++) {
20202
      /* the normal case: */
20203
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20204
     /* test for range errors (not always needed but do it anyway) */
20205
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20206
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20207
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20208
    }
20209
   /* copy workspace back if necessary */
20210
    if (realign) {
20211
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20212
      xp = (uint64 *) *xpp;
20213
    }
20214
   /* update xpp and tp */
20215
    xp += ni;
20216
    tp += ni;
20217
    *xpp = (void*)xp;
20218
  }
20219
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20220
20221
#else   /* not SX */
20222
20223
0
  char *xp = (char *) *xpp;
20224
0
  int status = NC_NOERR;
20225
20226
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20227
0
  {
20228
0
    int lstatus = ncx_put_ulonglong_short(xp, tp, fillp);
20229
0
    if (status == NC_NOERR) /* report the first encountered error */
20230
0
      status = lstatus;
20231
0
  }
20232
20233
0
  *xpp = (void *)xp;
20234
0
  return status;
20235
0
#endif
20236
0
}
20237
20238
int
20239
ncx_putn_ulonglong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
20240
0
{
20241
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20242
20243
 /* basic algorithm is:
20244
  *   - ensure sane alignment of output data
20245
  *   - copy (conversion happens automatically) input data
20246
  *     to output
20247
  *   - update tp to point at next unconverted input, and xpp to point
20248
  *     at next location for converted output
20249
  */
20250
  long i, j, ni;
20251
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20252
  uint64 *xp;
20253
  int nrange = 0;         /* number of range errors */
20254
  int realign = 0;        /* "do we need to fix input data alignment?" */
20255
  long cxp = (long) *((char**)xpp);
20256
20257
  realign = (cxp & 7) % SIZEOF_UINT64;
20258
  /* sjl: manually stripmine so we can limit amount of
20259
   * vector work space reserved to LOOPCNT elements. Also
20260
   * makes vectorisation easy */
20261
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20262
    ni=Min(nelems-j,LOOPCNT);
20263
    if (realign) {
20264
      xp = tmp;
20265
    } else {
20266
      xp = (uint64 *) *xpp;
20267
    }
20268
   /* copy the next block */
20269
#pragma cdir loopcnt=LOOPCNT
20270
#pragma cdir shortloop
20271
    for (i=0; i<ni; i++) {
20272
      /* the normal case: */
20273
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20274
     /* test for range errors (not always needed but do it anyway) */
20275
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20276
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20277
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20278
    }
20279
   /* copy workspace back if necessary */
20280
    if (realign) {
20281
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20282
      xp = (uint64 *) *xpp;
20283
    }
20284
   /* update xpp and tp */
20285
    xp += ni;
20286
    tp += ni;
20287
    *xpp = (void*)xp;
20288
  }
20289
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20290
20291
#else   /* not SX */
20292
20293
0
  char *xp = (char *) *xpp;
20294
0
  int status = NC_NOERR;
20295
20296
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20297
0
  {
20298
0
    int lstatus = ncx_put_ulonglong_int(xp, tp, fillp);
20299
0
    if (status == NC_NOERR) /* report the first encountered error */
20300
0
      status = lstatus;
20301
0
  }
20302
20303
0
  *xpp = (void *)xp;
20304
0
  return status;
20305
0
#endif
20306
0
}
20307
20308
int
20309
ncx_putn_ulonglong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
20310
0
{
20311
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20312
20313
 /* basic algorithm is:
20314
  *   - ensure sane alignment of output data
20315
  *   - copy (conversion happens automatically) input data
20316
  *     to output
20317
  *   - update tp to point at next unconverted input, and xpp to point
20318
  *     at next location for converted output
20319
  */
20320
  long i, j, ni;
20321
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20322
  uint64 *xp;
20323
  int nrange = 0;         /* number of range errors */
20324
  int realign = 0;        /* "do we need to fix input data alignment?" */
20325
  long cxp = (long) *((char**)xpp);
20326
20327
  realign = (cxp & 7) % SIZEOF_UINT64;
20328
  /* sjl: manually stripmine so we can limit amount of
20329
   * vector work space reserved to LOOPCNT elements. Also
20330
   * makes vectorisation easy */
20331
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20332
    ni=Min(nelems-j,LOOPCNT);
20333
    if (realign) {
20334
      xp = tmp;
20335
    } else {
20336
      xp = (uint64 *) *xpp;
20337
    }
20338
   /* copy the next block */
20339
#pragma cdir loopcnt=LOOPCNT
20340
#pragma cdir shortloop
20341
    for (i=0; i<ni; i++) {
20342
      /* the normal case: */
20343
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20344
     /* test for range errors (not always needed but do it anyway) */
20345
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20346
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20347
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20348
    }
20349
   /* copy workspace back if necessary */
20350
    if (realign) {
20351
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20352
      xp = (uint64 *) *xpp;
20353
    }
20354
   /* update xpp and tp */
20355
    xp += ni;
20356
    tp += ni;
20357
    *xpp = (void*)xp;
20358
  }
20359
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20360
20361
#else   /* not SX */
20362
20363
0
  char *xp = (char *) *xpp;
20364
0
  int status = NC_NOERR;
20365
20366
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20367
0
  {
20368
0
    int lstatus = ncx_put_ulonglong_long(xp, tp, fillp);
20369
0
    if (status == NC_NOERR) /* report the first encountered error */
20370
0
      status = lstatus;
20371
0
  }
20372
20373
0
  *xpp = (void *)xp;
20374
0
  return status;
20375
0
#endif
20376
0
}
20377
20378
int
20379
ncx_putn_ulonglong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
20380
0
{
20381
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20382
20383
 /* basic algorithm is:
20384
  *   - ensure sane alignment of output data
20385
  *   - copy (conversion happens automatically) input data
20386
  *     to output
20387
  *   - update tp to point at next unconverted input, and xpp to point
20388
  *     at next location for converted output
20389
  */
20390
  long i, j, ni;
20391
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20392
  uint64 *xp;
20393
  int nrange = 0;         /* number of range errors */
20394
  int realign = 0;        /* "do we need to fix input data alignment?" */
20395
  long cxp = (long) *((char**)xpp);
20396
20397
  realign = (cxp & 7) % SIZEOF_UINT64;
20398
  /* sjl: manually stripmine so we can limit amount of
20399
   * vector work space reserved to LOOPCNT elements. Also
20400
   * makes vectorisation easy */
20401
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20402
    ni=Min(nelems-j,LOOPCNT);
20403
    if (realign) {
20404
      xp = tmp;
20405
    } else {
20406
      xp = (uint64 *) *xpp;
20407
    }
20408
   /* copy the next block */
20409
#pragma cdir loopcnt=LOOPCNT
20410
#pragma cdir shortloop
20411
    for (i=0; i<ni; i++) {
20412
      /* the normal case: */
20413
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20414
     /* test for range errors (not always needed but do it anyway) */
20415
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20416
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20417
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20418
    }
20419
   /* copy workspace back if necessary */
20420
    if (realign) {
20421
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20422
      xp = (uint64 *) *xpp;
20423
    }
20424
   /* update xpp and tp */
20425
    xp += ni;
20426
    tp += ni;
20427
    *xpp = (void*)xp;
20428
  }
20429
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20430
20431
#else   /* not SX */
20432
20433
0
  char *xp = (char *) *xpp;
20434
0
  int status = NC_NOERR;
20435
20436
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20437
0
  {
20438
0
    int lstatus = ncx_put_ulonglong_float(xp, tp, fillp);
20439
0
    if (status == NC_NOERR) /* report the first encountered error */
20440
0
      status = lstatus;
20441
0
  }
20442
20443
0
  *xpp = (void *)xp;
20444
0
  return status;
20445
0
#endif
20446
0
}
20447
20448
int
20449
ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
20450
0
{
20451
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20452
20453
 /* basic algorithm is:
20454
  *   - ensure sane alignment of output data
20455
  *   - copy (conversion happens automatically) input data
20456
  *     to output
20457
  *   - update tp to point at next unconverted input, and xpp to point
20458
  *     at next location for converted output
20459
  */
20460
  long i, j, ni;
20461
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20462
  uint64 *xp;
20463
  int nrange = 0;         /* number of range errors */
20464
  int realign = 0;        /* "do we need to fix input data alignment?" */
20465
  long cxp = (long) *((char**)xpp);
20466
20467
  realign = (cxp & 7) % SIZEOF_UINT64;
20468
  /* sjl: manually stripmine so we can limit amount of
20469
   * vector work space reserved to LOOPCNT elements. Also
20470
   * makes vectorisation easy */
20471
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20472
    ni=Min(nelems-j,LOOPCNT);
20473
    if (realign) {
20474
      xp = tmp;
20475
    } else {
20476
      xp = (uint64 *) *xpp;
20477
    }
20478
   /* copy the next block */
20479
#pragma cdir loopcnt=LOOPCNT
20480
#pragma cdir shortloop
20481
    for (i=0; i<ni; i++) {
20482
      /* the normal case: */
20483
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20484
     /* test for range errors (not always needed but do it anyway) */
20485
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20486
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20487
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20488
    }
20489
   /* copy workspace back if necessary */
20490
    if (realign) {
20491
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20492
      xp = (uint64 *) *xpp;
20493
    }
20494
   /* update xpp and tp */
20495
    xp += ni;
20496
    tp += ni;
20497
    *xpp = (void*)xp;
20498
  }
20499
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20500
20501
#else   /* not SX */
20502
20503
0
  char *xp = (char *) *xpp;
20504
0
  int status = NC_NOERR;
20505
20506
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20507
0
  {
20508
0
    int lstatus = ncx_put_ulonglong_double(xp, tp, fillp);
20509
0
    if (status == NC_NOERR) /* report the first encountered error */
20510
0
      status = lstatus;
20511
0
  }
20512
20513
0
  *xpp = (void *)xp;
20514
0
  return status;
20515
0
#endif
20516
0
}
20517
20518
int
20519
ncx_putn_ulonglong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
20520
0
{
20521
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20522
20523
 /* basic algorithm is:
20524
  *   - ensure sane alignment of output data
20525
  *   - copy (conversion happens automatically) input data
20526
  *     to output
20527
  *   - update tp to point at next unconverted input, and xpp to point
20528
  *     at next location for converted output
20529
  */
20530
  long i, j, ni;
20531
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20532
  uint64 *xp;
20533
  int nrange = 0;         /* number of range errors */
20534
  int realign = 0;        /* "do we need to fix input data alignment?" */
20535
  long cxp = (long) *((char**)xpp);
20536
20537
  realign = (cxp & 7) % SIZEOF_UINT64;
20538
  /* sjl: manually stripmine so we can limit amount of
20539
   * vector work space reserved to LOOPCNT elements. Also
20540
   * makes vectorisation easy */
20541
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20542
    ni=Min(nelems-j,LOOPCNT);
20543
    if (realign) {
20544
      xp = tmp;
20545
    } else {
20546
      xp = (uint64 *) *xpp;
20547
    }
20548
   /* copy the next block */
20549
#pragma cdir loopcnt=LOOPCNT
20550
#pragma cdir shortloop
20551
    for (i=0; i<ni; i++) {
20552
      /* the normal case: */
20553
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20554
     /* test for range errors (not always needed but do it anyway) */
20555
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20556
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20557
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20558
    }
20559
   /* copy workspace back if necessary */
20560
    if (realign) {
20561
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20562
      xp = (uint64 *) *xpp;
20563
    }
20564
   /* update xpp and tp */
20565
    xp += ni;
20566
    tp += ni;
20567
    *xpp = (void*)xp;
20568
  }
20569
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20570
20571
#else   /* not SX */
20572
20573
0
  char *xp = (char *) *xpp;
20574
0
  int status = NC_NOERR;
20575
20576
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20577
0
  {
20578
0
    int lstatus = ncx_put_ulonglong_longlong(xp, tp, fillp);
20579
0
    if (status == NC_NOERR) /* report the first encountered error */
20580
0
      status = lstatus;
20581
0
  }
20582
20583
0
  *xpp = (void *)xp;
20584
0
  return status;
20585
0
#endif
20586
0
}
20587
20588
int
20589
ncx_putn_ulonglong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
20590
0
{
20591
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20592
20593
 /* basic algorithm is:
20594
  *   - ensure sane alignment of output data
20595
  *   - copy (conversion happens automatically) input data
20596
  *     to output
20597
  *   - update tp to point at next unconverted input, and xpp to point
20598
  *     at next location for converted output
20599
  */
20600
  long i, j, ni;
20601
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20602
  uint64 *xp;
20603
  int nrange = 0;         /* number of range errors */
20604
  int realign = 0;        /* "do we need to fix input data alignment?" */
20605
  long cxp = (long) *((char**)xpp);
20606
20607
  realign = (cxp & 7) % SIZEOF_UINT64;
20608
  /* sjl: manually stripmine so we can limit amount of
20609
   * vector work space reserved to LOOPCNT elements. Also
20610
   * makes vectorisation easy */
20611
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20612
    ni=Min(nelems-j,LOOPCNT);
20613
    if (realign) {
20614
      xp = tmp;
20615
    } else {
20616
      xp = (uint64 *) *xpp;
20617
    }
20618
   /* copy the next block */
20619
#pragma cdir loopcnt=LOOPCNT
20620
#pragma cdir shortloop
20621
    for (i=0; i<ni; i++) {
20622
      /* the normal case: */
20623
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20624
     /* test for range errors (not always needed but do it anyway) */
20625
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20626
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20627
      nrange += tp[i] > X_UINT64_MAX ;
20628
    }
20629
   /* copy workspace back if necessary */
20630
    if (realign) {
20631
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20632
      xp = (uint64 *) *xpp;
20633
    }
20634
   /* update xpp and tp */
20635
    xp += ni;
20636
    tp += ni;
20637
    *xpp = (void*)xp;
20638
  }
20639
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20640
20641
#else   /* not SX */
20642
20643
0
  char *xp = (char *) *xpp;
20644
0
  int status = NC_NOERR;
20645
20646
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20647
0
  {
20648
0
    int lstatus = ncx_put_ulonglong_uchar(xp, tp, fillp);
20649
0
    if (status == NC_NOERR) /* report the first encountered error */
20650
0
      status = lstatus;
20651
0
  }
20652
20653
0
  *xpp = (void *)xp;
20654
0
  return status;
20655
0
#endif
20656
0
}
20657
20658
int
20659
ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
20660
0
{
20661
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20662
20663
 /* basic algorithm is:
20664
  *   - ensure sane alignment of output data
20665
  *   - copy (conversion happens automatically) input data
20666
  *     to output
20667
  *   - update tp to point at next unconverted input, and xpp to point
20668
  *     at next location for converted output
20669
  */
20670
  long i, j, ni;
20671
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20672
  uint64 *xp;
20673
  int nrange = 0;         /* number of range errors */
20674
  int realign = 0;        /* "do we need to fix input data alignment?" */
20675
  long cxp = (long) *((char**)xpp);
20676
20677
  realign = (cxp & 7) % SIZEOF_UINT64;
20678
  /* sjl: manually stripmine so we can limit amount of
20679
   * vector work space reserved to LOOPCNT elements. Also
20680
   * makes vectorisation easy */
20681
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20682
    ni=Min(nelems-j,LOOPCNT);
20683
    if (realign) {
20684
      xp = tmp;
20685
    } else {
20686
      xp = (uint64 *) *xpp;
20687
    }
20688
   /* copy the next block */
20689
#pragma cdir loopcnt=LOOPCNT
20690
#pragma cdir shortloop
20691
    for (i=0; i<ni; i++) {
20692
      /* the normal case: */
20693
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20694
     /* test for range errors (not always needed but do it anyway) */
20695
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20696
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20697
      nrange += tp[i] > X_UINT64_MAX ;
20698
    }
20699
   /* copy workspace back if necessary */
20700
    if (realign) {
20701
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20702
      xp = (uint64 *) *xpp;
20703
    }
20704
   /* update xpp and tp */
20705
    xp += ni;
20706
    tp += ni;
20707
    *xpp = (void*)xp;
20708
  }
20709
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20710
20711
#else   /* not SX */
20712
20713
0
  char *xp = (char *) *xpp;
20714
0
  int status = NC_NOERR;
20715
20716
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20717
0
  {
20718
0
    int lstatus = ncx_put_ulonglong_ushort(xp, tp, fillp);
20719
0
    if (status == NC_NOERR) /* report the first encountered error */
20720
0
      status = lstatus;
20721
0
  }
20722
20723
0
  *xpp = (void *)xp;
20724
0
  return status;
20725
0
#endif
20726
0
}
20727
20728
int
20729
ncx_putn_ulonglong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
20730
0
{
20731
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20732
20733
 /* basic algorithm is:
20734
  *   - ensure sane alignment of output data
20735
  *   - copy (conversion happens automatically) input data
20736
  *     to output
20737
  *   - update tp to point at next unconverted input, and xpp to point
20738
  *     at next location for converted output
20739
  */
20740
  long i, j, ni;
20741
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20742
  uint64 *xp;
20743
  int nrange = 0;         /* number of range errors */
20744
  int realign = 0;        /* "do we need to fix input data alignment?" */
20745
  long cxp = (long) *((char**)xpp);
20746
20747
  realign = (cxp & 7) % SIZEOF_UINT64;
20748
  /* sjl: manually stripmine so we can limit amount of
20749
   * vector work space reserved to LOOPCNT elements. Also
20750
   * makes vectorisation easy */
20751
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20752
    ni=Min(nelems-j,LOOPCNT);
20753
    if (realign) {
20754
      xp = tmp;
20755
    } else {
20756
      xp = (uint64 *) *xpp;
20757
    }
20758
   /* copy the next block */
20759
#pragma cdir loopcnt=LOOPCNT
20760
#pragma cdir shortloop
20761
    for (i=0; i<ni; i++) {
20762
      /* the normal case: */
20763
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20764
     /* test for range errors (not always needed but do it anyway) */
20765
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20766
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20767
      nrange += tp[i] > X_UINT64_MAX ;
20768
    }
20769
   /* copy workspace back if necessary */
20770
    if (realign) {
20771
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20772
      xp = (uint64 *) *xpp;
20773
    }
20774
   /* update xpp and tp */
20775
    xp += ni;
20776
    tp += ni;
20777
    *xpp = (void*)xp;
20778
  }
20779
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20780
20781
#else   /* not SX */
20782
20783
0
  char *xp = (char *) *xpp;
20784
0
  int status = NC_NOERR;
20785
20786
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20787
0
  {
20788
0
    int lstatus = ncx_put_ulonglong_uint(xp, tp, fillp);
20789
0
    if (status == NC_NOERR) /* report the first encountered error */
20790
0
      status = lstatus;
20791
0
  }
20792
20793
0
  *xpp = (void *)xp;
20794
0
  return status;
20795
0
#endif
20796
0
}
20797
20798
20799
20800
/*
20801
 * Other aggregate conversion functions.
20802
 */
20803
20804
/* text */
20805
20806
int
20807
ncx_getn_text(const void **xpp, size_t nelems, char *tp)
20808
0
{
20809
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
20810
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20811
0
  return NC_NOERR;
20812
20813
0
}
20814
20815
int
20816
ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
20817
602k
{
20818
602k
  size_t rndup = nelems % X_ALIGN;
20819
20820
602k
  if (rndup)
20821
4.87k
    rndup = X_ALIGN - rndup;
20822
20823
602k
  (void) memcpy(tp, *xpp, (size_t)nelems);
20824
602k
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
20825
20826
602k
  return NC_NOERR;
20827
20828
602k
}
20829
20830
int
20831
ncx_putn_text(void **xpp, size_t nelems, const char *tp)
20832
0
{
20833
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20834
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20835
20836
0
  return NC_NOERR;
20837
20838
0
}
20839
20840
int
20841
ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
20842
0
{
20843
0
  size_t rndup = nelems % X_ALIGN;
20844
20845
0
  if (rndup)
20846
0
    rndup = X_ALIGN - rndup;
20847
20848
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20849
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20850
20851
0
  if (rndup)
20852
0
  {
20853
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
20854
0
    *xpp = (void *)((char *)(*xpp) + rndup);
20855
0
  }
20856
20857
0
  return NC_NOERR;
20858
20859
0
}
20860
20861
20862
/* opaque */
20863
20864
int
20865
ncx_getn_void(const void **xpp, size_t nelems, void *tp)
20866
0
{
20867
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
20868
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20869
0
  return NC_NOERR;
20870
20871
0
}
20872
20873
int
20874
ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
20875
0
{
20876
0
  size_t rndup = nelems % X_ALIGN;
20877
20878
0
  if (rndup)
20879
0
    rndup = X_ALIGN - rndup;
20880
20881
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
20882
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
20883
20884
0
  return NC_NOERR;
20885
20886
0
}
20887
20888
int
20889
ncx_putn_void(void **xpp, size_t nelems, const void *tp)
20890
0
{
20891
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20892
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20893
20894
0
  return NC_NOERR;
20895
20896
0
}
20897
20898
int
20899
ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
20900
0
{
20901
0
  size_t rndup = nelems % X_ALIGN;
20902
20903
0
  if (rndup)
20904
0
    rndup = X_ALIGN - rndup;
20905
20906
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20907
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20908
20909
0
  if (rndup)
20910
0
  {
20911
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
20912
0
    *xpp = (void *)((char *)(*xpp) + rndup);
20913
0
  }
20914
20915
0
  return NC_NOERR;
20916
20917
0
}