Coverage Report

Created: 2025-10-28 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/netcdf-c/build/libsrc/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
371k
#define SWAP4(a) ( ((a) << 24) | \
207
371k
                  (((a) <<  8) & 0x00ff0000) | \
208
371k
                  (((a) >>  8) & 0x0000ff00) | \
209
371k
                  (((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
    uint16_t *op = (uint16_t*) dst;
230
0
    uint16_t *ip = (uint16_t*) 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[i], sizeof(tmp));
235
0
        tmp = SWAP2(tmp);
236
0
        memcpy(&op[i], &tmp, sizeof(tmp));
237
0
    }
238
0
}
239
240
# ifndef vax
241
inline static void
242
swap4b(void *dst, const void *src)
243
0
{
244
0
    uint32_t tmp;
245
    /* memcpy is used to handle the case of unaligned memory */
246
0
    memcpy(&tmp, src, sizeof(tmp));
247
0
    tmp = SWAP4(tmp);
248
0
    memcpy(dst, &tmp, 4);
249
0
}
250
# endif /* !vax */
251
252
inline static void
253
swapn4b(void *dst, const void *src, size_t nn)
254
141k
{
255
141k
    size_t i;
256
141k
    uint32_t *op = (uint32_t*) dst;
257
141k
    uint32_t *ip = (uint32_t*) src;
258
141k
    uint32_t tmp;
259
513k
    for (i=0; i<nn; i++) {
260
        /* memcpy is used to handle the case of unaligned memory */
261
371k
        memcpy(&tmp, &ip[i], sizeof(tmp));
262
371k
        tmp = SWAP4(tmp);
263
371k
        memcpy(&op[i], &tmp, sizeof(tmp));
264
371k
    }
265
141k
}
266
267
# ifndef vax
268
inline static void
269
swap8b(void *dst, const void *src)
270
0
{
271
0
    uint64_t tmp;
272
    /* memcpy is used to handle the case of unaligned memory */
273
0
    memcpy(&tmp, src, sizeof(tmp));
274
0
    tmp = SWAP8(tmp);
275
0
    memcpy(dst, &tmp, 8);
276
0
}
277
# endif /* !vax */
278
279
# ifndef vax
280
inline static void
281
swapn8b(void *dst, const void *src, size_t nn)
282
0
{
283
0
    size_t i;
284
0
    uint64_t *op = (uint64_t*) dst;
285
0
    uint64_t *ip = (uint64_t*) src;
286
0
    uint64_t tmp;
287
0
    for (i=0; i<nn; i++) {
288
        /* memcpy is used to handle the case of unaligned memory */
289
0
        memcpy(&tmp, &ip[i], sizeof(tmp));
290
0
        tmp = SWAP8(tmp);
291
0
        memcpy(&op[i], &tmp, sizeof(tmp));
292
0
    }
293
0
}
294
# endif /* !vax */
295
296
#endif /* LITTLE_ENDIAN */
297
298
299
300
301
302
303
/*
304
 * Primitive numeric conversion functions.
305
 */
306
307
308
309
310
311
/* x_schar */
312
/* x_uchar */
313
314
/* We don't implement any x_schar and x_uchar primitives. */
315
316
317
/* external NC_SHORT --------------------------------------------------------*/
318
319
#if SHORT_MAX == X_SHORT_MAX
320
typedef short ix_short;
321
#define SIZEOF_IX_SHORT SIZEOF_SHORT
322
0
#define IX_SHORT_MAX SHORT_MAX
323
#elif INT_MAX >= X_SHORT_MAX
324
typedef int ix_short;
325
#define SIZEOF_IX_SHORT SIZEOF_INT
326
#define IX_SHORT_MAX INT_MAX
327
#elif LONG_MAX >= X_SHORT_MAX
328
typedef long ix_short;
329
#define SIZEOF_IX_SHORT SIZEOF_LONG
330
#define IX_SHORT_MAX LONG_MAX
331
#elif LLONG_MAX >= X_SHORT_MAX
332
typedef long long ix_short;
333
#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
334
#define IX_SHORT_MAX LLONG_MAX
335
#else
336
#error "ix_short implementation"
337
#endif
338
339
static void
340
get_ix_short(const void *xp, ix_short *ip)
341
0
{
342
0
  const uchar *cp = (const uchar *) xp;
343
0
  *ip = (ix_short)(*cp++ << 8);
344
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
345
  if (*ip & 0x8000)
346
  {
347
    /* extern is negative */
348
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
349
  }
350
#endif
351
0
  *ip = (ix_short)(*ip | *cp);
352
0
}
353
354
static void
355
put_ix_short(void *xp, const ix_short *ip)
356
0
{
357
0
  uchar *cp = (uchar *) xp;
358
0
  *cp++ = (uchar)((*ip) >> 8);
359
0
  *cp   = (uchar)((*ip) & 0xff);
360
0
}
361
362
static int
363
ncx_get_short_schar(const void *xp, schar *ip)
364
0
{
365
0
    int err=NC_NOERR;
366
0
    ix_short xx = 0;
367
0
    get_ix_short(xp, &xx);
368
369
0
#if IX_SHORT_MAX > SCHAR_MAX
370
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
371
0
#ifdef ERANGE_FILL
372
0
        *ip = NC_FILL_BYTE;
373
0
        return NC_ERANGE;
374
#else
375
        err = NC_ERANGE;
376
#endif
377
0
    }
378
0
#endif
379
380
381
0
    *ip = (schar) xx;
382
0
    return err;
383
0
}
384
385
static int
386
ncx_get_short_short(const void *xp, short *ip)
387
0
{
388
0
    int err=NC_NOERR;
389
0
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
390
0
    get_ix_short(xp, (ix_short *)ip);
391
#else
392
    ix_short xx = 0;
393
    get_ix_short(xp, &xx);
394
395
#if IX_SHORT_MAX > SHORT_MAX
396
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
397
#ifdef ERANGE_FILL
398
        *ip = NC_FILL_SHORT;
399
        return NC_ERANGE;
400
#else
401
        err = NC_ERANGE;
402
#endif
403
    }
404
#endif
405
406
407
    *ip = (short) xx;
408
#endif
409
0
    return err;
410
0
}
411
412
static int
413
ncx_get_short_int(const void *xp, int *ip)
414
0
{
415
0
    int err=NC_NOERR;
416
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
417
    get_ix_short(xp, (ix_short *)ip);
418
#else
419
0
    ix_short xx = 0;
420
0
    get_ix_short(xp, &xx);
421
422
#if IX_SHORT_MAX > INT_MAX
423
    if (xx > INT_MAX || xx < INT_MIN) {
424
#ifdef ERANGE_FILL
425
        *ip = NC_FILL_INT;
426
        return NC_ERANGE;
427
#else
428
        err = NC_ERANGE;
429
#endif
430
    }
431
#endif
432
433
434
0
    *ip = (int) xx;
435
0
#endif
436
0
    return err;
437
0
}
438
439
static int
440
ncx_get_short_long(const void *xp, long *ip)
441
0
{
442
0
    int err=NC_NOERR;
443
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
444
    get_ix_short(xp, (ix_short *)ip);
445
#else
446
0
    ix_short xx = 0;
447
0
    get_ix_short(xp, &xx);
448
449
#if IX_SHORT_MAX > LONG_MAX
450
    if (xx > LONG_MAX || xx < LONG_MIN) {
451
#ifdef ERANGE_FILL
452
        *ip = NC_FILL_INT;
453
        return NC_ERANGE;
454
#else
455
        err = NC_ERANGE;
456
#endif
457
    }
458
#endif
459
460
461
0
    *ip = (long) xx;
462
0
#endif
463
0
    return err;
464
0
}
465
466
static int
467
ncx_get_short_longlong(const void *xp, longlong *ip)
468
0
{
469
0
    int err=NC_NOERR;
470
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
471
    get_ix_short(xp, (ix_short *)ip);
472
#else
473
0
    ix_short xx = 0;
474
0
    get_ix_short(xp, &xx);
475
476
#if IX_SHORT_MAX > LONGLONG_MAX
477
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
478
#ifdef ERANGE_FILL
479
        *ip = NC_FILL_INT64;
480
        return NC_ERANGE;
481
#else
482
        err = NC_ERANGE;
483
#endif
484
    }
485
#endif
486
487
488
0
    *ip = (longlong) xx;
489
0
#endif
490
0
    return err;
491
0
}
492
493
static int
494
ncx_get_short_ushort(const void *xp, ushort *ip)
495
0
{
496
0
    int err=NC_NOERR;
497
0
    ix_short xx = 0;
498
0
    get_ix_short(xp, &xx);
499
500
#if IX_SHORT_MAX > USHORT_MAX
501
    if (xx > USHORT_MAX) {
502
#ifdef ERANGE_FILL
503
        *ip = NC_FILL_USHORT;
504
        return NC_ERANGE;
505
#else
506
        err = NC_ERANGE;
507
#endif
508
    }
509
#endif
510
511
0
    if (xx < 0) {
512
0
#ifdef ERANGE_FILL
513
0
        *ip = NC_FILL_USHORT;
514
0
        return NC_ERANGE;
515
#else
516
        err = NC_ERANGE; /* because ip is unsigned */
517
#endif
518
0
    }
519
0
    *ip = (ushort) xx;
520
0
    return err;
521
0
}
522
523
static int
524
ncx_get_short_uchar(const void *xp, uchar *ip)
525
0
{
526
0
    int err=NC_NOERR;
527
0
    ix_short xx = 0;
528
0
    get_ix_short(xp, &xx);
529
530
0
#if IX_SHORT_MAX > UCHAR_MAX
531
0
    if (xx > UCHAR_MAX) {
532
0
#ifdef ERANGE_FILL
533
0
        *ip = NC_FILL_UBYTE;
534
0
        return NC_ERANGE;
535
#else
536
        err = NC_ERANGE;
537
#endif
538
0
    }
539
0
#endif
540
541
0
    if (xx < 0) {
542
0
#ifdef ERANGE_FILL
543
0
        *ip = NC_FILL_UBYTE;
544
0
        return NC_ERANGE;
545
#else
546
        err = NC_ERANGE; /* because ip is unsigned */
547
#endif
548
0
    }
549
0
    *ip = (uchar) xx;
550
0
    return err;
551
0
}
552
553
static int
554
ncx_get_short_uint(const void *xp, uint *ip)
555
0
{
556
0
    int err=NC_NOERR;
557
0
    ix_short xx = 0;
558
0
    get_ix_short(xp, &xx);
559
560
#if IX_SHORT_MAX > UINT_MAX
561
    if (xx > UINT_MAX) {
562
#ifdef ERANGE_FILL
563
        *ip = NC_FILL_UINT;
564
        return NC_ERANGE;
565
#else
566
        err = NC_ERANGE;
567
#endif
568
    }
569
#endif
570
571
0
    if (xx < 0) {
572
0
#ifdef ERANGE_FILL
573
0
        *ip = NC_FILL_UINT;
574
0
        return NC_ERANGE;
575
#else
576
        err = NC_ERANGE; /* because ip is unsigned */
577
#endif
578
0
    }
579
0
    *ip = (uint) xx;
580
0
    return err;
581
0
}
582
583
static int
584
ncx_get_short_ulonglong(const void *xp, ulonglong *ip)
585
0
{
586
0
    int err=NC_NOERR;
587
0
    ix_short xx = 0;
588
0
    get_ix_short(xp, &xx);
589
590
#if IX_SHORT_MAX > ULONGLONG_MAX
591
    if (xx > ULONGLONG_MAX) {
592
#ifdef ERANGE_FILL
593
        *ip = NC_FILL_UINT64;
594
        return NC_ERANGE;
595
#else
596
        err = NC_ERANGE;
597
#endif
598
    }
599
#endif
600
601
0
    if (xx < 0) {
602
0
#ifdef ERANGE_FILL
603
0
        *ip = NC_FILL_UINT64;
604
0
        return NC_ERANGE;
605
#else
606
        err = NC_ERANGE; /* because ip is unsigned */
607
#endif
608
0
    }
609
0
    *ip = (ulonglong) xx;
610
0
    return err;
611
0
}
612
613
static int
614
ncx_get_short_float(const void *xp, float *ip)
615
0
{
616
0
  ix_short xx = 0;
617
0
  get_ix_short(xp, &xx);
618
0
  *ip = (float)xx;
619
0
  return NC_NOERR;
620
0
}
621
622
static int
623
ncx_get_short_double(const void *xp, double *ip)
624
0
{
625
0
  ix_short xx = 0;
626
0
  get_ix_short(xp, &xx);
627
0
  *ip = (double)xx;
628
0
  return NC_NOERR;
629
0
}
630
631
632
static int
633
ncx_put_short_schar(void *xp, const schar *ip, void *fillp)
634
0
{
635
0
  uchar *cp = (uchar *) xp;
636
0
  if (*ip & 0x80)
637
0
    *cp++ = 0xff;
638
0
  else
639
0
    *cp++ = 0;
640
0
  *cp = (uchar)*ip;
641
0
  return NC_NOERR;
642
0
}
643
644
static int
645
ncx_put_short_uchar(void *xp, const uchar *ip, void *fillp)
646
0
{
647
0
  uchar *cp = (uchar *) xp;
648
0
  *cp++ = 0;
649
0
  *cp = *ip;
650
0
  return NC_NOERR;
651
0
}
652
653
static int
654
ncx_put_short_short(void *xp, const short *ip, void *fillp)
655
0
{
656
0
    int err=NC_NOERR;
657
0
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
658
0
    put_ix_short(xp, (const ix_short *)ip);
659
#else
660
    ix_short xx = NC_FILL_SHORT;
661
662
#if IX_SHORT_MAX < SHORT_MAX
663
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
664
        
665
#ifdef ERANGE_FILL
666
            if (fillp != NULL) memcpy(&xx, fillp, 2);
667
#endif
668
        err = NC_ERANGE;
669
    }
670
#ifdef ERANGE_FILL
671
    else
672
#endif
673
#endif
674
        xx = (ix_short)*ip;
675
676
    put_ix_short(xp, &xx);
677
#endif
678
0
    return err;
679
0
}
680
681
static int
682
ncx_put_short_int(void *xp, const int *ip, void *fillp)
683
0
{
684
0
    int err=NC_NOERR;
685
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
686
    put_ix_short(xp, (const ix_short *)ip);
687
#else
688
0
    ix_short xx = NC_FILL_SHORT;
689
690
0
#if IX_SHORT_MAX < INT_MAX
691
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
692
        
693
0
#ifdef ERANGE_FILL
694
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
695
0
#endif
696
0
        err = NC_ERANGE;
697
0
    }
698
0
#ifdef ERANGE_FILL
699
0
    else
700
0
#endif
701
0
#endif
702
0
        xx = (ix_short)*ip;
703
704
0
    put_ix_short(xp, &xx);
705
0
#endif
706
0
    return err;
707
0
}
708
709
static int
710
ncx_put_short_long(void *xp, const long *ip, void *fillp)
711
0
{
712
0
    int err=NC_NOERR;
713
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
714
    put_ix_short(xp, (const ix_short *)ip);
715
#else
716
0
    ix_short xx = NC_FILL_SHORT;
717
718
0
#if IX_SHORT_MAX < LONG_MAX
719
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
720
        
721
0
#ifdef ERANGE_FILL
722
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
723
0
#endif
724
0
        err = NC_ERANGE;
725
0
    }
726
0
#ifdef ERANGE_FILL
727
0
    else
728
0
#endif
729
0
#endif
730
0
        xx = (ix_short)*ip;
731
732
0
    put_ix_short(xp, &xx);
733
0
#endif
734
0
    return err;
735
0
}
736
737
static int
738
ncx_put_short_longlong(void *xp, const longlong *ip, void *fillp)
739
0
{
740
0
    int err=NC_NOERR;
741
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
742
    put_ix_short(xp, (const ix_short *)ip);
743
#else
744
0
    ix_short xx = NC_FILL_SHORT;
745
746
0
#if IX_SHORT_MAX < LONGLONG_MAX
747
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
748
        
749
0
#ifdef ERANGE_FILL
750
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
751
0
#endif
752
0
        err = NC_ERANGE;
753
0
    }
754
0
#ifdef ERANGE_FILL
755
0
    else
756
0
#endif
757
0
#endif
758
0
        xx = (ix_short)*ip;
759
760
0
    put_ix_short(xp, &xx);
761
0
#endif
762
0
    return err;
763
0
}
764
765
static int
766
ncx_put_short_ushort(void *xp, const ushort *ip, void *fillp)
767
0
{
768
0
    int err=NC_NOERR;
769
0
    ix_short xx = NC_FILL_SHORT;
770
771
0
#if IX_SHORT_MAX < USHORT_MAX
772
0
    if (*ip > IX_SHORT_MAX) {
773
        
774
0
#ifdef ERANGE_FILL
775
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
776
0
#endif
777
0
        err = NC_ERANGE;
778
0
    }
779
0
#ifdef ERANGE_FILL
780
0
    else
781
0
#endif
782
0
#endif
783
0
        xx = (ix_short)*ip;
784
785
0
    put_ix_short(xp, &xx);
786
0
    return err;
787
0
}
788
789
static int
790
ncx_put_short_uint(void *xp, const uint *ip, void *fillp)
791
0
{
792
0
    int err=NC_NOERR;
793
0
    ix_short xx = NC_FILL_SHORT;
794
795
0
#if IX_SHORT_MAX < UINT_MAX
796
0
    if (*ip > IX_SHORT_MAX) {
797
        
798
0
#ifdef ERANGE_FILL
799
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
800
0
#endif
801
0
        err = NC_ERANGE;
802
0
    }
803
0
#ifdef ERANGE_FILL
804
0
    else
805
0
#endif
806
0
#endif
807
0
        xx = (ix_short)*ip;
808
809
0
    put_ix_short(xp, &xx);
810
0
    return err;
811
0
}
812
813
static int
814
ncx_put_short_ulonglong(void *xp, const ulonglong *ip, void *fillp)
815
0
{
816
0
    int err=NC_NOERR;
817
0
    ix_short xx = NC_FILL_SHORT;
818
819
0
#if IX_SHORT_MAX < ULONGLONG_MAX
820
0
    if (*ip > IX_SHORT_MAX) {
821
        
822
0
#ifdef ERANGE_FILL
823
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
824
0
#endif
825
0
        err = NC_ERANGE;
826
0
    }
827
0
#ifdef ERANGE_FILL
828
0
    else
829
0
#endif
830
0
#endif
831
0
        xx = (ix_short)*ip;
832
833
0
    put_ix_short(xp, &xx);
834
0
    return err;
835
0
}
836
837
static int
838
ncx_put_short_float(void *xp, const float *ip, void *fillp)
839
0
{
840
0
    int err=NC_NOERR;
841
0
    ix_short xx = NC_FILL_SHORT;
842
843
0
    if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
844
        
845
0
#ifdef ERANGE_FILL
846
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
847
0
#endif
848
0
        err = NC_ERANGE;
849
0
    }
850
0
#ifdef ERANGE_FILL
851
0
    else
852
0
#endif
853
0
        xx = (ix_short)*ip;
854
855
0
    put_ix_short(xp, &xx);
856
0
    return err;
857
0
}
858
859
static int
860
ncx_put_short_double(void *xp, const double *ip, void *fillp)
861
0
{
862
0
    int err=NC_NOERR;
863
0
    ix_short xx = NC_FILL_SHORT;
864
865
0
    if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) {
866
        
867
0
#ifdef ERANGE_FILL
868
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
869
0
#endif
870
0
        err = NC_ERANGE;
871
0
    }
872
0
#ifdef ERANGE_FILL
873
0
    else
874
0
#endif
875
0
        xx = (ix_short)*ip;
876
877
0
    put_ix_short(xp, &xx);
878
0
    return err;
879
0
}
880
881
882
/* external NC_USHORT -------------------------------------------------------*/
883
884
#if USHORT_MAX == X_USHORT_MAX
885
typedef unsigned short ix_ushort;
886
#define SIZEOF_IX_USHORT SIZEOF_USHORT
887
0
#define IX_USHORT_MAX USHORT_MAX
888
#elif UINT_MAX >= X_USHORT_MAX
889
typedef unsigned int ix_ushort;
890
#define SIZEOF_IX_USHORT SIZEOF_UINT
891
#define IX_USHORT_MAX UINT_MAX
892
#elif ULONG_MAX >= X_USHORT_MAX
893
typedef unsigned long ix_ushort;
894
#define SIZEOF_IX_USHORT SIZEOF_ULONG
895
#define IX_USHORT_MAX ULONG_MAX
896
#elif ULLONG_MAX >= X_USHORT_MAX
897
typedef unsigned long long ix_ushort;
898
#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
899
#define IX_USHORT_MAX ULLONG_MAX
900
#else
901
#error "ix_ushort implementation"
902
#endif
903
904
static void
905
get_ix_ushort(const void *xp, ix_ushort *ip)
906
0
{
907
0
  const uchar *cp = (const uchar *) xp;
908
0
  *ip = (ix_ushort)(*cp++ << 8);
909
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
910
  if (*ip & 0x8000)
911
  {
912
    /* extern is negative */
913
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
914
  }
915
#endif
916
0
  *ip = (ix_ushort)(*ip | *cp);
917
0
}
918
919
static void
920
put_ix_ushort(void *xp, const ix_ushort *ip)
921
0
{
922
0
  uchar *cp = (uchar *) xp;
923
0
  *cp++ = (uchar)((*ip) >> 8);
924
0
  *cp   = (uchar)((*ip) & 0xff);
925
0
}
926
927
static int
928
ncx_get_ushort_schar(const void *xp, schar *ip)
929
0
{
930
0
    int err=NC_NOERR;
931
0
    ix_ushort xx = 0;
932
0
    get_ix_ushort(xp, &xx);
933
934
0
#if IX_USHORT_MAX > SCHAR_MAX
935
0
    if (xx > SCHAR_MAX) {
936
0
#ifdef ERANGE_FILL
937
0
        *ip = NC_FILL_BYTE;
938
0
        return NC_ERANGE;
939
#else
940
        err = NC_ERANGE;
941
#endif
942
0
    }
943
0
#endif
944
945
946
0
    *ip = (schar) xx;
947
0
    return err;
948
0
}
949
950
static int
951
ncx_get_ushort_short(const void *xp, short *ip)
952
0
{
953
0
    int err=NC_NOERR;
954
0
    ix_ushort xx = 0;
955
0
    get_ix_ushort(xp, &xx);
956
957
0
#if IX_USHORT_MAX > SHORT_MAX
958
0
    if (xx > SHORT_MAX) {
959
0
#ifdef ERANGE_FILL
960
0
        *ip = NC_FILL_SHORT;
961
0
        return NC_ERANGE;
962
#else
963
        err = NC_ERANGE;
964
#endif
965
0
    }
966
0
#endif
967
968
969
0
    *ip = (short) xx;
970
0
    return err;
971
0
}
972
973
static int
974
ncx_get_ushort_int(const void *xp, int *ip)
975
0
{
976
0
    int err=NC_NOERR;
977
0
    ix_ushort xx = 0;
978
0
    get_ix_ushort(xp, &xx);
979
980
#if IX_USHORT_MAX > INT_MAX
981
    if (xx > INT_MAX) {
982
#ifdef ERANGE_FILL
983
        *ip = NC_FILL_INT;
984
        return NC_ERANGE;
985
#else
986
        err = NC_ERANGE;
987
#endif
988
    }
989
#endif
990
991
992
0
    *ip = (int) xx;
993
0
    return err;
994
0
}
995
996
static int
997
ncx_get_ushort_long(const void *xp, long *ip)
998
0
{
999
0
    int err=NC_NOERR;
1000
0
    ix_ushort xx = 0;
1001
0
    get_ix_ushort(xp, &xx);
1002
1003
#if IX_USHORT_MAX > LONG_MAX
1004
    if (xx > LONG_MAX) {
1005
#ifdef ERANGE_FILL
1006
        *ip = NC_FILL_INT;
1007
        return NC_ERANGE;
1008
#else
1009
        err = NC_ERANGE;
1010
#endif
1011
    }
1012
#endif
1013
1014
1015
0
    *ip = (long) xx;
1016
0
    return err;
1017
0
}
1018
1019
static int
1020
ncx_get_ushort_longlong(const void *xp, longlong *ip)
1021
0
{
1022
0
    int err=NC_NOERR;
1023
0
    ix_ushort xx = 0;
1024
0
    get_ix_ushort(xp, &xx);
1025
1026
#if IX_USHORT_MAX > LONGLONG_MAX
1027
    if (xx > LONGLONG_MAX) {
1028
#ifdef ERANGE_FILL
1029
        *ip = NC_FILL_INT64;
1030
        return NC_ERANGE;
1031
#else
1032
        err = NC_ERANGE;
1033
#endif
1034
    }
1035
#endif
1036
1037
1038
0
    *ip = (longlong) xx;
1039
0
    return err;
1040
0
}
1041
1042
static int
1043
ncx_get_ushort_ushort(const void *xp, ushort *ip)
1044
0
{
1045
0
    int err=NC_NOERR;
1046
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1047
0
    get_ix_ushort(xp, (ix_ushort *)ip);
1048
#else
1049
    ix_ushort xx = 0;
1050
    get_ix_ushort(xp, &xx);
1051
1052
#if IX_USHORT_MAX > USHORT_MAX
1053
    if (xx > USHORT_MAX) {
1054
#ifdef ERANGE_FILL
1055
        *ip = NC_FILL_USHORT;
1056
        return NC_ERANGE;
1057
#else
1058
        err = NC_ERANGE;
1059
#endif
1060
    }
1061
#endif
1062
1063
1064
    *ip = (ushort) xx;
1065
#endif
1066
0
    return err;
1067
0
}
1068
1069
static int
1070
ncx_get_ushort_uchar(const void *xp, uchar *ip)
1071
0
{
1072
0
    int err=NC_NOERR;
1073
#if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
1074
    get_ix_ushort(xp, (ix_ushort *)ip);
1075
#else
1076
0
    ix_ushort xx = 0;
1077
0
    get_ix_ushort(xp, &xx);
1078
1079
0
#if IX_USHORT_MAX > UCHAR_MAX
1080
0
    if (xx > UCHAR_MAX) {
1081
0
#ifdef ERANGE_FILL
1082
0
        *ip = NC_FILL_UBYTE;
1083
0
        return NC_ERANGE;
1084
#else
1085
        err = NC_ERANGE;
1086
#endif
1087
0
    }
1088
0
#endif
1089
1090
1091
0
    *ip = (uchar) xx;
1092
0
#endif
1093
0
    return err;
1094
0
}
1095
1096
static int
1097
ncx_get_ushort_uint(const void *xp, uint *ip)
1098
0
{
1099
0
    int err=NC_NOERR;
1100
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1101
    get_ix_ushort(xp, (ix_ushort *)ip);
1102
#else
1103
0
    ix_ushort xx = 0;
1104
0
    get_ix_ushort(xp, &xx);
1105
1106
#if IX_USHORT_MAX > UINT_MAX
1107
    if (xx > UINT_MAX) {
1108
#ifdef ERANGE_FILL
1109
        *ip = NC_FILL_UINT;
1110
        return NC_ERANGE;
1111
#else
1112
        err = NC_ERANGE;
1113
#endif
1114
    }
1115
#endif
1116
1117
1118
0
    *ip = (uint) xx;
1119
0
#endif
1120
0
    return err;
1121
0
}
1122
1123
static int
1124
ncx_get_ushort_ulonglong(const void *xp, ulonglong *ip)
1125
0
{
1126
0
    int err=NC_NOERR;
1127
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1128
    get_ix_ushort(xp, (ix_ushort *)ip);
1129
#else
1130
0
    ix_ushort xx = 0;
1131
0
    get_ix_ushort(xp, &xx);
1132
1133
#if IX_USHORT_MAX > ULONGLONG_MAX
1134
    if (xx > ULONGLONG_MAX) {
1135
#ifdef ERANGE_FILL
1136
        *ip = NC_FILL_UINT64;
1137
        return NC_ERANGE;
1138
#else
1139
        err = NC_ERANGE;
1140
#endif
1141
    }
1142
#endif
1143
1144
1145
0
    *ip = (ulonglong) xx;
1146
0
#endif
1147
0
    return err;
1148
0
}
1149
1150
static int
1151
ncx_get_ushort_float(const void *xp, float *ip)
1152
0
{
1153
0
  ix_ushort xx = 0;
1154
0
  get_ix_ushort(xp, &xx);
1155
0
  *ip = (float)xx;
1156
0
  return NC_NOERR;
1157
0
}
1158
1159
static int
1160
ncx_get_ushort_double(const void *xp, double *ip)
1161
0
{
1162
0
  ix_ushort xx = 0;
1163
0
  get_ix_ushort(xp, &xx);
1164
0
  *ip = (double)xx;
1165
0
  return NC_NOERR;
1166
0
}
1167
1168
1169
static int
1170
ncx_put_ushort_schar(void *xp, const schar *ip, void *fillp)
1171
0
{
1172
0
    int err=NC_NOERR;
1173
0
    uchar *cp;
1174
0
    if (*ip < 0) {
1175
0
#ifdef ERANGE_FILL
1176
0
        if (fillp != NULL) memcpy(xp, fillp, 2);
1177
0
#ifndef WORDS_BIGENDIAN
1178
0
        swapn2b(xp, xp, 1);
1179
0
#endif
1180
0
        return NC_ERANGE;
1181
#else
1182
        err = NC_ERANGE;
1183
#endif
1184
0
    }
1185
1186
0
    cp = (uchar *) xp;
1187
0
    if (*ip & 0x80)
1188
0
        *cp++ = 0xff;
1189
0
    else
1190
0
        *cp++ = 0;
1191
0
    *cp = (uchar)*ip;
1192
1193
0
    return err;
1194
0
}
1195
1196
static int
1197
ncx_put_ushort_uchar(void *xp, const uchar *ip, void *fillp)
1198
0
{
1199
0
  uchar *cp = (uchar *) xp;
1200
0
  *cp++ = 0;
1201
0
  *cp = *ip;
1202
0
  return NC_NOERR;
1203
0
}
1204
1205
static int
1206
ncx_put_ushort_short(void *xp, const short *ip, void *fillp)
1207
0
{
1208
0
    int err=NC_NOERR;
1209
0
    ix_ushort xx = NC_FILL_USHORT;
1210
1211
#if IX_USHORT_MAX < SHORT_MAX
1212
    if (*ip > IX_USHORT_MAX) {
1213
        
1214
#ifdef ERANGE_FILL
1215
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1216
#endif
1217
        err = NC_ERANGE;
1218
    }
1219
#ifdef ERANGE_FILL
1220
    else
1221
#endif
1222
#endif
1223
0
    if (*ip < 0) {
1224
        
1225
0
#ifdef ERANGE_FILL
1226
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1227
0
#endif
1228
0
        err = NC_ERANGE; /* because xp is unsigned */
1229
0
    }
1230
0
#ifdef ERANGE_FILL
1231
0
    else
1232
0
#endif
1233
0
        xx = (ix_ushort)*ip;
1234
1235
0
    put_ix_ushort(xp, &xx);
1236
0
    return err;
1237
0
}
1238
1239
static int
1240
ncx_put_ushort_int(void *xp, const int *ip, void *fillp)
1241
0
{
1242
0
    int err=NC_NOERR;
1243
0
    ix_ushort xx = NC_FILL_USHORT;
1244
1245
0
#if IX_USHORT_MAX < INT_MAX
1246
0
    if (*ip > IX_USHORT_MAX) {
1247
        
1248
0
#ifdef ERANGE_FILL
1249
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1250
0
#endif
1251
0
        err = NC_ERANGE;
1252
0
    }
1253
0
#ifdef ERANGE_FILL
1254
0
    else
1255
0
#endif
1256
0
#endif
1257
0
    if (*ip < 0) {
1258
        
1259
0
#ifdef ERANGE_FILL
1260
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1261
0
#endif
1262
0
        err = NC_ERANGE; /* because xp is unsigned */
1263
0
    }
1264
0
#ifdef ERANGE_FILL
1265
0
    else
1266
0
#endif
1267
0
        xx = (ix_ushort)*ip;
1268
1269
0
    put_ix_ushort(xp, &xx);
1270
0
    return err;
1271
0
}
1272
1273
static int
1274
ncx_put_ushort_long(void *xp, const long *ip, void *fillp)
1275
0
{
1276
0
    int err=NC_NOERR;
1277
0
    ix_ushort xx = NC_FILL_USHORT;
1278
1279
0
#if IX_USHORT_MAX < LONG_MAX
1280
0
    if (*ip > IX_USHORT_MAX) {
1281
        
1282
0
#ifdef ERANGE_FILL
1283
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1284
0
#endif
1285
0
        err = NC_ERANGE;
1286
0
    }
1287
0
#ifdef ERANGE_FILL
1288
0
    else
1289
0
#endif
1290
0
#endif
1291
0
    if (*ip < 0) {
1292
        
1293
0
#ifdef ERANGE_FILL
1294
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1295
0
#endif
1296
0
        err = NC_ERANGE; /* because xp is unsigned */
1297
0
    }
1298
0
#ifdef ERANGE_FILL
1299
0
    else
1300
0
#endif
1301
0
        xx = (ix_ushort)*ip;
1302
1303
0
    put_ix_ushort(xp, &xx);
1304
0
    return err;
1305
0
}
1306
1307
static int
1308
ncx_put_ushort_longlong(void *xp, const longlong *ip, void *fillp)
1309
0
{
1310
0
    int err=NC_NOERR;
1311
0
    ix_ushort xx = NC_FILL_USHORT;
1312
1313
0
#if IX_USHORT_MAX < LONGLONG_MAX
1314
0
    if (*ip > IX_USHORT_MAX) {
1315
        
1316
0
#ifdef ERANGE_FILL
1317
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1318
0
#endif
1319
0
        err = NC_ERANGE;
1320
0
    }
1321
0
#ifdef ERANGE_FILL
1322
0
    else
1323
0
#endif
1324
0
#endif
1325
0
    if (*ip < 0) {
1326
        
1327
0
#ifdef ERANGE_FILL
1328
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1329
0
#endif
1330
0
        err = NC_ERANGE; /* because xp is unsigned */
1331
0
    }
1332
0
#ifdef ERANGE_FILL
1333
0
    else
1334
0
#endif
1335
0
        xx = (ix_ushort)*ip;
1336
1337
0
    put_ix_ushort(xp, &xx);
1338
0
    return err;
1339
0
}
1340
1341
static int
1342
ncx_put_ushort_ushort(void *xp, const ushort *ip, void *fillp)
1343
0
{
1344
0
    int err=NC_NOERR;
1345
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1346
0
    put_ix_ushort(xp, (const ix_ushort *)ip);
1347
#else
1348
    ix_ushort xx = NC_FILL_USHORT;
1349
1350
#if IX_USHORT_MAX < USHORT_MAX
1351
    if (*ip > IX_USHORT_MAX) {
1352
        
1353
#ifdef ERANGE_FILL
1354
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1355
#endif
1356
        err = NC_ERANGE;
1357
    }
1358
#ifdef ERANGE_FILL
1359
    else
1360
#endif
1361
#endif
1362
        xx = (ix_ushort)*ip;
1363
1364
    put_ix_ushort(xp, &xx);
1365
#endif
1366
0
    return err;
1367
0
}
1368
1369
static int
1370
ncx_put_ushort_uint(void *xp, const uint *ip, void *fillp)
1371
0
{
1372
0
    int err=NC_NOERR;
1373
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1374
    put_ix_ushort(xp, (const ix_ushort *)ip);
1375
#else
1376
0
    ix_ushort xx = NC_FILL_USHORT;
1377
1378
0
#if IX_USHORT_MAX < UINT_MAX
1379
0
    if (*ip > IX_USHORT_MAX) {
1380
        
1381
0
#ifdef ERANGE_FILL
1382
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1383
0
#endif
1384
0
        err = NC_ERANGE;
1385
0
    }
1386
0
#ifdef ERANGE_FILL
1387
0
    else
1388
0
#endif
1389
0
#endif
1390
0
        xx = (ix_ushort)*ip;
1391
1392
0
    put_ix_ushort(xp, &xx);
1393
0
#endif
1394
0
    return err;
1395
0
}
1396
1397
static int
1398
ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1399
0
{
1400
0
    int err=NC_NOERR;
1401
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1402
    put_ix_ushort(xp, (const ix_ushort *)ip);
1403
#else
1404
0
    ix_ushort xx = NC_FILL_USHORT;
1405
1406
0
#if IX_USHORT_MAX < ULONGLONG_MAX
1407
0
    if (*ip > IX_USHORT_MAX) {
1408
        
1409
0
#ifdef ERANGE_FILL
1410
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1411
0
#endif
1412
0
        err = NC_ERANGE;
1413
0
    }
1414
0
#ifdef ERANGE_FILL
1415
0
    else
1416
0
#endif
1417
0
#endif
1418
0
        xx = (ix_ushort)*ip;
1419
1420
0
    put_ix_ushort(xp, &xx);
1421
0
#endif
1422
0
    return err;
1423
0
}
1424
1425
static int
1426
ncx_put_ushort_float(void *xp, const float *ip, void *fillp)
1427
0
{
1428
0
    int err=NC_NOERR;
1429
0
    ix_ushort xx = NC_FILL_USHORT;
1430
1431
0
    if (*ip > (double)X_USHORT_MAX || *ip < 0) {
1432
        
1433
0
#ifdef ERANGE_FILL
1434
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1435
0
#endif
1436
0
        err = NC_ERANGE;
1437
0
    }
1438
0
#ifdef ERANGE_FILL
1439
0
    else
1440
0
#endif
1441
0
        xx = (ix_ushort)*ip;
1442
1443
0
    put_ix_ushort(xp, &xx);
1444
0
    return err;
1445
0
}
1446
1447
static int
1448
ncx_put_ushort_double(void *xp, const double *ip, void *fillp)
1449
0
{
1450
0
    int err=NC_NOERR;
1451
0
    ix_ushort xx = NC_FILL_USHORT;
1452
1453
0
    if (*ip > X_USHORT_MAX || *ip < 0) {
1454
        
1455
0
#ifdef ERANGE_FILL
1456
0
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1457
0
#endif
1458
0
        err = NC_ERANGE;
1459
0
    }
1460
0
#ifdef ERANGE_FILL
1461
0
    else
1462
0
#endif
1463
0
        xx = (ix_ushort)*ip;
1464
1465
0
    put_ix_ushort(xp, &xx);
1466
0
    return err;
1467
0
}
1468
1469
1470
/* external NC_INT ----------------------------------------------------------*/
1471
1472
#if SHORT_MAX == X_INT_MAX
1473
typedef short ix_int;
1474
#define SIZEOF_IX_INT SIZEOF_SHORT
1475
#define IX_INT_MAX SHORT_MAX
1476
#elif INT_MAX  >= X_INT_MAX
1477
typedef int ix_int;
1478
#define SIZEOF_IX_INT SIZEOF_INT
1479
0
#define IX_INT_MAX INT_MAX
1480
#elif LONG_MAX  >= X_INT_MAX
1481
typedef long ix_int;
1482
#define SIZEOF_IX_INT SIZEOF_LONG
1483
#define IX_INT_MAX LONG_MAX
1484
#else
1485
#error "ix_int implementation"
1486
#endif
1487
1488
1489
static void
1490
get_ix_int(const void *xp, ix_int *ip)
1491
0
{
1492
0
  const uchar *cp = (const uchar *) xp;
1493
1494
0
#if INT_MAX  >= X_INT_MAX
1495
0
  *ip = (ix_int)((unsigned)(*cp++) << 24);
1496
#else
1497
  *ip = *cp++ << 24;
1498
#endif
1499
#if SIZEOF_IX_INT > X_SIZEOF_INT
1500
  if (*ip & 0x80000000)
1501
  {
1502
    /* extern is negative */
1503
    *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
1504
  }
1505
#endif
1506
0
  *ip |= (*cp++ << 16);
1507
0
  *ip |= (*cp++ << 8);
1508
0
  *ip |= *cp;
1509
0
}
1510
1511
static void
1512
put_ix_int(void *xp, const ix_int *ip)
1513
0
{
1514
0
  uchar *cp = (uchar *) xp;
1515
1516
0
  *cp++ = (uchar)( (*ip) >> 24);
1517
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
1518
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
1519
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
1520
0
}
1521
1522
#if X_SIZEOF_INT != SIZEOF_INT
1523
static int
1524
ncx_get_int_int(const void *xp, int *ip)
1525
{
1526
    int err=NC_NOERR;
1527
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1528
    get_ix_int(xp, (ix_int *)ip);
1529
#else
1530
    ix_int xx = 0;
1531
    get_ix_int(xp, &xx);
1532
1533
#if IX_INT_MAX > INT_MAX
1534
    if (xx > INT_MAX || xx < INT_MIN) {
1535
#ifdef ERANGE_FILL
1536
        *ip = NC_FILL_INT;
1537
        return NC_ERANGE;
1538
#else
1539
        err = NC_ERANGE;
1540
#endif
1541
    }
1542
#endif
1543
1544
1545
    *ip = (int) xx;
1546
#endif
1547
    return err;
1548
}
1549
1550
#endif
1551
static int
1552
ncx_get_int_schar(const void *xp, schar *ip)
1553
0
{
1554
0
    int err=NC_NOERR;
1555
0
    ix_int xx = 0;
1556
0
    get_ix_int(xp, &xx);
1557
1558
0
#if IX_INT_MAX > SCHAR_MAX
1559
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
1560
0
#ifdef ERANGE_FILL
1561
0
        *ip = NC_FILL_BYTE;
1562
0
        return NC_ERANGE;
1563
#else
1564
        err = NC_ERANGE;
1565
#endif
1566
0
    }
1567
0
#endif
1568
1569
1570
0
    *ip = (schar) xx;
1571
0
    return err;
1572
0
}
1573
1574
static int
1575
ncx_get_int_short(const void *xp, short *ip)
1576
0
{
1577
0
    int err=NC_NOERR;
1578
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1579
    get_ix_int(xp, (ix_int *)ip);
1580
#else
1581
0
    ix_int xx = 0;
1582
0
    get_ix_int(xp, &xx);
1583
1584
0
#if IX_INT_MAX > SHORT_MAX
1585
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
1586
0
#ifdef ERANGE_FILL
1587
0
        *ip = NC_FILL_SHORT;
1588
0
        return NC_ERANGE;
1589
#else
1590
        err = NC_ERANGE;
1591
#endif
1592
0
    }
1593
0
#endif
1594
1595
1596
0
    *ip = (short) xx;
1597
0
#endif
1598
0
    return err;
1599
0
}
1600
1601
static int
1602
ncx_get_int_long(const void *xp, long *ip)
1603
0
{
1604
0
    int err=NC_NOERR;
1605
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1606
    get_ix_int(xp, (ix_int *)ip);
1607
#else
1608
0
    ix_int xx = 0;
1609
0
    get_ix_int(xp, &xx);
1610
1611
#if IX_INT_MAX > LONG_MAX
1612
    if (xx > LONG_MAX || xx < LONG_MIN) {
1613
#ifdef ERANGE_FILL
1614
        *ip = NC_FILL_INT;
1615
        return NC_ERANGE;
1616
#else
1617
        err = NC_ERANGE;
1618
#endif
1619
    }
1620
#endif
1621
1622
1623
0
    *ip = (long) xx;
1624
0
#endif
1625
0
    return err;
1626
0
}
1627
1628
static int
1629
ncx_get_int_longlong(const void *xp, longlong *ip)
1630
0
{
1631
0
    int err=NC_NOERR;
1632
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1633
    get_ix_int(xp, (ix_int *)ip);
1634
#else
1635
0
    ix_int xx = 0;
1636
0
    get_ix_int(xp, &xx);
1637
1638
#if IX_INT_MAX > LONGLONG_MAX
1639
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
1640
#ifdef ERANGE_FILL
1641
        *ip = NC_FILL_INT64;
1642
        return NC_ERANGE;
1643
#else
1644
        err = NC_ERANGE;
1645
#endif
1646
    }
1647
#endif
1648
1649
1650
0
    *ip = (longlong) xx;
1651
0
#endif
1652
0
    return err;
1653
0
}
1654
1655
static int
1656
ncx_get_int_ushort(const void *xp, ushort *ip)
1657
0
{
1658
0
    int err=NC_NOERR;
1659
0
    ix_int xx = 0;
1660
0
    get_ix_int(xp, &xx);
1661
1662
0
#if IX_INT_MAX > USHORT_MAX
1663
0
    if (xx > USHORT_MAX) {
1664
0
#ifdef ERANGE_FILL
1665
0
        *ip = NC_FILL_USHORT;
1666
0
        return NC_ERANGE;
1667
#else
1668
        err = NC_ERANGE;
1669
#endif
1670
0
    }
1671
0
#endif
1672
1673
0
    if (xx < 0) {
1674
0
#ifdef ERANGE_FILL
1675
0
        *ip = NC_FILL_USHORT;
1676
0
        return NC_ERANGE;
1677
#else
1678
        err = NC_ERANGE; /* because ip is unsigned */
1679
#endif
1680
0
    }
1681
0
    *ip = (ushort) xx;
1682
0
    return err;
1683
0
}
1684
1685
static int
1686
ncx_get_int_uchar(const void *xp, uchar *ip)
1687
0
{
1688
0
    int err=NC_NOERR;
1689
0
    ix_int xx = 0;
1690
0
    get_ix_int(xp, &xx);
1691
1692
0
#if IX_INT_MAX > UCHAR_MAX
1693
0
    if (xx > UCHAR_MAX) {
1694
0
#ifdef ERANGE_FILL
1695
0
        *ip = NC_FILL_UBYTE;
1696
0
        return NC_ERANGE;
1697
#else
1698
        err = NC_ERANGE;
1699
#endif
1700
0
    }
1701
0
#endif
1702
1703
0
    if (xx < 0) {
1704
0
#ifdef ERANGE_FILL
1705
0
        *ip = NC_FILL_UBYTE;
1706
0
        return NC_ERANGE;
1707
#else
1708
        err = NC_ERANGE; /* because ip is unsigned */
1709
#endif
1710
0
    }
1711
0
    *ip = (uchar) xx;
1712
0
    return err;
1713
0
}
1714
1715
static int
1716
ncx_get_int_uint(const void *xp, uint *ip)
1717
0
{
1718
0
    int err=NC_NOERR;
1719
0
    ix_int xx = 0;
1720
0
    get_ix_int(xp, &xx);
1721
1722
#if IX_INT_MAX > UINT_MAX
1723
    if (xx > UINT_MAX) {
1724
#ifdef ERANGE_FILL
1725
        *ip = NC_FILL_UINT;
1726
        return NC_ERANGE;
1727
#else
1728
        err = NC_ERANGE;
1729
#endif
1730
    }
1731
#endif
1732
1733
0
    if (xx < 0) {
1734
0
#ifdef ERANGE_FILL
1735
0
        *ip = NC_FILL_UINT;
1736
0
        return NC_ERANGE;
1737
#else
1738
        err = NC_ERANGE; /* because ip is unsigned */
1739
#endif
1740
0
    }
1741
0
    *ip = (uint) xx;
1742
0
    return err;
1743
0
}
1744
1745
static int
1746
ncx_get_int_ulonglong(const void *xp, ulonglong *ip)
1747
0
{
1748
0
    int err=NC_NOERR;
1749
0
    ix_int xx = 0;
1750
0
    get_ix_int(xp, &xx);
1751
1752
#if IX_INT_MAX > ULONGLONG_MAX
1753
    if (xx > ULONGLONG_MAX) {
1754
#ifdef ERANGE_FILL
1755
        *ip = NC_FILL_UINT64;
1756
        return NC_ERANGE;
1757
#else
1758
        err = NC_ERANGE;
1759
#endif
1760
    }
1761
#endif
1762
1763
0
    if (xx < 0) {
1764
0
#ifdef ERANGE_FILL
1765
0
        *ip = NC_FILL_UINT64;
1766
0
        return NC_ERANGE;
1767
#else
1768
        err = NC_ERANGE; /* because ip is unsigned */
1769
#endif
1770
0
    }
1771
0
    *ip = (ulonglong) xx;
1772
0
    return err;
1773
0
}
1774
1775
static int
1776
ncx_get_int_float(const void *xp, float *ip)
1777
0
{
1778
0
  ix_int xx = 0;
1779
0
  get_ix_int(xp, &xx);
1780
0
  *ip = (float)xx;
1781
0
  return NC_NOERR;
1782
0
}
1783
1784
static int
1785
ncx_get_int_double(const void *xp, double *ip)
1786
0
{
1787
0
  ix_int xx = 0;
1788
0
  get_ix_int(xp, &xx);
1789
0
  *ip = (double)xx;
1790
0
  return NC_NOERR;
1791
0
}
1792
1793
1794
static int
1795
ncx_put_int_schar(void *xp, const schar *ip, void *fillp)
1796
0
{
1797
0
  uchar *cp = (uchar *) xp;
1798
0
  if (*ip & 0x80)
1799
0
  {
1800
0
    *cp++ = 0xff;
1801
0
    *cp++ = 0xff;
1802
0
    *cp++ = 0xff;
1803
0
  }
1804
0
  else
1805
0
  {
1806
0
    *cp++ = 0x00;
1807
0
    *cp++ = 0x00;
1808
0
    *cp++ = 0x00;
1809
0
  }
1810
0
  *cp = (uchar)*ip;
1811
0
  return NC_NOERR;
1812
0
}
1813
1814
static int
1815
ncx_put_int_uchar(void *xp, const uchar *ip, void *fillp)
1816
0
{
1817
0
  uchar *cp = (uchar *) xp;
1818
0
  *cp++ = 0x00;
1819
0
  *cp++ = 0x00;
1820
0
  *cp++ = 0x00;
1821
0
  *cp   = *ip;
1822
0
  return NC_NOERR;
1823
0
}
1824
1825
#if X_SIZEOF_INT != SIZEOF_INT
1826
static int
1827
ncx_put_int_int(void *xp, const int *ip, void *fillp)
1828
{
1829
    int err=NC_NOERR;
1830
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1831
    put_ix_int(xp, (const ix_int *)ip);
1832
#else
1833
    ix_int xx = NC_FILL_INT;
1834
1835
#if IX_INT_MAX < INT_MAX
1836
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1837
        
1838
#ifdef ERANGE_FILL
1839
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1840
#endif
1841
        err = NC_ERANGE;
1842
    }
1843
#ifdef ERANGE_FILL
1844
    else
1845
#endif
1846
#endif
1847
        xx = (ix_int)*ip;
1848
1849
    put_ix_int(xp, &xx);
1850
#endif
1851
    return err;
1852
}
1853
1854
#endif
1855
static int
1856
ncx_put_int_short(void *xp, const short *ip, void *fillp)
1857
0
{
1858
0
    int err=NC_NOERR;
1859
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1860
    put_ix_int(xp, (const ix_int *)ip);
1861
#else
1862
0
    ix_int xx = NC_FILL_INT;
1863
1864
#if IX_INT_MAX < SHORT_MAX
1865
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1866
        
1867
#ifdef ERANGE_FILL
1868
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1869
#endif
1870
        err = NC_ERANGE;
1871
    }
1872
#ifdef ERANGE_FILL
1873
    else
1874
#endif
1875
#endif
1876
0
        xx = (ix_int)*ip;
1877
1878
0
    put_ix_int(xp, &xx);
1879
0
#endif
1880
0
    return err;
1881
0
}
1882
1883
static int
1884
ncx_put_int_long(void *xp, const long *ip, void *fillp)
1885
0
{
1886
0
    int err=NC_NOERR;
1887
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1888
    put_ix_int(xp, (const ix_int *)ip);
1889
#else
1890
0
    ix_int xx = NC_FILL_INT;
1891
1892
0
#if IX_INT_MAX < LONG_MAX
1893
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1894
        
1895
0
#ifdef ERANGE_FILL
1896
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1897
0
#endif
1898
0
        err = NC_ERANGE;
1899
0
    }
1900
0
#ifdef ERANGE_FILL
1901
0
    else
1902
0
#endif
1903
0
#endif
1904
0
        xx = (ix_int)*ip;
1905
1906
0
    put_ix_int(xp, &xx);
1907
0
#endif
1908
0
    return err;
1909
0
}
1910
1911
static int
1912
ncx_put_int_longlong(void *xp, const longlong *ip, void *fillp)
1913
0
{
1914
0
    int err=NC_NOERR;
1915
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1916
    put_ix_int(xp, (const ix_int *)ip);
1917
#else
1918
0
    ix_int xx = NC_FILL_INT;
1919
1920
0
#if IX_INT_MAX < LONGLONG_MAX
1921
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
1922
        
1923
0
#ifdef ERANGE_FILL
1924
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1925
0
#endif
1926
0
        err = NC_ERANGE;
1927
0
    }
1928
0
#ifdef ERANGE_FILL
1929
0
    else
1930
0
#endif
1931
0
#endif
1932
0
        xx = (ix_int)*ip;
1933
1934
0
    put_ix_int(xp, &xx);
1935
0
#endif
1936
0
    return err;
1937
0
}
1938
1939
static int
1940
ncx_put_int_ushort(void *xp, const ushort *ip, void *fillp)
1941
0
{
1942
0
    int err=NC_NOERR;
1943
0
    ix_int xx = NC_FILL_INT;
1944
1945
#if IX_INT_MAX < USHORT_MAX
1946
    if (*ip > IX_INT_MAX) {
1947
        
1948
#ifdef ERANGE_FILL
1949
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1950
#endif
1951
        err = NC_ERANGE;
1952
    }
1953
#ifdef ERANGE_FILL
1954
    else
1955
#endif
1956
#endif
1957
0
        xx = (ix_int)*ip;
1958
1959
0
    put_ix_int(xp, &xx);
1960
0
    return err;
1961
0
}
1962
1963
static int
1964
ncx_put_int_uint(void *xp, const uint *ip, void *fillp)
1965
0
{
1966
0
    int err=NC_NOERR;
1967
0
    ix_int xx = NC_FILL_INT;
1968
1969
0
#if IX_INT_MAX < UINT_MAX
1970
0
    if (*ip > IX_INT_MAX) {
1971
        
1972
0
#ifdef ERANGE_FILL
1973
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1974
0
#endif
1975
0
        err = NC_ERANGE;
1976
0
    }
1977
0
#ifdef ERANGE_FILL
1978
0
    else
1979
0
#endif
1980
0
#endif
1981
0
        xx = (ix_int)*ip;
1982
1983
0
    put_ix_int(xp, &xx);
1984
0
    return err;
1985
0
}
1986
1987
static int
1988
ncx_put_int_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1989
0
{
1990
0
    int err=NC_NOERR;
1991
0
    ix_int xx = NC_FILL_INT;
1992
1993
0
#if IX_INT_MAX < ULONGLONG_MAX
1994
0
    if (*ip > IX_INT_MAX) {
1995
        
1996
0
#ifdef ERANGE_FILL
1997
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
1998
0
#endif
1999
0
        err = NC_ERANGE;
2000
0
    }
2001
0
#ifdef ERANGE_FILL
2002
0
    else
2003
0
#endif
2004
0
#endif
2005
0
        xx = (ix_int)*ip;
2006
2007
0
    put_ix_int(xp, &xx);
2008
0
    return err;
2009
0
}
2010
2011
static int
2012
ncx_put_int_float(void *xp, const float *ip, void *fillp)
2013
0
{
2014
0
    int err=NC_NOERR;
2015
0
    ix_int xx = NC_FILL_INT;
2016
2017
0
    if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
2018
        
2019
0
#ifdef ERANGE_FILL
2020
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2021
0
#endif
2022
0
        err = NC_ERANGE;
2023
0
    }
2024
0
#ifdef ERANGE_FILL
2025
0
    else
2026
0
#endif
2027
0
        xx = (ix_int)*ip;
2028
2029
0
    put_ix_int(xp, &xx);
2030
0
    return err;
2031
0
}
2032
2033
static int
2034
ncx_put_int_double(void *xp, const double *ip, void *fillp)
2035
0
{
2036
0
    int err=NC_NOERR;
2037
0
    ix_int xx = NC_FILL_INT;
2038
2039
0
    if (*ip > X_INT_MAX || *ip < X_INT_MIN) {
2040
        
2041
0
#ifdef ERANGE_FILL
2042
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2043
0
#endif
2044
0
        err = NC_ERANGE;
2045
0
    }
2046
0
#ifdef ERANGE_FILL
2047
0
    else
2048
0
#endif
2049
0
        xx = (ix_int)*ip;
2050
2051
0
    put_ix_int(xp, &xx);
2052
0
    return err;
2053
0
}
2054
2055
2056
2057
/* external NC_UINT ---------------------------------------------------------*/
2058
2059
#if USHORT_MAX == X_UINT_MAX
2060
typedef ushort ix_uint;
2061
#define SIZEOF_IX_UINT SIZEOF_USHORT
2062
#define IX_UINT_MAX USHORT_MAX
2063
#elif UINT_MAX  >= X_UINT_MAX
2064
typedef uint ix_uint;
2065
#define SIZEOF_IX_UINT SIZEOF_UINT
2066
0
#define IX_UINT_MAX UINT_MAX
2067
#elif ULONG_MAX  >= X_UINT_MAX
2068
typedef ulong ix_uint;
2069
#define SIZEOF_IX_UINT SIZEOF_ULONG
2070
#define IX_UINT_MAX ULONG_MAX
2071
#else
2072
#error "ix_uint implementation"
2073
#endif
2074
2075
2076
static void
2077
get_ix_uint(const void *xp, ix_uint *ip)
2078
0
{
2079
0
  const uchar *cp = (const uchar *) xp;
2080
2081
0
  *ip = (ix_uint)(*cp++ << 24);
2082
0
  *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 16));
2083
0
  *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 8));
2084
0
  *ip = (ix_uint)(*ip | *cp);
2085
0
}
2086
2087
static void
2088
put_ix_uint(void *xp, const ix_uint *ip)
2089
0
{
2090
0
  uchar *cp = (uchar *) xp;
2091
2092
0
  *cp++ = (uchar)((*ip) >> 24);
2093
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
2094
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
2095
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
2096
0
}
2097
2098
#if X_SIZEOF_UINT != SIZEOF_UINT
2099
static int
2100
ncx_get_uint_uint(const void *xp, uint *ip)
2101
{
2102
    int err=NC_NOERR;
2103
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2104
    get_ix_uint(xp, (ix_uint *)ip);
2105
#else
2106
    ix_uint xx = 0;
2107
    get_ix_uint(xp, &xx);
2108
2109
#if IX_UINT_MAX > UINT_MAX
2110
    if (xx > UINT_MAX) {
2111
#ifdef ERANGE_FILL
2112
        *ip = NC_FILL_UINT;
2113
        return NC_ERANGE;
2114
#else
2115
        err = NC_ERANGE;
2116
#endif
2117
    }
2118
#endif
2119
2120
2121
    *ip = (uint) xx;
2122
#endif
2123
    return err;
2124
}
2125
2126
#endif
2127
2128
static int
2129
ncx_get_uint_schar(const void *xp, schar *ip)
2130
0
{
2131
0
    int err=NC_NOERR;
2132
0
    ix_uint xx = 0;
2133
0
    get_ix_uint(xp, &xx);
2134
2135
0
#if IX_UINT_MAX > SCHAR_MAX
2136
0
    if (xx > SCHAR_MAX) {
2137
0
#ifdef ERANGE_FILL
2138
0
        *ip = NC_FILL_BYTE;
2139
0
        return NC_ERANGE;
2140
#else
2141
        err = NC_ERANGE;
2142
#endif
2143
0
    }
2144
0
#endif
2145
2146
2147
0
    *ip = (schar) xx;
2148
0
    return err;
2149
0
}
2150
2151
static int
2152
ncx_get_uint_short(const void *xp, short *ip)
2153
0
{
2154
0
    int err=NC_NOERR;
2155
0
    ix_uint xx = 0;
2156
0
    get_ix_uint(xp, &xx);
2157
2158
0
#if IX_UINT_MAX > SHORT_MAX
2159
0
    if (xx > SHORT_MAX) {
2160
0
#ifdef ERANGE_FILL
2161
0
        *ip = NC_FILL_SHORT;
2162
0
        return NC_ERANGE;
2163
#else
2164
        err = NC_ERANGE;
2165
#endif
2166
0
    }
2167
0
#endif
2168
2169
2170
0
    *ip = (short) xx;
2171
0
    return err;
2172
0
}
2173
2174
static int
2175
ncx_get_uint_int(const void *xp, int *ip)
2176
0
{
2177
0
    int err=NC_NOERR;
2178
0
    ix_uint xx = 0;
2179
0
    get_ix_uint(xp, &xx);
2180
2181
0
#if IX_UINT_MAX > INT_MAX
2182
0
    if (xx > INT_MAX) {
2183
0
#ifdef ERANGE_FILL
2184
0
        *ip = NC_FILL_INT;
2185
0
        return NC_ERANGE;
2186
#else
2187
        err = NC_ERANGE;
2188
#endif
2189
0
    }
2190
0
#endif
2191
2192
2193
0
    *ip = (int) xx;
2194
0
    return err;
2195
0
}
2196
2197
static int
2198
ncx_get_uint_long(const void *xp, long *ip)
2199
0
{
2200
0
    int err=NC_NOERR;
2201
0
    ix_uint xx = 0;
2202
0
    get_ix_uint(xp, &xx);
2203
2204
#if IX_UINT_MAX > LONG_MAX
2205
    if (xx > LONG_MAX) {
2206
#ifdef ERANGE_FILL
2207
        *ip = NC_FILL_INT;
2208
        return NC_ERANGE;
2209
#else
2210
        err = NC_ERANGE;
2211
#endif
2212
    }
2213
#endif
2214
2215
2216
0
    *ip = (long) xx;
2217
0
    return err;
2218
0
}
2219
2220
static int
2221
ncx_get_uint_longlong(const void *xp, longlong *ip)
2222
0
{
2223
0
    int err=NC_NOERR;
2224
0
    ix_uint xx = 0;
2225
0
    get_ix_uint(xp, &xx);
2226
2227
#if IX_UINT_MAX > LONGLONG_MAX
2228
    if (xx > LONGLONG_MAX) {
2229
#ifdef ERANGE_FILL
2230
        *ip = NC_FILL_INT64;
2231
        return NC_ERANGE;
2232
#else
2233
        err = NC_ERANGE;
2234
#endif
2235
    }
2236
#endif
2237
2238
2239
0
    *ip = (longlong) xx;
2240
0
    return err;
2241
0
}
2242
2243
static int
2244
ncx_get_uint_ushort(const void *xp, ushort *ip)
2245
0
{
2246
0
    int err=NC_NOERR;
2247
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2248
    get_ix_uint(xp, (ix_uint *)ip);
2249
#else
2250
0
    ix_uint xx = 0;
2251
0
    get_ix_uint(xp, &xx);
2252
2253
0
#if IX_UINT_MAX > USHORT_MAX
2254
0
    if (xx > USHORT_MAX) {
2255
0
#ifdef ERANGE_FILL
2256
0
        *ip = NC_FILL_USHORT;
2257
0
        return NC_ERANGE;
2258
#else
2259
        err = NC_ERANGE;
2260
#endif
2261
0
    }
2262
0
#endif
2263
2264
2265
0
    *ip = (ushort) xx;
2266
0
#endif
2267
0
    return err;
2268
0
}
2269
2270
static int
2271
ncx_get_uint_uchar(const void *xp, uchar *ip)
2272
0
{
2273
0
    int err=NC_NOERR;
2274
#if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
2275
    get_ix_uint(xp, (ix_uint *)ip);
2276
#else
2277
0
    ix_uint xx = 0;
2278
0
    get_ix_uint(xp, &xx);
2279
2280
0
#if IX_UINT_MAX > UCHAR_MAX
2281
0
    if (xx > UCHAR_MAX) {
2282
0
#ifdef ERANGE_FILL
2283
0
        *ip = NC_FILL_UBYTE;
2284
0
        return NC_ERANGE;
2285
#else
2286
        err = NC_ERANGE;
2287
#endif
2288
0
    }
2289
0
#endif
2290
2291
2292
0
    *ip = (uchar) xx;
2293
0
#endif
2294
0
    return err;
2295
0
}
2296
2297
static int
2298
ncx_get_uint_ulonglong(const void *xp, ulonglong *ip)
2299
0
{
2300
0
    int err=NC_NOERR;
2301
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2302
    get_ix_uint(xp, (ix_uint *)ip);
2303
#else
2304
0
    ix_uint xx = 0;
2305
0
    get_ix_uint(xp, &xx);
2306
2307
#if IX_UINT_MAX > ULONGLONG_MAX
2308
    if (xx > ULONGLONG_MAX) {
2309
#ifdef ERANGE_FILL
2310
        *ip = NC_FILL_UINT64;
2311
        return NC_ERANGE;
2312
#else
2313
        err = NC_ERANGE;
2314
#endif
2315
    }
2316
#endif
2317
2318
2319
0
    *ip = (ulonglong) xx;
2320
0
#endif
2321
0
    return err;
2322
0
}
2323
2324
static int
2325
ncx_get_uint_float(const void *xp, float *ip)
2326
0
{
2327
0
  ix_uint xx = 0;
2328
0
  get_ix_uint(xp, &xx);
2329
0
  *ip = (float)xx;
2330
0
  return NC_NOERR;
2331
0
}
2332
2333
static int
2334
ncx_get_uint_double(const void *xp, double *ip)
2335
0
{
2336
0
  ix_uint xx = 0;
2337
0
  get_ix_uint(xp, &xx);
2338
0
  *ip = (double)xx;
2339
0
  return NC_NOERR;
2340
0
}
2341
2342
2343
static int
2344
ncx_put_uint_schar(void *xp, const schar *ip, void *fillp)
2345
0
{
2346
0
    uchar *cp;
2347
0
    if (*ip < 0) {
2348
0
#ifdef ERANGE_FILL
2349
0
        if (fillp != NULL) memcpy(xp, fillp, 4);
2350
0
#ifndef WORDS_BIGENDIAN
2351
0
        swapn4b(xp, xp, 1);
2352
0
#endif
2353
0
#endif
2354
0
        return NC_ERANGE;
2355
0
    }
2356
2357
0
    cp = (uchar *) xp;
2358
0
    *cp++ = 0x00;
2359
0
    *cp++ = 0x00;
2360
0
    *cp++ = 0x00;
2361
0
    *cp = (uchar)*ip;
2362
2363
0
    return NC_NOERR;
2364
0
}
2365
2366
static int
2367
ncx_put_uint_uchar(void *xp, const uchar *ip, void *fillp)
2368
0
{
2369
0
  uchar *cp = (uchar *) xp;
2370
0
  *cp++ = 0x00;
2371
0
  *cp++ = 0x00;
2372
0
  *cp++ = 0x00;
2373
0
  *cp   = *ip;
2374
0
  return NC_NOERR;
2375
0
}
2376
2377
#if X_SIZEOF_UINT != SIZEOF_UINT
2378
static int
2379
ncx_put_uint_uint(void *xp, const uint *ip, void *fillp)
2380
{
2381
    int err=NC_NOERR;
2382
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2383
    put_ix_uint(xp, (const ix_uint *)ip);
2384
#else
2385
    ix_uint xx = NC_FILL_UINT;
2386
2387
#if IX_UINT_MAX < UINT_MAX
2388
    if (*ip > IX_UINT_MAX) {
2389
        
2390
#ifdef ERANGE_FILL
2391
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2392
#endif
2393
        err = NC_ERANGE;
2394
    }
2395
#ifdef ERANGE_FILL
2396
    else
2397
#endif
2398
#endif
2399
        xx = (ix_uint)*ip;
2400
2401
    put_ix_uint(xp, &xx);
2402
#endif
2403
    return err;
2404
}
2405
2406
#endif
2407
2408
static int
2409
ncx_put_uint_short(void *xp, const short *ip, void *fillp)
2410
0
{
2411
0
    int err=NC_NOERR;
2412
0
    ix_uint xx = NC_FILL_UINT;
2413
2414
#if IX_UINT_MAX < SHORT_MAX
2415
    if (*ip > IX_UINT_MAX) {
2416
        
2417
#ifdef ERANGE_FILL
2418
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2419
#endif
2420
        err = NC_ERANGE;
2421
    }
2422
#ifdef ERANGE_FILL
2423
    else
2424
#endif
2425
#endif
2426
0
    if (*ip < 0) {
2427
        
2428
0
#ifdef ERANGE_FILL
2429
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2430
0
#endif
2431
0
        err = NC_ERANGE; /* because xp is unsigned */
2432
0
    }
2433
0
#ifdef ERANGE_FILL
2434
0
    else
2435
0
#endif
2436
0
        xx = (ix_uint)*ip;
2437
2438
0
    put_ix_uint(xp, &xx);
2439
0
    return err;
2440
0
}
2441
2442
static int
2443
ncx_put_uint_int(void *xp, const int *ip, void *fillp)
2444
0
{
2445
0
    int err=NC_NOERR;
2446
0
    ix_uint xx = NC_FILL_UINT;
2447
2448
#if IX_UINT_MAX < INT_MAX
2449
    if (*ip > IX_UINT_MAX) {
2450
        
2451
#ifdef ERANGE_FILL
2452
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2453
#endif
2454
        err = NC_ERANGE;
2455
    }
2456
#ifdef ERANGE_FILL
2457
    else
2458
#endif
2459
#endif
2460
0
    if (*ip < 0) {
2461
        
2462
0
#ifdef ERANGE_FILL
2463
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2464
0
#endif
2465
0
        err = NC_ERANGE; /* because xp is unsigned */
2466
0
    }
2467
0
#ifdef ERANGE_FILL
2468
0
    else
2469
0
#endif
2470
0
        xx = (ix_uint)*ip;
2471
2472
0
    put_ix_uint(xp, &xx);
2473
0
    return err;
2474
0
}
2475
2476
static int
2477
ncx_put_uint_long(void *xp, const long *ip, void *fillp)
2478
0
{
2479
0
    int err=NC_NOERR;
2480
0
    ix_uint xx = NC_FILL_UINT;
2481
2482
0
#if IX_UINT_MAX < LONG_MAX
2483
0
    if (*ip > IX_UINT_MAX) {
2484
        
2485
0
#ifdef ERANGE_FILL
2486
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2487
0
#endif
2488
0
        err = NC_ERANGE;
2489
0
    }
2490
0
#ifdef ERANGE_FILL
2491
0
    else
2492
0
#endif
2493
0
#endif
2494
0
    if (*ip < 0) {
2495
        
2496
0
#ifdef ERANGE_FILL
2497
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2498
0
#endif
2499
0
        err = NC_ERANGE; /* because xp is unsigned */
2500
0
    }
2501
0
#ifdef ERANGE_FILL
2502
0
    else
2503
0
#endif
2504
0
        xx = (ix_uint)*ip;
2505
2506
0
    put_ix_uint(xp, &xx);
2507
0
    return err;
2508
0
}
2509
2510
static int
2511
ncx_put_uint_longlong(void *xp, const longlong *ip, void *fillp)
2512
0
{
2513
0
    int err=NC_NOERR;
2514
0
    ix_uint xx = NC_FILL_UINT;
2515
2516
0
#if IX_UINT_MAX < LONGLONG_MAX
2517
0
    if (*ip > IX_UINT_MAX) {
2518
        
2519
0
#ifdef ERANGE_FILL
2520
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2521
0
#endif
2522
0
        err = NC_ERANGE;
2523
0
    }
2524
0
#ifdef ERANGE_FILL
2525
0
    else
2526
0
#endif
2527
0
#endif
2528
0
    if (*ip < 0) {
2529
        
2530
0
#ifdef ERANGE_FILL
2531
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2532
0
#endif
2533
0
        err = NC_ERANGE; /* because xp is unsigned */
2534
0
    }
2535
0
#ifdef ERANGE_FILL
2536
0
    else
2537
0
#endif
2538
0
        xx = (ix_uint)*ip;
2539
2540
0
    put_ix_uint(xp, &xx);
2541
0
    return err;
2542
0
}
2543
2544
static int
2545
ncx_put_uint_ushort(void *xp, const ushort *ip, void *fillp)
2546
0
{
2547
0
    int err=NC_NOERR;
2548
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2549
    put_ix_uint(xp, (const ix_uint *)ip);
2550
#else
2551
0
    ix_uint xx = NC_FILL_UINT;
2552
2553
#if IX_UINT_MAX < USHORT_MAX
2554
    if (*ip > IX_UINT_MAX) {
2555
        
2556
#ifdef ERANGE_FILL
2557
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2558
#endif
2559
        err = NC_ERANGE;
2560
    }
2561
#ifdef ERANGE_FILL
2562
    else
2563
#endif
2564
#endif
2565
0
        xx = (ix_uint)*ip;
2566
2567
0
    put_ix_uint(xp, &xx);
2568
0
#endif
2569
0
    return err;
2570
0
}
2571
2572
static int
2573
ncx_put_uint_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2574
0
{
2575
0
    int err=NC_NOERR;
2576
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2577
    put_ix_uint(xp, (const ix_uint *)ip);
2578
#else
2579
0
    ix_uint xx = NC_FILL_UINT;
2580
2581
0
#if IX_UINT_MAX < ULONGLONG_MAX
2582
0
    if (*ip > IX_UINT_MAX) {
2583
        
2584
0
#ifdef ERANGE_FILL
2585
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2586
0
#endif
2587
0
        err = NC_ERANGE;
2588
0
    }
2589
0
#ifdef ERANGE_FILL
2590
0
    else
2591
0
#endif
2592
0
#endif
2593
0
        xx = (ix_uint)*ip;
2594
2595
0
    put_ix_uint(xp, &xx);
2596
0
#endif
2597
0
    return err;
2598
0
}
2599
2600
static int
2601
ncx_put_uint_float(void *xp, const float *ip, void *fillp)
2602
0
{
2603
0
    int err=NC_NOERR;
2604
0
    ix_uint xx = NC_FILL_UINT;
2605
2606
0
    if (*ip > (double)X_UINT_MAX || *ip < 0) {
2607
        
2608
0
#ifdef ERANGE_FILL
2609
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2610
0
#endif
2611
0
        err = NC_ERANGE;
2612
0
    }
2613
0
#ifdef ERANGE_FILL
2614
0
    else
2615
0
#endif
2616
0
        xx = (ix_uint)*ip;
2617
2618
0
    put_ix_uint(xp, &xx);
2619
0
    return err;
2620
0
}
2621
2622
static int
2623
ncx_put_uint_double(void *xp, const double *ip, void *fillp)
2624
0
{
2625
0
    int err=NC_NOERR;
2626
0
    ix_uint xx = NC_FILL_UINT;
2627
2628
0
    if (*ip > X_UINT_MAX || *ip < 0) {
2629
        
2630
0
#ifdef ERANGE_FILL
2631
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2632
0
#endif
2633
0
        err = NC_ERANGE;
2634
0
    }
2635
0
#ifdef ERANGE_FILL
2636
0
    else
2637
0
#endif
2638
0
        xx = (ix_uint)*ip;
2639
2640
0
    put_ix_uint(xp, &xx);
2641
0
    return err;
2642
0
}
2643
2644
2645
2646
/* external NC_FLOAT --------------------------------------------------------*/
2647
2648
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
2649
2650
inline static void
2651
get_ix_float(const void *xp, float *ip)
2652
0
{
2653
#ifdef WORDS_BIGENDIAN
2654
  (void) memcpy(ip, xp, SIZEOF_FLOAT);
2655
#else
2656
0
  swap4b(ip, xp);
2657
0
#endif
2658
0
}
2659
2660
inline static void
2661
put_ix_float(void *xp, const float *ip)
2662
0
{
2663
#ifdef WORDS_BIGENDIAN
2664
  (void) memcpy(xp, ip, X_SIZEOF_FLOAT);
2665
#else
2666
0
  swap4b(xp, ip);
2667
0
#endif
2668
0
}
2669
2670
#elif defined(vax) && vax != 0
2671
2672
/* What IEEE single precision floating point looks like on a Vax */
2673
struct  ieee_single {
2674
  unsigned int  exp_hi       : 7;
2675
  unsigned int  sign         : 1;
2676
  unsigned int  mant_hi      : 7;
2677
  unsigned int  exp_lo       : 1;
2678
  unsigned int  mant_lo_hi   : 8;
2679
  unsigned int  mant_lo_lo   : 8;
2680
};
2681
2682
/* Vax single precision floating point */
2683
struct  vax_single {
2684
  unsigned int  mantissa1 : 7;
2685
  unsigned int  exp       : 8;
2686
  unsigned int  sign      : 1;
2687
  unsigned int  mantissa2 : 16;
2688
};
2689
2690
#define VAX_SNG_BIAS  0x81
2691
#define IEEE_SNG_BIAS 0x7f
2692
2693
static struct sgl_limits {
2694
  struct vax_single s;
2695
  struct ieee_single ieee;
2696
} max = {
2697
  { 0x7f, 0xff, 0x0, 0xffff },  /* Max Vax */
2698
  { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }   /* Max IEEE */
2699
};
2700
static struct sgl_limits min = {
2701
  { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
2702
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }    /* Min IEEE */
2703
};
2704
2705
static void
2706
get_ix_float(const void *xp, float *ip)
2707
{
2708
    struct vax_single *const vsp = (struct vax_single *) ip;
2709
    const struct ieee_single *const isp =
2710
       (const struct ieee_single *) xp;
2711
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
2712
2713
    switch(exp) {
2714
    case 0 :
2715
      /* ieee subnormal */
2716
      if (isp->mant_hi == min.ieee.mant_hi
2717
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
2718
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
2719
      {
2720
        *vsp = min.s;
2721
      }
2722
      else
2723
      {
2724
        unsigned mantissa = (isp->mant_hi << 16)
2725
           | isp->mant_lo_hi << 8
2726
           | isp->mant_lo_lo;
2727
        unsigned tmp = mantissa >> 20;
2728
        if (tmp >= 4) {
2729
          vsp->exp = 2;
2730
        } else if (tmp >= 2) {
2731
          vsp->exp = 1;
2732
        } else {
2733
          *vsp = min.s;
2734
          break;
2735
        } /* else */
2736
        tmp = mantissa - (1 << (20 + vsp->exp ));
2737
        tmp <<= 3 - vsp->exp;
2738
        vsp->mantissa2 = tmp;
2739
        vsp->mantissa1 = (tmp >> 16);
2740
      }
2741
      break;
2742
    case 0xfe :
2743
    case 0xff :
2744
      *vsp = max.s;
2745
      break;
2746
    default :
2747
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
2748
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
2749
      vsp->mantissa1 = isp->mant_hi;
2750
    }
2751
2752
    vsp->sign = isp->sign;
2753
2754
}
2755
2756
2757
static void
2758
put_ix_float(void *xp, const float *ip)
2759
{
2760
    const struct vax_single *const vsp =
2761
       (const struct vax_single *)ip;
2762
    struct ieee_single *const isp = (struct ieee_single *) xp;
2763
2764
    switch(vsp->exp){
2765
    case 0 :
2766
      /* all vax float with zero exponent map to zero */
2767
      *isp = min.ieee;
2768
      break;
2769
    case 2 :
2770
    case 1 :
2771
    {
2772
      /* These will map to subnormals */
2773
      unsigned mantissa = (vsp->mantissa1 << 16)
2774
           | vsp->mantissa2;
2775
      mantissa >>= 3 - vsp->exp;
2776
      mantissa += (1 << (20 + vsp->exp));
2777
      isp->mant_lo_lo = mantissa;
2778
      isp->mant_lo_hi = mantissa >> 8;
2779
      isp->mant_hi = mantissa >> 16;
2780
      isp->exp_lo = 0;
2781
      isp->exp_hi = 0;
2782
    }
2783
      break;
2784
    case 0xff : /* max.s.exp */
2785
      if (vsp->mantissa2 == max.s.mantissa2 &&
2786
          vsp->mantissa1 == max.s.mantissa1)
2787
      {
2788
        /* map largest vax float to ieee infinity */
2789
        *isp = max.ieee;
2790
        break;
2791
      } /* else, fall thru */
2792
    default :
2793
    {
2794
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
2795
      isp->exp_hi = exp >> 1;
2796
      isp->exp_lo = exp;
2797
      isp->mant_lo_lo = vsp->mantissa2;
2798
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
2799
      isp->mant_hi = vsp->mantissa1;
2800
    }
2801
    }
2802
2803
    isp->sign = vsp->sign;
2804
2805
}
2806
2807
  /* vax */
2808
#elif defined(_CRAY) && !defined(__crayx1)
2809
2810
/*
2811
 * Return the number of bytes until the next "word" boundary
2812
 * N.B. This is based on the very weird YMP address structure,
2813
 * which puts the address within a word in the leftmost 3 bits
2814
 * of the address.
2815
 */
2816
static size_t
2817
word_align(const void *vp)
2818
{
2819
  const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
2820
  return (rem != 0);
2821
}
2822
2823
struct ieee_single_hi {
2824
  unsigned int  sign  : 1;
2825
  unsigned int   exp  : 8;
2826
  unsigned int  mant  :23;
2827
  unsigned int  pad :32;
2828
};
2829
typedef struct ieee_single_hi ieee_single_hi;
2830
2831
struct ieee_single_lo {
2832
  unsigned int  pad :32;
2833
  unsigned int  sign  : 1;
2834
  unsigned int   exp  : 8;
2835
  unsigned int  mant  :23;
2836
};
2837
typedef struct ieee_single_lo ieee_single_lo;
2838
2839
static const int ieee_single_bias = 0x7f;
2840
2841
struct ieee_double {
2842
  unsigned int  sign  : 1;
2843
  unsigned int   exp  :11;
2844
  unsigned int  mant  :52;
2845
};
2846
typedef struct ieee_double ieee_double;
2847
2848
static const int ieee_double_bias = 0x3ff;
2849
2850
#if defined(NO_IEEE_FLOAT)
2851
2852
struct cray_single {
2853
  unsigned int  sign  : 1;
2854
  unsigned int   exp  :15;
2855
  unsigned int  mant  :48;
2856
};
2857
typedef struct cray_single cray_single;
2858
2859
static const int cs_ieis_bias = 0x4000 - 0x7f;
2860
2861
static const int cs_id_bias = 0x4000 - 0x3ff;
2862
2863
2864
static void
2865
get_ix_float(const void *xp, float *ip)
2866
{
2867
2868
  if (word_align(xp) == 0)
2869
  {
2870
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
2871
    cray_single *csp = (cray_single *) ip;
2872
2873
    if (isp->exp == 0)
2874
    {
2875
      /* ieee subnormal */
2876
      *ip = (double)isp->mant;
2877
      if (isp->mant != 0)
2878
      {
2879
        csp->exp -= (ieee_single_bias + 22);
2880
      }
2881
    }
2882
    else
2883
    {
2884
      csp->exp  = isp->exp + cs_ieis_bias + 1;
2885
      csp->mant = isp->mant << (48 - 1 - 23);
2886
      csp->mant |= (1 << (48 - 1));
2887
    }
2888
    csp->sign = isp->sign;
2889
2890
2891
  }
2892
  else
2893
  {
2894
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
2895
    cray_single *csp = (cray_single *) ip;
2896
2897
    if (isp->exp == 0)
2898
    {
2899
      /* ieee subnormal */
2900
      *ip = (double)isp->mant;
2901
      if (isp->mant != 0)
2902
      {
2903
        csp->exp -= (ieee_single_bias + 22);
2904
      }
2905
    }
2906
    else
2907
    {
2908
      csp->exp  = isp->exp + cs_ieis_bias + 1;
2909
      csp->mant = isp->mant << (48 - 1 - 23);
2910
      csp->mant |= (1 << (48 - 1));
2911
    }
2912
    csp->sign = isp->sign;
2913
2914
2915
  }
2916
}
2917
2918
static void
2919
put_ix_float(void *xp, const float *ip)
2920
{
2921
  if (word_align(xp) == 0)
2922
  {
2923
    ieee_single_hi *isp = (ieee_single_hi*)xp;
2924
  const cray_single *csp = (const cray_single *) ip;
2925
  int ieee_exp = csp->exp - cs_ieis_bias -1;
2926
2927
  isp->sign = csp->sign;
2928
2929
  if (ieee_exp >= 0xff)
2930
  {
2931
    /* NC_ERANGE => ieee Inf */
2932
    isp->exp = 0xff;
2933
    isp->mant = 0x0;
2934
  }
2935
  else if (ieee_exp > 0)
2936
  {
2937
    /* normal ieee representation */
2938
    isp->exp  = ieee_exp;
2939
    /* assumes cray rep is in normal form */
2940
    assert(csp->mant & 0x800000000000);
2941
    isp->mant = (((csp->mant << 1) &
2942
        0xffffffffffff) >> (48 - 23));
2943
  }
2944
  else if (ieee_exp > -23)
2945
  {
2946
    /* ieee subnormal, right shift */
2947
    const int rshift = (48 - 23 - ieee_exp);
2948
2949
    isp->mant = csp->mant >> rshift;
2950
2951
#if 0
2952
    if (csp->mant & (1 << (rshift -1)))
2953
    {
2954
      /* round up */
2955
      isp->mant++;
2956
    }
2957
#endif
2958
2959
    isp->exp  = 0;
2960
  }
2961
  else
2962
  {
2963
    /* smaller than ieee can represent */
2964
    isp->exp = 0;
2965
    isp->mant = 0;
2966
  }
2967
2968
  }
2969
  else
2970
  {
2971
    ieee_single_lo *isp = (ieee_single_lo*)xp;
2972
  const cray_single *csp = (const cray_single *) ip;
2973
  int ieee_exp = csp->exp - cs_ieis_bias -1;
2974
2975
  isp->sign = csp->sign;
2976
2977
  if (ieee_exp >= 0xff)
2978
  {
2979
    /* NC_ERANGE => ieee Inf */
2980
    isp->exp = 0xff;
2981
    isp->mant = 0x0;
2982
  }
2983
  else if (ieee_exp > 0)
2984
  {
2985
    /* normal ieee representation */
2986
    isp->exp  = ieee_exp;
2987
    /* assumes cray rep is in normal form */
2988
    assert(csp->mant & 0x800000000000);
2989
    isp->mant = (((csp->mant << 1) &
2990
        0xffffffffffff) >> (48 - 23));
2991
  }
2992
  else if (ieee_exp > -23)
2993
  {
2994
    /* ieee subnormal, right shift */
2995
    const int rshift = (48 - 23 - ieee_exp);
2996
2997
    isp->mant = csp->mant >> rshift;
2998
2999
#if 0
3000
    if (csp->mant & (1 << (rshift -1)))
3001
    {
3002
      /* round up */
3003
      isp->mant++;
3004
    }
3005
#endif
3006
3007
    isp->exp  = 0;
3008
  }
3009
  else
3010
  {
3011
    /* smaller than ieee can represent */
3012
    isp->exp = 0;
3013
    isp->mant = 0;
3014
  }
3015
3016
  }
3017
}
3018
3019
#else
3020
  /* IEEE Cray with only doubles */
3021
static void
3022
get_ix_float(const void *xp, float *ip)
3023
{
3024
3025
  ieee_double *idp = (ieee_double *) ip;
3026
3027
  if (word_align(xp) == 0)
3028
  {
3029
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3030
    if (isp->exp == 0 && isp->mant == 0)
3031
    {
3032
      idp->exp = 0;
3033
      idp->mant = 0;
3034
    }
3035
    else
3036
    {
3037
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3038
      idp->mant = isp->mant << (52 - 23);
3039
    }
3040
    idp->sign = isp->sign;
3041
  }
3042
  else
3043
  {
3044
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3045
    if (isp->exp == 0 && isp->mant == 0)
3046
    {
3047
      idp->exp = 0;
3048
      idp->mant = 0;
3049
    }
3050
    else
3051
    {
3052
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3053
      idp->mant = isp->mant << (52 - 23);
3054
    }
3055
    idp->sign = isp->sign;
3056
  }
3057
}
3058
3059
static void
3060
put_ix_float(void *xp, const float *ip)
3061
{
3062
  const ieee_double *idp = (const ieee_double *) ip;
3063
  if (word_align(xp) == 0)
3064
  {
3065
    ieee_single_hi *isp = (ieee_single_hi*)xp;
3066
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3067
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3068
    else
3069
      isp->exp = 0;
3070
    isp->mant = idp->mant >> (52 - 23);
3071
    isp->sign = idp->sign;
3072
  }
3073
  else
3074
  {
3075
    ieee_single_lo *isp = (ieee_single_lo*)xp;
3076
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3077
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3078
    else
3079
      isp->exp = 0;
3080
    isp->mant = idp->mant >> (52 - 23);
3081
    isp->sign = idp->sign;
3082
  }
3083
}
3084
#endif
3085
3086
#else
3087
#error "ix_float implementation"
3088
#endif
3089
3090
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3091
static int
3092
ncx_get_float_float(const void *xp, float *ip, void *fillp)
3093
{
3094
  /* TODO */
3095
  get_ix_float(xp, ip);
3096
  return NC_NOERR;
3097
}
3098
#endif
3099
3100
0
#define ix_float float
3101
3102
static int
3103
ncx_get_float_schar(const void *xp, schar *ip)
3104
0
{
3105
0
  ix_float xx = 0;
3106
0
  get_ix_float(xp, &xx);
3107
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3108
0
#ifdef ERANGE_FILL
3109
0
            *ip = NC_FILL_BYTE;
3110
0
#endif
3111
0
            return NC_ERANGE;
3112
0
        }
3113
0
  *ip = (schar)xx;
3114
0
  return NC_NOERR;
3115
0
}
3116
3117
static int
3118
ncx_get_float_short(const void *xp, short *ip)
3119
0
{
3120
0
  ix_float xx = 0;
3121
0
  get_ix_float(xp, &xx);
3122
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3123
0
#ifdef ERANGE_FILL
3124
0
            *ip = NC_FILL_SHORT;
3125
0
#endif
3126
0
            return NC_ERANGE;
3127
0
        }
3128
0
  *ip = (short)xx;
3129
0
  return NC_NOERR;
3130
0
}
3131
3132
static int
3133
ncx_get_float_int(const void *xp, int *ip)
3134
0
{
3135
0
  ix_float xx = 0;
3136
0
  get_ix_float(xp, &xx);
3137
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3138
0
#ifdef ERANGE_FILL
3139
0
            *ip = NC_FILL_INT;
3140
0
#endif
3141
0
            return NC_ERANGE;
3142
0
        }
3143
0
  *ip = (int)xx;
3144
0
  return NC_NOERR;
3145
0
}
3146
3147
static int
3148
ncx_get_float_long(const void *xp, long *ip)
3149
0
{
3150
0
  ix_float xx = 0;
3151
0
  get_ix_float(xp, &xx);
3152
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3153
0
#ifdef ERANGE_FILL
3154
0
            *ip = NC_FILL_INT;
3155
0
#endif
3156
0
            return NC_ERANGE;
3157
0
        }
3158
0
  *ip = (long)xx;
3159
0
  return NC_NOERR;
3160
0
}
3161
3162
static int
3163
ncx_get_float_double(const void *xp, double *ip)
3164
0
{
3165
0
  ix_float xx = 0;
3166
0
  get_ix_float(xp, &xx);
3167
0
  *ip = (double)xx;
3168
0
  return NC_NOERR;
3169
0
}
3170
3171
static int
3172
ncx_get_float_longlong(const void *xp, longlong *ip)
3173
0
{
3174
0
  ix_float xx = 0;
3175
0
  get_ix_float(xp, &xx);
3176
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3177
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3178
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3179
0
#ifdef ERANGE_FILL
3180
0
            *ip = NC_FILL_INT64;
3181
0
#endif
3182
0
            return NC_ERANGE;
3183
0
        }
3184
0
  else *ip = (longlong)xx;
3185
0
  return NC_NOERR;
3186
0
}
3187
3188
static int
3189
ncx_get_float_uchar(const void *xp, uchar *ip)
3190
0
{
3191
0
  ix_float xx = 0;
3192
0
  get_ix_float(xp, &xx);
3193
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3194
0
#ifdef ERANGE_FILL
3195
0
            *ip = NC_FILL_UBYTE;
3196
0
#endif
3197
0
            return NC_ERANGE;
3198
0
        }
3199
0
  *ip = (uchar)xx;
3200
0
  return NC_NOERR;
3201
0
}
3202
3203
static int
3204
ncx_get_float_ushort(const void *xp, ushort *ip)
3205
0
{
3206
0
  ix_float xx = 0;
3207
0
  get_ix_float(xp, &xx);
3208
0
  if (xx > (double)USHORT_MAX || xx < 0) {
3209
0
#ifdef ERANGE_FILL
3210
0
            *ip = NC_FILL_USHORT;
3211
0
#endif
3212
0
            return NC_ERANGE;
3213
0
        }
3214
0
  *ip = (ushort)xx;
3215
0
  return NC_NOERR;
3216
0
}
3217
3218
static int
3219
ncx_get_float_uint(const void *xp, uint *ip)
3220
0
{
3221
0
  ix_float xx = 0;
3222
0
  get_ix_float(xp, &xx);
3223
0
  if (xx > (double)UINT_MAX || xx < 0) {
3224
0
#ifdef ERANGE_FILL
3225
0
            *ip = NC_FILL_UINT;
3226
0
#endif
3227
0
            return NC_ERANGE;
3228
0
        }
3229
0
  *ip = (uint)xx;
3230
0
  return NC_NOERR;
3231
0
}
3232
3233
static int
3234
ncx_get_float_ulonglong(const void *xp, ulonglong *ip)
3235
0
{
3236
0
  ix_float xx = 0;
3237
0
  get_ix_float(xp, &xx);
3238
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3239
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3240
0
#ifdef ERANGE_FILL
3241
0
            *ip = NC_FILL_UINT64;
3242
0
#endif
3243
0
            return NC_ERANGE;
3244
0
        }
3245
0
  else *ip = (ulonglong)xx;
3246
0
  return NC_NOERR;
3247
0
}
3248
3249
3250
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3251
static int
3252
ncx_put_float_float(void *xp, const float *ip, void *fillp)
3253
{
3254
    int err=NC_NOERR;
3255
    float *_ip=ip;
3256
#ifdef NO_IEEE_FLOAT
3257
#ifdef ERANGE_FILL
3258
    float tmp;
3259
#endif
3260
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3261
        
3262
#ifdef ERANGE_FILL
3263
            if (fillp != NULL) memcpy(&tmp, fillp, 4);
3264
#endif
3265
#ifdef ERANGE_FILL
3266
        _ip = &tmp;
3267
#endif
3268
        err = NC_ERANGE;
3269
    }
3270
#endif
3271
    put_ix_float(xp, _ip);
3272
    return err;
3273
}
3274
#endif
3275
3276
static int
3277
ncx_put_float_schar(void *xp, const schar *ip, void *fillp)
3278
0
{
3279
0
    int err=NC_NOERR;
3280
0
    ix_float xx = NC_FILL_FLOAT;
3281
3282
    
3283
0
        xx = (ix_float)*ip;
3284
3285
0
    put_ix_float(xp, &xx);
3286
0
    return err;
3287
0
}
3288
3289
static int
3290
ncx_put_float_short(void *xp, const short *ip, void *fillp)
3291
0
{
3292
0
    int err=NC_NOERR;
3293
0
    ix_float xx = NC_FILL_FLOAT;
3294
3295
    
3296
0
        xx = (ix_float)*ip;
3297
3298
0
    put_ix_float(xp, &xx);
3299
0
    return err;
3300
0
}
3301
3302
static int
3303
ncx_put_float_int(void *xp, const int *ip, void *fillp)
3304
0
{
3305
0
    int err=NC_NOERR;
3306
0
    ix_float xx = NC_FILL_FLOAT;
3307
3308
    
3309
0
        xx = (ix_float)*ip;
3310
3311
0
    put_ix_float(xp, &xx);
3312
0
    return err;
3313
0
}
3314
3315
static int
3316
ncx_put_float_long(void *xp, const long *ip, void *fillp)
3317
0
{
3318
0
    int err=NC_NOERR;
3319
0
    ix_float xx = NC_FILL_FLOAT;
3320
3321
    
3322
0
        xx = (ix_float)*ip;
3323
3324
0
    put_ix_float(xp, &xx);
3325
0
    return err;
3326
0
}
3327
3328
static int
3329
ncx_put_float_double(void *xp, const double *ip, void *fillp)
3330
0
{
3331
0
    int err=NC_NOERR;
3332
0
    ix_float xx = NC_FILL_FLOAT;
3333
3334
0
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3335
        
3336
0
#ifdef ERANGE_FILL
3337
0
            if (fillp != NULL) memcpy(&xx, fillp, 4);
3338
0
#endif
3339
0
        err = NC_ERANGE;
3340
0
    }
3341
0
#ifdef ERANGE_FILL
3342
0
    else
3343
0
#endif
3344
0
        xx = (ix_float)*ip;
3345
3346
0
    put_ix_float(xp, &xx);
3347
0
    return err;
3348
0
}
3349
3350
static int
3351
ncx_put_float_longlong(void *xp, const longlong *ip, void *fillp)
3352
0
{
3353
0
    int err=NC_NOERR;
3354
0
    ix_float xx = NC_FILL_FLOAT;
3355
3356
    
3357
0
        xx = (ix_float)*ip;
3358
3359
0
    put_ix_float(xp, &xx);
3360
0
    return err;
3361
0
}
3362
3363
static int
3364
ncx_put_float_uchar(void *xp, const uchar *ip, void *fillp)
3365
0
{
3366
0
    int err=NC_NOERR;
3367
0
    ix_float xx = NC_FILL_FLOAT;
3368
3369
    
3370
0
        xx = (ix_float)*ip;
3371
3372
0
    put_ix_float(xp, &xx);
3373
0
    return err;
3374
0
}
3375
3376
static int
3377
ncx_put_float_ushort(void *xp, const ushort *ip, void *fillp)
3378
0
{
3379
0
    int err=NC_NOERR;
3380
0
    ix_float xx = NC_FILL_FLOAT;
3381
3382
    
3383
0
        xx = (ix_float)*ip;
3384
3385
0
    put_ix_float(xp, &xx);
3386
0
    return err;
3387
0
}
3388
3389
static int
3390
ncx_put_float_uint(void *xp, const uint *ip, void *fillp)
3391
0
{
3392
0
    int err=NC_NOERR;
3393
0
    ix_float xx = NC_FILL_FLOAT;
3394
3395
    
3396
0
        xx = (ix_float)*ip;
3397
3398
0
    put_ix_float(xp, &xx);
3399
0
    return err;
3400
0
}
3401
3402
static int
3403
ncx_put_float_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3404
0
{
3405
0
    int err=NC_NOERR;
3406
0
    ix_float xx = NC_FILL_FLOAT;
3407
3408
    
3409
0
        xx = (ix_float)*ip;
3410
3411
0
    put_ix_float(xp, &xx);
3412
0
    return err;
3413
0
}
3414
3415
3416
3417
/* external NC_DOUBLE -------------------------------------------------------*/
3418
3419
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
3420
3421
static void
3422
get_ix_double(const void *xp, double *ip)
3423
0
{
3424
#ifdef WORDS_BIGENDIAN
3425
  (void) memcpy(ip, xp, SIZEOF_DOUBLE);
3426
#else
3427
0
  swap8b(ip, xp);
3428
0
#endif
3429
0
}
3430
3431
static void
3432
put_ix_double(void *xp, const double *ip)
3433
0
{
3434
#ifdef WORDS_BIGENDIAN
3435
  (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
3436
#else
3437
0
  swap8b(xp, ip);
3438
0
#endif
3439
0
}
3440
3441
#elif defined(vax) && vax != 0
3442
3443
/* What IEEE double precision floating point looks like on a Vax */
3444
struct  ieee_double {
3445
  unsigned int  exp_hi   : 7;
3446
  unsigned int  sign     : 1;
3447
  unsigned int  mant_6   : 4;
3448
  unsigned int  exp_lo   : 4;
3449
  unsigned int  mant_5   : 8;
3450
  unsigned int  mant_4   : 8;
3451
3452
  unsigned int  mant_lo  : 32;
3453
};
3454
3455
/* Vax double precision floating point */
3456
struct  vax_double {
3457
  unsigned int  mantissa1 : 7;
3458
  unsigned int  exp       : 8;
3459
  unsigned int  sign      : 1;
3460
  unsigned int  mantissa2 : 16;
3461
  unsigned int  mantissa3 : 16;
3462
  unsigned int  mantissa4 : 16;
3463
};
3464
3465
#define VAX_DBL_BIAS  0x81
3466
#define IEEE_DBL_BIAS 0x3ff
3467
#define MASK(nbits) ((1 << nbits) - 1)
3468
3469
static const struct dbl_limits {
3470
  struct  vax_double d;
3471
  struct  ieee_double ieee;
3472
} dbl_limits[2] = {
3473
  {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
3474
  { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
3475
  {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},   /* Min Vax */
3476
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
3477
};
3478
3479
3480
static void
3481
get_ix_double(const void *xp, double *ip)
3482
{
3483
  struct vax_double *const vdp =
3484
       (struct vax_double *)ip;
3485
  const struct ieee_double *const idp =
3486
       (const struct ieee_double *) xp;
3487
  {
3488
    const struct dbl_limits *lim;
3489
    int ii;
3490
    for (ii = 0, lim = dbl_limits;
3491
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
3492
      ii++, lim++)
3493
    {
3494
      if ((idp->mant_lo == lim->ieee.mant_lo)
3495
        && (idp->mant_4 == lim->ieee.mant_4)
3496
        && (idp->mant_5 == lim->ieee.mant_5)
3497
        && (idp->mant_6 == lim->ieee.mant_6)
3498
        && (idp->exp_lo == lim->ieee.exp_lo)
3499
        && (idp->exp_hi == lim->ieee.exp_hi)
3500
        )
3501
      {
3502
        *vdp = lim->d;
3503
        goto doneit;
3504
      }
3505
    }
3506
  }
3507
  {
3508
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
3509
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
3510
  }
3511
  {
3512
    unsigned mant_hi = ((idp->mant_6 << 16)
3513
         | (idp->mant_5 << 8)
3514
         | idp->mant_4);
3515
    unsigned mant_lo = SWAP4(idp->mant_lo);
3516
    vdp->mantissa1 = (mant_hi >> 13);
3517
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
3518
        | (mant_lo >> 29);
3519
    vdp->mantissa3 = (mant_lo >> 13);
3520
    vdp->mantissa4 = (mant_lo << 3);
3521
  }
3522
  doneit:
3523
    vdp->sign = idp->sign;
3524
3525
}
3526
3527
3528
static void
3529
put_ix_double(void *xp, const double *ip)
3530
{
3531
  const struct vax_double *const vdp =
3532
      (const struct vax_double *)ip;
3533
  struct ieee_double *const idp =
3534
       (struct ieee_double *) xp;
3535
3536
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
3537
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
3538
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
3539
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
3540
    (vdp->exp == dbl_limits[0].d.exp))
3541
  {
3542
    *idp = dbl_limits[0].ieee;
3543
    goto shipit;
3544
  }
3545
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
3546
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
3547
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
3548
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
3549
    (vdp->exp == dbl_limits[1].d.exp))
3550
  {
3551
    *idp = dbl_limits[1].ieee;
3552
    goto shipit;
3553
  }
3554
3555
  {
3556
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
3557
3558
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
3559
      (vdp->mantissa3 << 13) |
3560
      ((vdp->mantissa4 >> 3) & MASK(13));
3561
3562
    unsigned mant_hi = (vdp->mantissa1 << 13)
3563
         | (vdp->mantissa2 >> 3);
3564
3565
    if ((vdp->mantissa4 & 7) > 4)
3566
    {
3567
      /* round up */
3568
      mant_lo++;
3569
      if (mant_lo == 0)
3570
      {
3571
        mant_hi++;
3572
        if (mant_hi > 0xffffff)
3573
        {
3574
          mant_hi = 0;
3575
          exp++;
3576
        }
3577
      }
3578
    }
3579
3580
    idp->mant_lo = SWAP4(mant_lo);
3581
    idp->mant_6 = mant_hi >> 16;
3582
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
3583
    idp->mant_4 = mant_hi;
3584
    idp->exp_hi = exp >> 4;
3585
    idp->exp_lo = exp;
3586
  }
3587
3588
  shipit:
3589
    idp->sign = vdp->sign;
3590
3591
}
3592
3593
  /* vax */
3594
#elif defined(_CRAY) && !defined(__crayx1)
3595
3596
static void
3597
get_ix_double(const void *xp, double *ip)
3598
{
3599
  const ieee_double *idp = (const ieee_double *) xp;
3600
  cray_single *csp = (cray_single *) ip;
3601
3602
  if (idp->exp == 0)
3603
  {
3604
    /* ieee subnormal */
3605
    *ip = (double)idp->mant;
3606
    if (idp->mant != 0)
3607
    {
3608
      csp->exp -= (ieee_double_bias + 51);
3609
    }
3610
  }
3611
  else
3612
  {
3613
    csp->exp  = idp->exp + cs_id_bias + 1;
3614
    csp->mant = idp->mant >> (52 - 48 + 1);
3615
    csp->mant |= (1 << (48 - 1));
3616
  }
3617
  csp->sign = idp->sign;
3618
}
3619
3620
static void
3621
put_ix_double(void *xp, const double *ip)
3622
{
3623
  ieee_double *idp = (ieee_double *) xp;
3624
  const cray_single *csp = (const cray_single *) ip;
3625
3626
  int ieee_exp = csp->exp - cs_id_bias -1;
3627
3628
  idp->sign = csp->sign;
3629
3630
  if (ieee_exp >= 0x7ff)
3631
  {
3632
    /* NC_ERANGE => ieee Inf */
3633
    idp->exp = 0x7ff;
3634
    idp->mant = 0x0;
3635
  }
3636
  else if (ieee_exp > 0)
3637
  {
3638
    /* normal ieee representation */
3639
    idp->exp  = ieee_exp;
3640
    /* assumes cray rep is in normal form */
3641
    assert(csp->mant & 0x800000000000);
3642
    idp->mant = (((csp->mant << 1) &
3643
        0xffffffffffff) << (52 - 48));
3644
  }
3645
  else if (ieee_exp >= (-(52 -48)))
3646
  {
3647
    /* ieee subnormal, left shift */
3648
    const int lshift = (52 - 48) + ieee_exp;
3649
    idp->mant = csp->mant << lshift;
3650
    idp->exp  = 0;
3651
  }
3652
  else if (ieee_exp >= -52)
3653
  {
3654
    /* ieee subnormal, right shift */
3655
    const int rshift = (- (52 - 48) - ieee_exp);
3656
3657
    idp->mant = csp->mant >> rshift;
3658
3659
#if 0
3660
    if (csp->mant & (1 << (rshift -1)))
3661
    {
3662
      /* round up */
3663
      idp->mant++;
3664
    }
3665
#endif
3666
3667
    idp->exp  = 0;
3668
  }
3669
  else
3670
  {
3671
    /* smaller than ieee can represent */
3672
    idp->exp = 0;
3673
    idp->mant = 0;
3674
  }
3675
}
3676
#else
3677
#error "ix_double implementation"
3678
#endif
3679
3680
0
#define ix_double double
3681
3682
static int
3683
ncx_get_double_schar(const void *xp, schar *ip)
3684
0
{
3685
0
  ix_double xx = 0;
3686
0
  get_ix_double(xp, &xx);
3687
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3688
0
#ifdef ERANGE_FILL
3689
0
            *ip = NC_FILL_BYTE;
3690
0
#endif
3691
0
            return NC_ERANGE;
3692
0
        }
3693
0
  *ip = (schar)xx;
3694
0
  return NC_NOERR;
3695
0
}
3696
3697
static int
3698
ncx_get_double_short(const void *xp, short *ip)
3699
0
{
3700
0
  ix_double xx = 0;
3701
0
  get_ix_double(xp, &xx);
3702
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3703
0
#ifdef ERANGE_FILL
3704
0
            *ip = NC_FILL_SHORT;
3705
0
#endif
3706
0
            return NC_ERANGE;
3707
0
        }
3708
0
  *ip = (short)xx;
3709
0
  return NC_NOERR;
3710
0
}
3711
3712
static int
3713
ncx_get_double_int(const void *xp, int *ip)
3714
0
{
3715
0
  ix_double xx = 0;
3716
0
  get_ix_double(xp, &xx);
3717
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3718
0
#ifdef ERANGE_FILL
3719
0
            *ip = NC_FILL_INT;
3720
0
#endif
3721
0
            return NC_ERANGE;
3722
0
        }
3723
0
  *ip = (int)xx;
3724
0
  return NC_NOERR;
3725
0
}
3726
3727
static int
3728
ncx_get_double_long(const void *xp, long *ip)
3729
0
{
3730
0
  ix_double xx = 0;
3731
0
  get_ix_double(xp, &xx);
3732
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3733
0
#ifdef ERANGE_FILL
3734
0
            *ip = NC_FILL_INT;
3735
0
#endif
3736
0
            return NC_ERANGE;
3737
0
        }
3738
0
  *ip = (long)xx;
3739
0
  return NC_NOERR;
3740
0
}
3741
3742
static int
3743
ncx_get_double_longlong(const void *xp, longlong *ip)
3744
0
{
3745
0
  ix_double xx = 0;
3746
0
  get_ix_double(xp, &xx);
3747
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3748
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3749
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3750
0
#ifdef ERANGE_FILL
3751
0
            *ip = NC_FILL_INT64;
3752
0
#endif
3753
0
            return NC_ERANGE;
3754
0
        }
3755
0
  else *ip = (longlong)xx;
3756
0
  return NC_NOERR;
3757
0
}
3758
3759
static int
3760
ncx_get_double_uchar(const void *xp, uchar *ip)
3761
0
{
3762
0
  ix_double xx = 0;
3763
0
  get_ix_double(xp, &xx);
3764
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3765
0
#ifdef ERANGE_FILL
3766
0
            *ip = NC_FILL_UBYTE;
3767
0
#endif
3768
0
            return NC_ERANGE;
3769
0
        }
3770
0
  *ip = (uchar)xx;
3771
0
  return NC_NOERR;
3772
0
}
3773
3774
static int
3775
ncx_get_double_ushort(const void *xp, ushort *ip)
3776
0
{
3777
0
  ix_double xx = 0;
3778
0
  get_ix_double(xp, &xx);
3779
0
  if (xx > (double)USHORT_MAX || xx < 0) {
3780
0
#ifdef ERANGE_FILL
3781
0
            *ip = NC_FILL_USHORT;
3782
0
#endif
3783
0
            return NC_ERANGE;
3784
0
        }
3785
0
  *ip = (ushort)xx;
3786
0
  return NC_NOERR;
3787
0
}
3788
3789
static int
3790
ncx_get_double_uint(const void *xp, uint *ip)
3791
0
{
3792
0
  ix_double xx = 0;
3793
0
  get_ix_double(xp, &xx);
3794
0
  if (xx > (double)UINT_MAX || xx < 0) {
3795
0
#ifdef ERANGE_FILL
3796
0
            *ip = NC_FILL_UINT;
3797
0
#endif
3798
0
            return NC_ERANGE;
3799
0
        }
3800
0
  *ip = (uint)xx;
3801
0
  return NC_NOERR;
3802
0
}
3803
3804
static int
3805
ncx_get_double_ulonglong(const void *xp, ulonglong *ip)
3806
0
{
3807
0
  ix_double xx = 0;
3808
0
  get_ix_double(xp, &xx);
3809
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3810
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3811
0
#ifdef ERANGE_FILL
3812
0
            *ip = NC_FILL_UINT64;
3813
0
#endif
3814
0
            return NC_ERANGE;
3815
0
        }
3816
0
  else *ip = (ulonglong)xx;
3817
0
  return NC_NOERR;
3818
0
}
3819
3820
3821
static int
3822
ncx_get_double_float(const void *xp, float *ip)
3823
0
{
3824
0
    double xx = 0.0;
3825
0
    get_ix_double(xp, &xx);
3826
0
    if (xx > FLT_MAX) {
3827
0
#ifdef ERANGE_FILL
3828
0
        *ip = NC_FILL_FLOAT;
3829
#else
3830
        *ip = FLT_MAX;
3831
#endif
3832
0
        return NC_ERANGE;
3833
0
    }
3834
0
    if (xx < (-FLT_MAX)) {
3835
0
#ifdef ERANGE_FILL
3836
0
        *ip = NC_FILL_FLOAT;
3837
#else
3838
        *ip = (-FLT_MAX);
3839
#endif
3840
0
        return NC_ERANGE;
3841
0
    }
3842
0
    *ip = (float) xx;
3843
0
    return NC_NOERR;
3844
0
}
3845
3846
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
3847
static int
3848
ncx_get_double_double(const void *xp, double *ip, void *fillp)
3849
{
3850
  /* TODO */
3851
  get_ix_double(xp, ip);
3852
  return NC_NOERR;
3853
}
3854
#endif
3855
3856
static int
3857
ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
3858
0
{
3859
0
    int err=NC_NOERR;
3860
0
    ix_double xx = NC_FILL_DOUBLE;
3861
3862
    
3863
0
        xx = (ix_double)*ip;
3864
3865
0
    put_ix_double(xp, &xx);
3866
0
    return err;
3867
0
}
3868
3869
static int
3870
ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
3871
0
{
3872
0
    int err=NC_NOERR;
3873
0
    ix_double xx = NC_FILL_DOUBLE;
3874
3875
    
3876
0
        xx = (ix_double)*ip;
3877
3878
0
    put_ix_double(xp, &xx);
3879
0
    return err;
3880
0
}
3881
3882
static int
3883
ncx_put_double_short(void *xp, const short *ip, void *fillp)
3884
0
{
3885
0
    int err=NC_NOERR;
3886
0
    ix_double xx = NC_FILL_DOUBLE;
3887
3888
    
3889
0
        xx = (ix_double)*ip;
3890
3891
0
    put_ix_double(xp, &xx);
3892
0
    return err;
3893
0
}
3894
3895
static int
3896
ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
3897
0
{
3898
0
    int err=NC_NOERR;
3899
0
    ix_double xx = NC_FILL_DOUBLE;
3900
3901
    
3902
0
        xx = (ix_double)*ip;
3903
3904
0
    put_ix_double(xp, &xx);
3905
0
    return err;
3906
0
}
3907
3908
static int
3909
ncx_put_double_int(void *xp, const int *ip, void *fillp)
3910
0
{
3911
0
    int err=NC_NOERR;
3912
0
    ix_double xx = NC_FILL_DOUBLE;
3913
3914
    
3915
0
        xx = (ix_double)*ip;
3916
3917
0
    put_ix_double(xp, &xx);
3918
0
    return err;
3919
0
}
3920
3921
static int
3922
ncx_put_double_long(void *xp, const long *ip, void *fillp)
3923
0
{
3924
0
    int err=NC_NOERR;
3925
0
    ix_double xx = NC_FILL_DOUBLE;
3926
3927
    
3928
0
        xx = (ix_double)*ip;
3929
3930
0
    put_ix_double(xp, &xx);
3931
0
    return err;
3932
0
}
3933
3934
static int
3935
ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
3936
0
{
3937
0
    int err=NC_NOERR;
3938
0
    ix_double xx = NC_FILL_DOUBLE;
3939
3940
    
3941
0
        xx = (ix_double)*ip;
3942
3943
0
    put_ix_double(xp, &xx);
3944
0
    return err;
3945
0
}
3946
3947
static int
3948
ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
3949
0
{
3950
0
    int err=NC_NOERR;
3951
0
    ix_double xx = NC_FILL_DOUBLE;
3952
3953
    
3954
0
        xx = (ix_double)*ip;
3955
3956
0
    put_ix_double(xp, &xx);
3957
0
    return err;
3958
0
}
3959
3960
static int
3961
ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3962
0
{
3963
0
    int err=NC_NOERR;
3964
0
    ix_double xx = NC_FILL_DOUBLE;
3965
3966
    
3967
0
        xx = (ix_double)*ip;
3968
3969
0
    put_ix_double(xp, &xx);
3970
0
    return err;
3971
0
}
3972
3973
3974
static int
3975
ncx_put_double_float(void *xp, const float *ip, void *fillp)
3976
0
{
3977
0
    int err=NC_NOERR;
3978
0
    double xx = NC_FILL_DOUBLE;
3979
0
#if 1 /* TODO: figure this out (if condition below will never be true)*/
3980
0
    if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
3981
        
3982
0
#ifdef ERANGE_FILL
3983
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
3984
0
#endif
3985
0
        err = NC_ERANGE;
3986
0
    }
3987
0
#ifdef ERANGE_FILL
3988
0
    else
3989
0
#endif
3990
0
#endif
3991
0
        xx = (double) *ip;
3992
3993
0
    put_ix_double(xp, &xx);
3994
0
    return err;
3995
0
}
3996
3997
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
3998
static int
3999
ncx_put_double_double(void *xp, const double *ip, void *fillp)
4000
{
4001
    int err=NC_NOERR;
4002
    double *_ip = ip;
4003
#ifdef NO_IEEE_FLOAT
4004
#ifdef ERANGE_FILL
4005
    double tmp=NC_FILL_DOUBLE;
4006
#endif
4007
    if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
4008
        
4009
#ifdef ERANGE_FILL
4010
            if (fillp != NULL) memcpy(&tmp, fillp, 8);
4011
#endif
4012
#ifdef ERANGE_FILL
4013
        _ip = &tmp;
4014
#endif
4015
        err = NC_ERANGE;
4016
    }
4017
#endif
4018
    put_ix_double(xp, _ip);
4019
    return err;
4020
}
4021
#endif
4022
4023
4024
/* external NC_INT64 --------------------------------------------------------*/
4025
4026
#if SHORT_MAX == X_INT64_MAX
4027
typedef short ix_int64;
4028
#define SIZEOF_IX_INT64 SIZEOF_SHORT
4029
#define IX_INT64_MAX SHORT_MAX
4030
#elif LONG_LONG_MAX  >= X_INT64_MAX
4031
typedef longlong ix_int64;
4032
#define SIZEOF_IX_INT64 SIZEOF_LONGLONG
4033
0
#define IX_INT64_MAX LONG_LONG_MAX
4034
#elif LONG_MAX  >= X_INT64_MAX
4035
typedef long ix_int64;
4036
#define SIZEOF_IX_INT64 SIZEOF_LONG
4037
#define IX_INT64_MAX LONG_MAX
4038
#else
4039
#error "ix_int64 implementation"
4040
#endif
4041
4042
4043
static void
4044
get_ix_int64(const void *xp, ix_int64 *ip)
4045
4.25k
{
4046
4.25k
    const uchar *cp = (const uchar *) xp;
4047
4048
4.25k
    *ip  = ((ix_int64)(*cp++) << 56);
4049
4.25k
    *ip |= ((ix_int64)(*cp++) << 48);
4050
4.25k
    *ip |= ((ix_int64)(*cp++) << 40);
4051
4.25k
    *ip |= ((ix_int64)(*cp++) << 32);
4052
4.25k
    *ip |= ((ix_int64)(*cp++) << 24);
4053
4.25k
    *ip |= ((ix_int64)(*cp++) << 16);
4054
4.25k
    *ip |= ((ix_int64)(*cp++) <<  8);
4055
4.25k
    *ip |=  (ix_int64)*cp;
4056
4.25k
}
4057
4058
static void
4059
put_ix_int64(void *xp, const ix_int64 *ip)
4060
0
{
4061
0
    uchar *cp = (uchar *) xp;
4062
4063
0
    *cp++ = (uchar)((*ip) >> 56);
4064
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48);
4065
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40);
4066
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32);
4067
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24);
4068
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16);
4069
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >>  8);
4070
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffLL);
4071
0
}
4072
4073
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4074
static int
4075
ncx_get_longlong_longlong(const void *xp, longlong *ip)
4076
{
4077
    int err=NC_NOERR;
4078
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4079
    get_ix_int64(xp, (ix_int64 *)ip);
4080
#else
4081
    ix_int64 xx = 0;
4082
    get_ix_int64(xp, &xx);
4083
4084
#if IX_INT64_MAX > LONGLONG_MAX
4085
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
4086
#ifdef ERANGE_FILL
4087
        *ip = NC_FILL_INT64;
4088
        return NC_ERANGE;
4089
#else
4090
        err = NC_ERANGE;
4091
#endif
4092
    }
4093
#endif
4094
4095
4096
    *ip = (longlong) xx;
4097
#endif
4098
    return err;
4099
}
4100
4101
#endif
4102
static int
4103
ncx_get_longlong_schar(const void *xp, schar *ip)
4104
0
{
4105
0
    int err=NC_NOERR;
4106
0
    ix_int64 xx = 0;
4107
0
    get_ix_int64(xp, &xx);
4108
4109
0
#if IX_INT64_MAX > SCHAR_MAX
4110
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
4111
0
#ifdef ERANGE_FILL
4112
0
        *ip = NC_FILL_BYTE;
4113
0
        return NC_ERANGE;
4114
#else
4115
        err = NC_ERANGE;
4116
#endif
4117
0
    }
4118
0
#endif
4119
4120
4121
0
    *ip = (schar) xx;
4122
0
    return err;
4123
0
}
4124
4125
static int
4126
ncx_get_longlong_short(const void *xp, short *ip)
4127
0
{
4128
0
    int err=NC_NOERR;
4129
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4130
    get_ix_int64(xp, (ix_int64 *)ip);
4131
#else
4132
0
    ix_int64 xx = 0;
4133
0
    get_ix_int64(xp, &xx);
4134
4135
0
#if IX_INT64_MAX > SHORT_MAX
4136
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
4137
0
#ifdef ERANGE_FILL
4138
0
        *ip = NC_FILL_SHORT;
4139
0
        return NC_ERANGE;
4140
#else
4141
        err = NC_ERANGE;
4142
#endif
4143
0
    }
4144
0
#endif
4145
4146
4147
0
    *ip = (short) xx;
4148
0
#endif
4149
0
    return err;
4150
0
}
4151
4152
static int
4153
ncx_get_longlong_int(const void *xp, int *ip)
4154
4.25k
{
4155
4.25k
    int err=NC_NOERR;
4156
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4157
    get_ix_int64(xp, (ix_int64 *)ip);
4158
#else
4159
4.25k
    ix_int64 xx = 0;
4160
4.25k
    get_ix_int64(xp, &xx);
4161
4162
4.25k
#if IX_INT64_MAX > INT_MAX
4163
4.25k
    if (xx > INT_MAX || xx < INT_MIN) {
4164
2.28k
#ifdef ERANGE_FILL
4165
2.28k
        *ip = NC_FILL_INT;
4166
2.28k
        return NC_ERANGE;
4167
#else
4168
        err = NC_ERANGE;
4169
#endif
4170
2.28k
    }
4171
1.96k
#endif
4172
4173
4174
1.96k
    *ip = (int) xx;
4175
1.96k
#endif
4176
1.96k
    return err;
4177
4.25k
}
4178
4179
static int
4180
ncx_get_longlong_long(const void *xp, long *ip)
4181
0
{
4182
0
    int err=NC_NOERR;
4183
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4184
0
    get_ix_int64(xp, (ix_int64 *)ip);
4185
#else
4186
    ix_int64 xx = 0;
4187
    get_ix_int64(xp, &xx);
4188
4189
#if IX_INT64_MAX > LONG_MAX
4190
    if (xx > LONG_MAX || xx < LONG_MIN) {
4191
#ifdef ERANGE_FILL
4192
        *ip = NC_FILL_INT;
4193
        return NC_ERANGE;
4194
#else
4195
        err = NC_ERANGE;
4196
#endif
4197
    }
4198
#endif
4199
4200
4201
    *ip = (long) xx;
4202
#endif
4203
0
    return err;
4204
0
}
4205
4206
static int
4207
ncx_get_longlong_ushort(const void *xp, ushort *ip)
4208
0
{
4209
0
    int err=NC_NOERR;
4210
0
    ix_int64 xx = 0;
4211
0
    get_ix_int64(xp, &xx);
4212
4213
0
#if IX_INT64_MAX > USHORT_MAX
4214
0
    if (xx > USHORT_MAX) {
4215
0
#ifdef ERANGE_FILL
4216
0
        *ip = NC_FILL_USHORT;
4217
0
        return NC_ERANGE;
4218
#else
4219
        err = NC_ERANGE;
4220
#endif
4221
0
    }
4222
0
#endif
4223
4224
0
    if (xx < 0) {
4225
0
#ifdef ERANGE_FILL
4226
0
        *ip = NC_FILL_USHORT;
4227
0
        return NC_ERANGE;
4228
#else
4229
        err = NC_ERANGE; /* because ip is unsigned */
4230
#endif
4231
0
    }
4232
0
    *ip = (ushort) xx;
4233
0
    return err;
4234
0
}
4235
4236
static int
4237
ncx_get_longlong_uchar(const void *xp, uchar *ip)
4238
0
{
4239
0
    int err=NC_NOERR;
4240
0
    ix_int64 xx = 0;
4241
0
    get_ix_int64(xp, &xx);
4242
4243
0
#if IX_INT64_MAX > UCHAR_MAX
4244
0
    if (xx > UCHAR_MAX) {
4245
0
#ifdef ERANGE_FILL
4246
0
        *ip = NC_FILL_UBYTE;
4247
0
        return NC_ERANGE;
4248
#else
4249
        err = NC_ERANGE;
4250
#endif
4251
0
    }
4252
0
#endif
4253
4254
0
    if (xx < 0) {
4255
0
#ifdef ERANGE_FILL
4256
0
        *ip = NC_FILL_UBYTE;
4257
0
        return NC_ERANGE;
4258
#else
4259
        err = NC_ERANGE; /* because ip is unsigned */
4260
#endif
4261
0
    }
4262
0
    *ip = (uchar) xx;
4263
0
    return err;
4264
0
}
4265
4266
static int
4267
ncx_get_longlong_uint(const void *xp, uint *ip)
4268
0
{
4269
0
    int err=NC_NOERR;
4270
0
    ix_int64 xx = 0;
4271
0
    get_ix_int64(xp, &xx);
4272
4273
0
#if IX_INT64_MAX > UINT_MAX
4274
0
    if (xx > UINT_MAX) {
4275
0
#ifdef ERANGE_FILL
4276
0
        *ip = NC_FILL_UINT;
4277
0
        return NC_ERANGE;
4278
#else
4279
        err = NC_ERANGE;
4280
#endif
4281
0
    }
4282
0
#endif
4283
4284
0
    if (xx < 0) {
4285
0
#ifdef ERANGE_FILL
4286
0
        *ip = NC_FILL_UINT;
4287
0
        return NC_ERANGE;
4288
#else
4289
        err = NC_ERANGE; /* because ip is unsigned */
4290
#endif
4291
0
    }
4292
0
    *ip = (uint) xx;
4293
0
    return err;
4294
0
}
4295
4296
static int
4297
ncx_get_longlong_ulonglong(const void *xp, ulonglong *ip)
4298
0
{
4299
0
    int err=NC_NOERR;
4300
0
    ix_int64 xx = 0;
4301
0
    get_ix_int64(xp, &xx);
4302
4303
#if IX_INT64_MAX > ULONGLONG_MAX
4304
    if (xx > ULONGLONG_MAX) {
4305
#ifdef ERANGE_FILL
4306
        *ip = NC_FILL_UINT64;
4307
        return NC_ERANGE;
4308
#else
4309
        err = NC_ERANGE;
4310
#endif
4311
    }
4312
#endif
4313
4314
0
    if (xx < 0) {
4315
0
#ifdef ERANGE_FILL
4316
0
        *ip = NC_FILL_UINT64;
4317
0
        return NC_ERANGE;
4318
#else
4319
        err = NC_ERANGE; /* because ip is unsigned */
4320
#endif
4321
0
    }
4322
0
    *ip = (ulonglong) xx;
4323
0
    return err;
4324
0
}
4325
4326
static int
4327
ncx_get_longlong_float(const void *xp, float *ip)
4328
0
{
4329
0
  ix_int64 xx = 0;
4330
0
  get_ix_int64(xp, &xx);
4331
0
  *ip = (float)xx;
4332
0
  return NC_NOERR;
4333
0
}
4334
4335
static int
4336
ncx_get_longlong_double(const void *xp, double *ip)
4337
0
{
4338
0
  ix_int64 xx = 0;
4339
0
  get_ix_int64(xp, &xx);
4340
0
  *ip = (double)xx;
4341
0
  return NC_NOERR;
4342
0
}
4343
4344
4345
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4346
static int
4347
ncx_put_longlong_longlong(void *xp, const longlong *ip, void *fillp)
4348
{
4349
    int err=NC_NOERR;
4350
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4351
    put_ix_int64(xp, (const ix_int64 *)ip);
4352
#else
4353
    ix_int64 xx = NC_FILL_INT64;
4354
4355
#if IX_INT64_MAX < LONGLONG_MAX
4356
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4357
        
4358
#ifdef ERANGE_FILL
4359
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4360
#endif
4361
        err = NC_ERANGE;
4362
    }
4363
#ifdef ERANGE_FILL
4364
    else
4365
#endif
4366
#endif
4367
        xx = (ix_int64)*ip;
4368
4369
    put_ix_int64(xp, &xx);
4370
#endif
4371
    return err;
4372
}
4373
4374
#endif
4375
static int
4376
ncx_put_longlong_schar(void *xp, const schar *ip, void *fillp)
4377
0
{
4378
0
    int err=NC_NOERR;
4379
0
    ix_int64 xx = NC_FILL_INT64;
4380
4381
#if IX_INT64_MAX < SCHAR_MAX
4382
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4383
        
4384
#ifdef ERANGE_FILL
4385
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4386
#endif
4387
        err = NC_ERANGE;
4388
    }
4389
#ifdef ERANGE_FILL
4390
    else
4391
#endif
4392
#endif
4393
0
        xx = (ix_int64)*ip;
4394
4395
0
    put_ix_int64(xp, &xx);
4396
0
    return err;
4397
0
}
4398
4399
static int
4400
ncx_put_longlong_short(void *xp, const short *ip, void *fillp)
4401
0
{
4402
0
    int err=NC_NOERR;
4403
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4404
    put_ix_int64(xp, (const ix_int64 *)ip);
4405
#else
4406
0
    ix_int64 xx = NC_FILL_INT64;
4407
4408
#if IX_INT64_MAX < SHORT_MAX
4409
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4410
        
4411
#ifdef ERANGE_FILL
4412
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4413
#endif
4414
        err = NC_ERANGE;
4415
    }
4416
#ifdef ERANGE_FILL
4417
    else
4418
#endif
4419
#endif
4420
0
        xx = (ix_int64)*ip;
4421
4422
0
    put_ix_int64(xp, &xx);
4423
0
#endif
4424
0
    return err;
4425
0
}
4426
4427
static int
4428
ncx_put_longlong_int(void *xp, const int *ip, void *fillp)
4429
0
{
4430
0
    int err=NC_NOERR;
4431
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4432
    put_ix_int64(xp, (const ix_int64 *)ip);
4433
#else
4434
0
    ix_int64 xx = NC_FILL_INT64;
4435
4436
#if IX_INT64_MAX < INT_MAX
4437
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4438
        
4439
#ifdef ERANGE_FILL
4440
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4441
#endif
4442
        err = NC_ERANGE;
4443
    }
4444
#ifdef ERANGE_FILL
4445
    else
4446
#endif
4447
#endif
4448
0
        xx = (ix_int64)*ip;
4449
4450
0
    put_ix_int64(xp, &xx);
4451
0
#endif
4452
0
    return err;
4453
0
}
4454
4455
static int
4456
ncx_put_longlong_long(void *xp, const long *ip, void *fillp)
4457
0
{
4458
0
    int err=NC_NOERR;
4459
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4460
0
    put_ix_int64(xp, (const ix_int64 *)ip);
4461
#else
4462
    ix_int64 xx = NC_FILL_INT64;
4463
4464
#if IX_INT64_MAX < LONG_MAX
4465
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4466
        
4467
#ifdef ERANGE_FILL
4468
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4469
#endif
4470
        err = NC_ERANGE;
4471
    }
4472
#ifdef ERANGE_FILL
4473
    else
4474
#endif
4475
#endif
4476
        xx = (ix_int64)*ip;
4477
4478
    put_ix_int64(xp, &xx);
4479
#endif
4480
0
    return err;
4481
0
}
4482
4483
static int
4484
ncx_put_longlong_ushort(void *xp, const ushort *ip, void *fillp)
4485
0
{
4486
0
    int err=NC_NOERR;
4487
0
    ix_int64 xx = NC_FILL_INT64;
4488
4489
#if IX_INT64_MAX < USHORT_MAX
4490
    if (*ip > IX_INT64_MAX) {
4491
        
4492
#ifdef ERANGE_FILL
4493
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4494
#endif
4495
        err = NC_ERANGE;
4496
    }
4497
#ifdef ERANGE_FILL
4498
    else
4499
#endif
4500
#endif
4501
0
        xx = (ix_int64)*ip;
4502
4503
0
    put_ix_int64(xp, &xx);
4504
0
    return err;
4505
0
}
4506
4507
static int
4508
ncx_put_longlong_uchar(void *xp, const uchar *ip, void *fillp)
4509
0
{
4510
0
    int err=NC_NOERR;
4511
0
    ix_int64 xx = NC_FILL_INT64;
4512
4513
#if IX_INT64_MAX < UCHAR_MAX
4514
    if (*ip > IX_INT64_MAX) {
4515
        
4516
#ifdef ERANGE_FILL
4517
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4518
#endif
4519
        err = NC_ERANGE;
4520
    }
4521
#ifdef ERANGE_FILL
4522
    else
4523
#endif
4524
#endif
4525
0
        xx = (ix_int64)*ip;
4526
4527
0
    put_ix_int64(xp, &xx);
4528
0
    return err;
4529
0
}
4530
4531
static int
4532
ncx_put_longlong_uint(void *xp, const uint *ip, void *fillp)
4533
0
{
4534
0
    int err=NC_NOERR;
4535
0
    ix_int64 xx = NC_FILL_INT64;
4536
4537
#if IX_INT64_MAX < UINT_MAX
4538
    if (*ip > IX_INT64_MAX) {
4539
        
4540
#ifdef ERANGE_FILL
4541
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4542
#endif
4543
        err = NC_ERANGE;
4544
    }
4545
#ifdef ERANGE_FILL
4546
    else
4547
#endif
4548
#endif
4549
0
        xx = (ix_int64)*ip;
4550
4551
0
    put_ix_int64(xp, &xx);
4552
0
    return err;
4553
0
}
4554
4555
static int
4556
ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4557
0
{
4558
0
    int err=NC_NOERR;
4559
0
    ix_int64 xx = NC_FILL_INT64;
4560
4561
0
#if IX_INT64_MAX < ULONGLONG_MAX
4562
0
    if (*ip > IX_INT64_MAX) {
4563
        
4564
0
#ifdef ERANGE_FILL
4565
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4566
0
#endif
4567
0
        err = NC_ERANGE;
4568
0
    }
4569
0
#ifdef ERANGE_FILL
4570
0
    else
4571
0
#endif
4572
0
#endif
4573
0
        xx = (ix_int64)*ip;
4574
4575
0
    put_ix_int64(xp, &xx);
4576
0
    return err;
4577
0
}
4578
4579
static int
4580
ncx_put_longlong_float(void *xp, const float *ip, void *fillp)
4581
0
{
4582
0
    int err=NC_NOERR;
4583
0
    ix_int64 xx = NC_FILL_INT64;
4584
4585
0
    if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
4586
        
4587
0
#ifdef ERANGE_FILL
4588
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4589
0
#endif
4590
0
        err = NC_ERANGE;
4591
0
    }
4592
0
#ifdef ERANGE_FILL
4593
0
    else
4594
0
#endif
4595
0
        xx = (ix_int64)*ip;
4596
4597
0
    put_ix_int64(xp, &xx);
4598
0
    return err;
4599
0
}
4600
4601
static int
4602
ncx_put_longlong_double(void *xp, const double *ip, void *fillp)
4603
0
{
4604
0
    int err=NC_NOERR;
4605
0
    ix_int64 xx = NC_FILL_INT64;
4606
4607
0
    if (*ip > X_INT64_MAX || *ip < X_INT64_MIN) {
4608
        
4609
0
#ifdef ERANGE_FILL
4610
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4611
0
#endif
4612
0
        err = NC_ERANGE;
4613
0
    }
4614
0
#ifdef ERANGE_FILL
4615
0
    else
4616
0
#endif
4617
0
        xx = (ix_int64)*ip;
4618
4619
0
    put_ix_int64(xp, &xx);
4620
0
    return err;
4621
0
}
4622
4623
4624
4625
/* external NC_UINT64 -------------------------------------------------------*/
4626
4627
#if USHORT_MAX == X_UINT64_MAX
4628
typedef ushort ix_uint64;
4629
#define SIZEOF_IX_UINT64 SIZEOF_USHORT
4630
#define IX_UINT64_MAX USHORT_MAX
4631
#elif ULONG_LONG_MAX  >= X_UINT64_MAX
4632
typedef ulonglong ix_uint64;
4633
#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
4634
#define IX_UINT64_MAX ULONG_LONG_MAX
4635
#elif ULONG_MAX  >= X_UINT64_MAX
4636
typedef ulong ix_uint64;
4637
#define SIZEOF_IX_UINT64 SIZEOF_ULONG
4638
#define IX_UINT64_MAX ULONG_MAX
4639
#else
4640
#error "ix_uint64 implementation"
4641
#endif
4642
4643
4644
static void
4645
get_ix_uint64(const void *xp, ix_uint64 *ip)
4646
0
{
4647
0
    const uchar *cp = (const uchar *) xp;
4648
4649
0
    *ip  = ((ix_uint64)(*cp++) << 56);
4650
0
    *ip |= ((ix_uint64)(*cp++) << 48);
4651
0
    *ip |= ((ix_uint64)(*cp++) << 40);
4652
0
    *ip |= ((ix_uint64)(*cp++) << 32);
4653
0
    *ip |= ((ix_uint64)(*cp++) << 24);
4654
0
    *ip |= ((ix_uint64)(*cp++) << 16);
4655
0
    *ip |= ((ix_uint64)(*cp++) <<  8);
4656
0
    *ip |=  (ix_uint64)*cp;
4657
0
}
4658
4659
static void
4660
put_ix_uint64(void *xp, const ix_uint64 *ip)
4661
0
{
4662
0
    uchar *cp = (uchar *) xp;
4663
4664
0
    *cp++ = (uchar)((*ip) >> 56);
4665
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48);
4666
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40);
4667
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32);
4668
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24);
4669
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16);
4670
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >>  8);
4671
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffULL);
4672
0
}
4673
4674
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4675
static int
4676
ncx_get_ulonglong_ulonglong(const void *xp, ulonglong *ip)
4677
{
4678
    int err=NC_NOERR;
4679
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4680
    get_ix_uint64(xp, (ix_uint64 *)ip);
4681
#else
4682
    ix_uint64 xx = 0;
4683
    get_ix_uint64(xp, &xx);
4684
4685
#if IX_UINT64_MAX > ULONGLONG_MAX
4686
    if (xx > ULONGLONG_MAX) {
4687
#ifdef ERANGE_FILL
4688
        *ip = NC_FILL_UINT64;
4689
        return NC_ERANGE;
4690
#else
4691
        err = NC_ERANGE;
4692
#endif
4693
    }
4694
#endif
4695
4696
4697
    *ip = (ulonglong) xx;
4698
#endif
4699
    return err;
4700
}
4701
4702
#endif
4703
static int
4704
ncx_get_ulonglong_schar(const void *xp, schar *ip)
4705
0
{
4706
0
    int err=NC_NOERR;
4707
0
    ix_uint64 xx = 0;
4708
0
    get_ix_uint64(xp, &xx);
4709
4710
0
#if IX_UINT64_MAX > SCHAR_MAX
4711
0
    if (xx > SCHAR_MAX) {
4712
0
#ifdef ERANGE_FILL
4713
0
        *ip = NC_FILL_BYTE;
4714
0
        return NC_ERANGE;
4715
#else
4716
        err = NC_ERANGE;
4717
#endif
4718
0
    }
4719
0
#endif
4720
4721
4722
0
    *ip = (schar) xx;
4723
0
    return err;
4724
0
}
4725
4726
static int
4727
ncx_get_ulonglong_short(const void *xp, short *ip)
4728
0
{
4729
0
    int err=NC_NOERR;
4730
0
    ix_uint64 xx = 0;
4731
0
    get_ix_uint64(xp, &xx);
4732
4733
0
#if IX_UINT64_MAX > SHORT_MAX
4734
0
    if (xx > SHORT_MAX) {
4735
0
#ifdef ERANGE_FILL
4736
0
        *ip = NC_FILL_SHORT;
4737
0
        return NC_ERANGE;
4738
#else
4739
        err = NC_ERANGE;
4740
#endif
4741
0
    }
4742
0
#endif
4743
4744
4745
0
    *ip = (short) xx;
4746
0
    return err;
4747
0
}
4748
4749
static int
4750
ncx_get_ulonglong_int(const void *xp, int *ip)
4751
0
{
4752
0
    int err=NC_NOERR;
4753
0
    ix_uint64 xx = 0;
4754
0
    get_ix_uint64(xp, &xx);
4755
4756
0
#if IX_UINT64_MAX > INT_MAX
4757
0
    if (xx > INT_MAX) {
4758
0
#ifdef ERANGE_FILL
4759
0
        *ip = NC_FILL_INT;
4760
0
        return NC_ERANGE;
4761
#else
4762
        err = NC_ERANGE;
4763
#endif
4764
0
    }
4765
0
#endif
4766
4767
4768
0
    *ip = (int) xx;
4769
0
    return err;
4770
0
}
4771
4772
static int
4773
ncx_get_ulonglong_long(const void *xp, long *ip)
4774
0
{
4775
0
    int err=NC_NOERR;
4776
0
    ix_uint64 xx = 0;
4777
0
    get_ix_uint64(xp, &xx);
4778
4779
0
#if IX_UINT64_MAX > LONG_MAX
4780
0
    if (xx > LONG_MAX) {
4781
0
#ifdef ERANGE_FILL
4782
0
        *ip = NC_FILL_INT;
4783
0
        return NC_ERANGE;
4784
#else
4785
        err = NC_ERANGE;
4786
#endif
4787
0
    }
4788
0
#endif
4789
4790
4791
0
    *ip = (long) xx;
4792
0
    return err;
4793
0
}
4794
4795
static int
4796
ncx_get_ulonglong_longlong(const void *xp, longlong *ip)
4797
0
{
4798
0
    int err=NC_NOERR;
4799
0
    ix_uint64 xx = 0;
4800
0
    get_ix_uint64(xp, &xx);
4801
4802
0
#if IX_UINT64_MAX > LONGLONG_MAX
4803
0
    if (xx > LONGLONG_MAX) {
4804
0
#ifdef ERANGE_FILL
4805
0
        *ip = NC_FILL_INT64;
4806
0
        return NC_ERANGE;
4807
#else
4808
        err = NC_ERANGE;
4809
#endif
4810
0
    }
4811
0
#endif
4812
4813
4814
0
    *ip = (longlong) xx;
4815
0
    return err;
4816
0
}
4817
4818
static int
4819
ncx_get_ulonglong_ushort(const void *xp, ushort *ip)
4820
0
{
4821
0
    int err=NC_NOERR;
4822
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
4823
    get_ix_uint64(xp, (ix_uint64 *)ip);
4824
#else
4825
0
    ix_uint64 xx = 0;
4826
0
    get_ix_uint64(xp, &xx);
4827
4828
0
#if IX_UINT64_MAX > USHORT_MAX
4829
0
    if (xx > USHORT_MAX) {
4830
0
#ifdef ERANGE_FILL
4831
0
        *ip = NC_FILL_USHORT;
4832
0
        return NC_ERANGE;
4833
#else
4834
        err = NC_ERANGE;
4835
#endif
4836
0
    }
4837
0
#endif
4838
4839
4840
0
    *ip = (ushort) xx;
4841
0
#endif
4842
0
    return err;
4843
0
}
4844
4845
static int
4846
ncx_get_ulonglong_uchar(const void *xp, uchar *ip)
4847
0
{
4848
0
    int err=NC_NOERR;
4849
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
4850
    get_ix_uint64(xp, (ix_uint64 *)ip);
4851
#else
4852
0
    ix_uint64 xx = 0;
4853
0
    get_ix_uint64(xp, &xx);
4854
4855
0
#if IX_UINT64_MAX > UCHAR_MAX
4856
0
    if (xx > UCHAR_MAX) {
4857
0
#ifdef ERANGE_FILL
4858
0
        *ip = NC_FILL_UBYTE;
4859
0
        return NC_ERANGE;
4860
#else
4861
        err = NC_ERANGE;
4862
#endif
4863
0
    }
4864
0
#endif
4865
4866
4867
0
    *ip = (uchar) xx;
4868
0
#endif
4869
0
    return err;
4870
0
}
4871
4872
static int
4873
ncx_get_ulonglong_uint(const void *xp, uint *ip)
4874
0
{
4875
0
    int err=NC_NOERR;
4876
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
4877
    get_ix_uint64(xp, (ix_uint64 *)ip);
4878
#else
4879
0
    ix_uint64 xx = 0;
4880
0
    get_ix_uint64(xp, &xx);
4881
4882
0
#if IX_UINT64_MAX > UINT_MAX
4883
0
    if (xx > UINT_MAX) {
4884
0
#ifdef ERANGE_FILL
4885
0
        *ip = NC_FILL_UINT;
4886
0
        return NC_ERANGE;
4887
#else
4888
        err = NC_ERANGE;
4889
#endif
4890
0
    }
4891
0
#endif
4892
4893
4894
0
    *ip = (uint) xx;
4895
0
#endif
4896
0
    return err;
4897
0
}
4898
4899
static int
4900
ncx_get_ulonglong_float(const void *xp, float *ip)
4901
0
{
4902
0
  ix_uint64 xx = 0;
4903
0
  get_ix_uint64(xp, &xx);
4904
0
  *ip = (float)xx;
4905
0
  return NC_NOERR;
4906
0
}
4907
4908
static int
4909
ncx_get_ulonglong_double(const void *xp, double *ip)
4910
0
{
4911
0
  ix_uint64 xx = 0;
4912
0
  get_ix_uint64(xp, &xx);
4913
0
  *ip = (double)xx;
4914
0
  return NC_NOERR;
4915
0
}
4916
4917
4918
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4919
static int
4920
ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4921
{
4922
    int err=NC_NOERR;
4923
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4924
    put_ix_uint64(xp, (const ix_uint64 *)ip);
4925
#else
4926
    ix_uint64 xx = NC_FILL_UINT64;
4927
4928
#if IX_UINT64_MAX < ULONGLONG_MAX
4929
    if (*ip > IX_UINT64_MAX) {
4930
        
4931
#ifdef ERANGE_FILL
4932
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4933
#endif
4934
        err = NC_ERANGE;
4935
    }
4936
#ifdef ERANGE_FILL
4937
    else
4938
#endif
4939
#endif
4940
        xx = (ix_uint64)*ip;
4941
4942
    put_ix_uint64(xp, &xx);
4943
#endif
4944
    return err;
4945
}
4946
4947
#endif
4948
static int
4949
ncx_put_ulonglong_schar(void *xp, const schar *ip, void *fillp)
4950
0
{
4951
0
    int err=NC_NOERR;
4952
0
    ix_uint64 xx = NC_FILL_UINT64;
4953
4954
#if IX_UINT64_MAX < SCHAR_MAX
4955
    if (*ip > IX_UINT64_MAX) {
4956
        
4957
#ifdef ERANGE_FILL
4958
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4959
#endif
4960
        err = NC_ERANGE;
4961
    }
4962
#ifdef ERANGE_FILL
4963
    else
4964
#endif
4965
#endif
4966
0
    if (*ip < 0) {
4967
        
4968
0
#ifdef ERANGE_FILL
4969
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4970
0
#endif
4971
0
        err = NC_ERANGE; /* because xp is unsigned */
4972
0
    }
4973
0
#ifdef ERANGE_FILL
4974
0
    else
4975
0
#endif
4976
0
        xx = (ix_uint64)*ip;
4977
4978
0
    put_ix_uint64(xp, &xx);
4979
0
    return err;
4980
0
}
4981
4982
static int
4983
ncx_put_ulonglong_short(void *xp, const short *ip, void *fillp)
4984
0
{
4985
0
    int err=NC_NOERR;
4986
0
    ix_uint64 xx = NC_FILL_UINT64;
4987
4988
#if IX_UINT64_MAX < SHORT_MAX
4989
    if (*ip > IX_UINT64_MAX) {
4990
        
4991
#ifdef ERANGE_FILL
4992
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4993
#endif
4994
        err = NC_ERANGE;
4995
    }
4996
#ifdef ERANGE_FILL
4997
    else
4998
#endif
4999
#endif
5000
0
    if (*ip < 0) {
5001
        
5002
0
#ifdef ERANGE_FILL
5003
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5004
0
#endif
5005
0
        err = NC_ERANGE; /* because xp is unsigned */
5006
0
    }
5007
0
#ifdef ERANGE_FILL
5008
0
    else
5009
0
#endif
5010
0
        xx = (ix_uint64)*ip;
5011
5012
0
    put_ix_uint64(xp, &xx);
5013
0
    return err;
5014
0
}
5015
5016
static int
5017
ncx_put_ulonglong_int(void *xp, const int *ip, void *fillp)
5018
0
{
5019
0
    int err=NC_NOERR;
5020
0
    ix_uint64 xx = NC_FILL_UINT64;
5021
5022
#if IX_UINT64_MAX < INT_MAX
5023
    if (*ip > IX_UINT64_MAX) {
5024
        
5025
#ifdef ERANGE_FILL
5026
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5027
#endif
5028
        err = NC_ERANGE;
5029
    }
5030
#ifdef ERANGE_FILL
5031
    else
5032
#endif
5033
#endif
5034
0
    if (*ip < 0) {
5035
        
5036
0
#ifdef ERANGE_FILL
5037
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5038
0
#endif
5039
0
        err = NC_ERANGE; /* because xp is unsigned */
5040
0
    }
5041
0
#ifdef ERANGE_FILL
5042
0
    else
5043
0
#endif
5044
0
        xx = (ix_uint64)*ip;
5045
5046
0
    put_ix_uint64(xp, &xx);
5047
0
    return err;
5048
0
}
5049
5050
static int
5051
ncx_put_ulonglong_long(void *xp, const long *ip, void *fillp)
5052
0
{
5053
0
    int err=NC_NOERR;
5054
0
    ix_uint64 xx = NC_FILL_UINT64;
5055
5056
#if IX_UINT64_MAX < LONG_MAX
5057
    if (*ip > IX_UINT64_MAX) {
5058
        
5059
#ifdef ERANGE_FILL
5060
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5061
#endif
5062
        err = NC_ERANGE;
5063
    }
5064
#ifdef ERANGE_FILL
5065
    else
5066
#endif
5067
#endif
5068
0
    if (*ip < 0) {
5069
        
5070
0
#ifdef ERANGE_FILL
5071
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5072
0
#endif
5073
0
        err = NC_ERANGE; /* because xp is unsigned */
5074
0
    }
5075
0
#ifdef ERANGE_FILL
5076
0
    else
5077
0
#endif
5078
0
        xx = (ix_uint64)*ip;
5079
5080
0
    put_ix_uint64(xp, &xx);
5081
0
    return err;
5082
0
}
5083
5084
static int
5085
ncx_put_ulonglong_longlong(void *xp, const longlong *ip, void *fillp)
5086
0
{
5087
0
    int err=NC_NOERR;
5088
0
    ix_uint64 xx = NC_FILL_UINT64;
5089
5090
#if IX_UINT64_MAX < LONGLONG_MAX
5091
    if (*ip > IX_UINT64_MAX) {
5092
        
5093
#ifdef ERANGE_FILL
5094
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5095
#endif
5096
        err = NC_ERANGE;
5097
    }
5098
#ifdef ERANGE_FILL
5099
    else
5100
#endif
5101
#endif
5102
0
    if (*ip < 0) {
5103
        
5104
0
#ifdef ERANGE_FILL
5105
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5106
0
#endif
5107
0
        err = NC_ERANGE; /* because xp is unsigned */
5108
0
    }
5109
0
#ifdef ERANGE_FILL
5110
0
    else
5111
0
#endif
5112
0
        xx = (ix_uint64)*ip;
5113
5114
0
    put_ix_uint64(xp, &xx);
5115
0
    return err;
5116
0
}
5117
5118
static int
5119
ncx_put_ulonglong_uchar(void *xp, const uchar *ip, void *fillp)
5120
0
{
5121
0
    int err=NC_NOERR;
5122
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5123
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5124
#else
5125
0
    ix_uint64 xx = NC_FILL_UINT64;
5126
5127
#if IX_UINT64_MAX < UCHAR_MAX
5128
    if (*ip > IX_UINT64_MAX) {
5129
        
5130
#ifdef ERANGE_FILL
5131
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5132
#endif
5133
        err = NC_ERANGE;
5134
    }
5135
#ifdef ERANGE_FILL
5136
    else
5137
#endif
5138
#endif
5139
0
        xx = (ix_uint64)*ip;
5140
5141
0
    put_ix_uint64(xp, &xx);
5142
0
#endif
5143
0
    return err;
5144
0
}
5145
5146
static int
5147
ncx_put_ulonglong_ushort(void *xp, const ushort *ip, void *fillp)
5148
0
{
5149
0
    int err=NC_NOERR;
5150
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5151
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5152
#else
5153
0
    ix_uint64 xx = NC_FILL_UINT64;
5154
5155
#if IX_UINT64_MAX < USHORT_MAX
5156
    if (*ip > IX_UINT64_MAX) {
5157
        
5158
#ifdef ERANGE_FILL
5159
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5160
#endif
5161
        err = NC_ERANGE;
5162
    }
5163
#ifdef ERANGE_FILL
5164
    else
5165
#endif
5166
#endif
5167
0
        xx = (ix_uint64)*ip;
5168
5169
0
    put_ix_uint64(xp, &xx);
5170
0
#endif
5171
0
    return err;
5172
0
}
5173
5174
static int
5175
ncx_put_ulonglong_uint(void *xp, const uint *ip, void *fillp)
5176
0
{
5177
0
    int err=NC_NOERR;
5178
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5179
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5180
#else
5181
0
    ix_uint64 xx = NC_FILL_UINT64;
5182
5183
#if IX_UINT64_MAX < UINT_MAX
5184
    if (*ip > IX_UINT64_MAX) {
5185
        
5186
#ifdef ERANGE_FILL
5187
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5188
#endif
5189
        err = NC_ERANGE;
5190
    }
5191
#ifdef ERANGE_FILL
5192
    else
5193
#endif
5194
#endif
5195
0
        xx = (ix_uint64)*ip;
5196
5197
0
    put_ix_uint64(xp, &xx);
5198
0
#endif
5199
0
    return err;
5200
0
}
5201
5202
static int
5203
ncx_put_ulonglong_float(void *xp, const float *ip, void *fillp)
5204
0
{
5205
0
    int err=NC_NOERR;
5206
0
    ix_uint64 xx = NC_FILL_UINT64;
5207
5208
0
    if (*ip > (double)X_UINT64_MAX || *ip < 0) {
5209
        
5210
0
#ifdef ERANGE_FILL
5211
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5212
0
#endif
5213
0
        err = NC_ERANGE;
5214
0
    }
5215
0
#ifdef ERANGE_FILL
5216
0
    else
5217
0
#endif
5218
0
        xx = (ix_uint64)*ip;
5219
5220
0
    put_ix_uint64(xp, &xx);
5221
0
    return err;
5222
0
}
5223
5224
static int
5225
ncx_put_ulonglong_double(void *xp, const double *ip, void *fillp)
5226
0
{
5227
0
    int err=NC_NOERR;
5228
0
    ix_uint64 xx = NC_FILL_UINT64;
5229
5230
0
    if (*ip > X_UINT64_MAX || *ip < 0) {
5231
        
5232
0
#ifdef ERANGE_FILL
5233
0
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5234
0
#endif
5235
0
        err = NC_ERANGE;
5236
0
    }
5237
0
#ifdef ERANGE_FILL
5238
0
    else
5239
0
#endif
5240
0
        xx = (ix_uint64)*ip;
5241
5242
0
    put_ix_uint64(xp, &xx);
5243
0
    return err;
5244
0
}
5245
5246
5247
5248
/* x_size_t */
5249
5250
#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
5251
#error "x_size_t implementation"
5252
/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
5253
#endif
5254
5255
int
5256
ncx_put_size_t(void **xpp, const size_t *ulp)
5257
0
{
5258
  /* similar to put_ix_int() */
5259
0
  uchar *cp = (uchar *) *xpp;
5260
0
  assert(*ulp <= X_SIZE_MAX);
5261
5262
0
  *cp++ = (uchar)((*ulp) >> 24);
5263
0
  *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
5264
0
  *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
5265
0
  *cp   = (uchar)((*ulp) & 0x000000ff);
5266
5267
0
  *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
5268
0
  return NC_NOERR;
5269
0
}
5270
5271
int
5272
ncx_get_size_t(const void **xpp,  size_t *ulp)
5273
982k
{
5274
  /* similar to get_ix_int */
5275
982k
  const uchar *cp = (const uchar *) *xpp;
5276
5277
982k
  *ulp  = (unsigned)(*cp++) << 24;
5278
982k
  *ulp |= (*cp++ << 16);
5279
982k
  *ulp |= (*cp++ << 8);
5280
982k
  *ulp |= *cp;
5281
5282
982k
  *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
5283
982k
  return NC_NOERR;
5284
982k
}
5285
5286
/* x_off_t */
5287
5288
int
5289
ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
5290
0
{
5291
  /* similar to put_ix_int() */
5292
0
  uchar *cp = (uchar *) *xpp;
5293
5294
  /* No negative offsets stored in netcdf */
5295
0
  if (*lp < 0) {
5296
    /* Assume this is an overflow of a 32-bit int... */
5297
0
    return NC_ERANGE;
5298
0
  }
5299
5300
0
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5301
5302
0
  if (sizeof_off_t == 4) {
5303
0
    *cp++ = (uchar) ((*lp)               >> 24);
5304
0
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5305
0
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5306
0
    *cp   = (uchar)( (*lp) & 0x000000ff);
5307
0
  } else {
5308
#if SIZEOF_OFF_T == 4
5309
/* Write a 64-bit offset on a system with only a 32-bit offset */
5310
    *cp++ = (uchar)0;
5311
    *cp++ = (uchar)0;
5312
    *cp++ = (uchar)0;
5313
    *cp++ = (uchar)0;
5314
5315
    *cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
5316
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5317
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5318
    *cp   = (uchar)( (*lp) & 0x000000ff);
5319
#else
5320
0
    *cp++ = (uchar) ((*lp)                          >> 56);
5321
0
    *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48);
5322
0
    *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40);
5323
0
    *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32);
5324
0
    *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24);
5325
0
    *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16);
5326
0
    *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >>  8);
5327
0
    *cp   = (uchar)( (*lp) & 0x00000000000000ffLL);
5328
0
#endif
5329
0
  }
5330
0
  *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
5331
0
  return NC_NOERR;
5332
0
}
5333
5334
int
5335
ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
5336
142k
{
5337
  /* similar to get_ix_int() */
5338
142k
  const uchar *cp = (const uchar *) *xpp;
5339
142k
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5340
5341
142k
  if (sizeof_off_t == 4) {
5342
1.90k
    *lp =  (off_t)(*cp++ << 24);
5343
1.90k
    *lp |= (off_t)(*cp++ << 16);
5344
1.90k
    *lp |= (off_t)(*cp++ <<  8);
5345
1.90k
    *lp |= (off_t)*cp;
5346
140k
  } else {
5347
#if SIZEOF_OFF_T == 4
5348
/* Read a 64-bit offset on a system with only a 32-bit offset */
5349
/* If the offset overflows, set an error code and return */
5350
    *lp =  ((off_t)(*cp++) << 24);
5351
    *lp |= ((off_t)(*cp++) << 16);
5352
    *lp |= ((off_t)(*cp++) <<  8);
5353
    *lp |= ((off_t)(*cp++));
5354
/*
5355
 * lp now contains the upper 32-bits of the 64-bit offset.  if lp is
5356
 * not zero, then the dataset is larger than can be represented
5357
 * on this system.  Set an error code and return.
5358
 */
5359
    if (*lp != 0) {
5360
      return NC_ERANGE;
5361
    }
5362
5363
    *lp  = ((off_t)(*cp++) << 24);
5364
    *lp |= ((off_t)(*cp++) << 16);
5365
    *lp |= ((off_t)(*cp++) <<  8);
5366
    *lp |=  (off_t)*cp;
5367
5368
    if (*lp < 0) {
5369
      /*
5370
       * If this fails, then the offset is >2^31, but less
5371
       * than 2^32 which is not allowed, but is not caught
5372
       * by the previous check
5373
       */
5374
      return NC_ERANGE;
5375
    }
5376
#else
5377
140k
    *lp =  ((off_t)(*cp++) << 56);
5378
140k
    *lp |= ((off_t)(*cp++) << 48);
5379
140k
    *lp |= ((off_t)(*cp++) << 40);
5380
140k
    *lp |= ((off_t)(*cp++) << 32);
5381
140k
    *lp |= ((off_t)(*cp++) << 24);
5382
140k
    *lp |= ((off_t)(*cp++) << 16);
5383
140k
    *lp |= ((off_t)(*cp++) <<  8);
5384
140k
    *lp |=  (off_t)*cp;
5385
140k
#endif
5386
140k
  }
5387
142k
  *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
5388
142k
  return NC_NOERR;
5389
142k
}
5390
5391
/*----< ncx_get_uint32() >------------------------------------------*/
5392
int
5393
ncx_get_uint32(const void **xpp, uint *ip)
5394
313k
{
5395
#ifdef WORDS_BIGENDIAN
5396
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5397
     * some system, such as HPUX */
5398
    (void) memcpy(ip, *xpp, SIZEOF_UINT);
5399
#else
5400
313k
    const uchar *cp = (const uchar *) *xpp;
5401
5402
313k
    *ip = (uint)(*cp++ << 24);
5403
313k
    *ip = (uint)(*ip | (uint)(*cp++ << 16));
5404
313k
    *ip = (uint)(*ip | (uint)(*cp++ <<  8));
5405
313k
    *ip = (uint)(*ip | *cp);
5406
313k
#endif
5407
    /* advance *xpp 4 bytes */
5408
313k
    *xpp = (void *)((const char *)(*xpp) + 4);
5409
5410
313k
    return NC_NOERR;
5411
313k
}
5412
5413
/*----< ncx_get_uint64() >------------------------------------------*/
5414
int
5415
ncx_get_uint64(const void **xpp, unsigned long long *ullp)
5416
280k
{
5417
#ifdef WORDS_BIGENDIAN
5418
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5419
     * some system, such as HPUX */
5420
    (void) memcpy(ullp, *xpp, SIZEOF_UINT64);
5421
#else
5422
280k
    const uchar *cp = (const uchar *) *xpp;
5423
5424
    /* below is the same as calling swap8b(ullp, *xpp) */
5425
280k
    *ullp = (unsigned long long)(*cp++) << 56;
5426
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48);
5427
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40);
5428
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32);
5429
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24);
5430
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16);
5431
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) <<  8);
5432
280k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp));
5433
280k
#endif
5434
    /* advance *xpp 8 bytes */
5435
280k
    *xpp = (void *)((const char *)(*xpp) + 8);
5436
5437
280k
    return NC_NOERR;
5438
280k
}
5439
5440
/*---< ncx_put_uint32() >-------------------------------------------*/
5441
/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
5442
 * form and advance *xpp 4 bytes
5443
 */
5444
int
5445
ncx_put_uint32(void **xpp, const unsigned int ip)
5446
0
{
5447
#ifdef WORDS_BIGENDIAN
5448
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5449
     * some system, such as HPUX */
5450
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
5451
#else
5452
    /* bitwise shifts below are to produce an integer in Big Endian */
5453
0
    uchar *cp = (uchar *) *xpp;
5454
0
    *cp++ = (uchar)((ip & 0xff000000) >> 24);
5455
0
    *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
5456
0
    *cp++ = (uchar)((ip & 0x0000ff00) >>  8);
5457
0
    *cp   = (uchar)( ip & 0x000000ff);
5458
0
#endif
5459
    /* advance *xpp 4 bytes */
5460
0
    *xpp  = (void *)((char *)(*xpp) + 4);
5461
5462
0
    return NC_NOERR;
5463
0
}
5464
5465
/*---< ncx_put_uint64() >-------------------------------------------*/
5466
/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
5467
 * form and advance *xpp 8 bytes
5468
 */
5469
int
5470
ncx_put_uint64(void **xpp, const unsigned long long ip)
5471
0
{
5472
#ifdef WORDS_BIGENDIAN
5473
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5474
     * some system, such as HPUX */
5475
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
5476
#else
5477
0
    uchar *cp = (uchar *) *xpp;
5478
    /* below is the same as calling swap8b(*xpp, &ip) */
5479
0
    *cp++ = (uchar) (ip                         >> 56);
5480
0
    *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48);
5481
0
    *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40);
5482
0
    *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32);
5483
0
    *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24);
5484
0
    *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16);
5485
0
    *cp++ = (uchar)((ip & 0x000000000000ff00LL) >>  8);
5486
0
    *cp   = (uchar) (ip & 0x00000000000000ffLL);
5487
0
#endif
5488
    /* advance *xpp 8 bytes */
5489
0
    *xpp  = (void *)((char *)(*xpp) + 8);
5490
5491
0
    return NC_NOERR;
5492
0
}
5493
5494
5495
/*
5496
 * Aggregate numeric conversion functions.
5497
 */
5498
5499
5500
5501
/* schar ---------------------------------------------------------------------*/
5502
5503
int
5504
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5505
291
{
5506
291
    (void) memcpy(tp, *xpp, (size_t)nelems);
5507
291
  *xpp = (void *)((char *)(*xpp) + nelems);
5508
291
  return NC_NOERR;
5509
5510
291
}
5511
int
5512
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5513
0
{
5514
0
    int status = NC_NOERR;
5515
0
    schar *xp = (schar *)(*xpp);
5516
5517
0
    while (nelems-- != 0) {
5518
        
5519
0
        if (*xp < 0) {
5520
0
#ifdef ERANGE_FILL
5521
0
            *tp = NC_FILL_UBYTE;
5522
0
#endif
5523
0
            status = NC_ERANGE; /* because tp is unsigned */
5524
            
5525
0
#ifdef ERANGE_FILL
5526
0
            xp++; tp++; continue;
5527
0
#endif
5528
0
        }
5529
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5530
0
    }
5531
5532
0
    *xpp = (const void *)xp;
5533
0
    return status;
5534
0
}
5535
5536
int
5537
ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5538
0
{
5539
0
    int status = NC_NOERR;
5540
0
    schar *xp = (schar *)(*xpp);
5541
5542
0
    while (nelems-- != 0) {
5543
        
5544
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5545
0
    }
5546
5547
0
    *xpp = (const void *)xp;
5548
0
    return status;
5549
0
}
5550
5551
int
5552
ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5553
0
{
5554
0
    int status = NC_NOERR;
5555
0
    schar *xp = (schar *)(*xpp);
5556
5557
0
    while (nelems-- != 0) {
5558
        
5559
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5560
0
    }
5561
5562
0
    *xpp = (const void *)xp;
5563
0
    return status;
5564
0
}
5565
5566
int
5567
ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5568
0
{
5569
0
    int status = NC_NOERR;
5570
0
    schar *xp = (schar *)(*xpp);
5571
5572
0
    while (nelems-- != 0) {
5573
        
5574
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5575
0
    }
5576
5577
0
    *xpp = (const void *)xp;
5578
0
    return status;
5579
0
}
5580
5581
int
5582
ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5583
0
{
5584
0
    int status = NC_NOERR;
5585
0
    schar *xp = (schar *)(*xpp);
5586
5587
0
    while (nelems-- != 0) {
5588
        
5589
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5590
0
    }
5591
5592
0
    *xpp = (const void *)xp;
5593
0
    return status;
5594
0
}
5595
5596
int
5597
ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5598
0
{
5599
0
    int status = NC_NOERR;
5600
0
    schar *xp = (schar *)(*xpp);
5601
5602
0
    while (nelems-- != 0) {
5603
        
5604
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5605
0
    }
5606
5607
0
    *xpp = (const void *)xp;
5608
0
    return status;
5609
0
}
5610
5611
int
5612
ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5613
0
{
5614
0
    int status = NC_NOERR;
5615
0
    schar *xp = (schar *)(*xpp);
5616
5617
0
    while (nelems-- != 0) {
5618
        
5619
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5620
0
    }
5621
5622
0
    *xpp = (const void *)xp;
5623
0
    return status;
5624
0
}
5625
5626
int
5627
ncx_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5628
0
{
5629
0
    int status = NC_NOERR;
5630
0
    schar *xp = (schar *)(*xpp);
5631
5632
0
    while (nelems-- != 0) {
5633
        
5634
0
        if (*xp < 0) {
5635
0
#ifdef ERANGE_FILL
5636
0
            *tp = NC_FILL_USHORT;
5637
0
#endif
5638
0
            status = NC_ERANGE; /* because tp is unsigned */
5639
            
5640
0
#ifdef ERANGE_FILL
5641
0
            xp++; tp++; continue;
5642
0
#endif
5643
0
        }
5644
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5645
0
    }
5646
5647
0
    *xpp = (const void *)xp;
5648
0
    return status;
5649
0
}
5650
5651
int
5652
ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5653
0
{
5654
0
    int status = NC_NOERR;
5655
0
    schar *xp = (schar *)(*xpp);
5656
5657
0
    while (nelems-- != 0) {
5658
        
5659
0
        if (*xp < 0) {
5660
0
#ifdef ERANGE_FILL
5661
0
            *tp = NC_FILL_UINT;
5662
0
#endif
5663
0
            status = NC_ERANGE; /* because tp is unsigned */
5664
            
5665
0
#ifdef ERANGE_FILL
5666
0
            xp++; tp++; continue;
5667
0
#endif
5668
0
        }
5669
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5670
0
    }
5671
5672
0
    *xpp = (const void *)xp;
5673
0
    return status;
5674
0
}
5675
5676
int
5677
ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5678
0
{
5679
0
    int status = NC_NOERR;
5680
0
    schar *xp = (schar *)(*xpp);
5681
5682
0
    while (nelems-- != 0) {
5683
        
5684
0
        if (*xp < 0) {
5685
0
#ifdef ERANGE_FILL
5686
0
            *tp = NC_FILL_UINT64;
5687
0
#endif
5688
0
            status = NC_ERANGE; /* because tp is unsigned */
5689
            
5690
0
#ifdef ERANGE_FILL
5691
0
            xp++; tp++; continue;
5692
0
#endif
5693
0
        }
5694
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5695
0
    }
5696
5697
0
    *xpp = (const void *)xp;
5698
0
    return status;
5699
0
}
5700
5701
5702
int
5703
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5704
0
{
5705
0
    size_t rndup = nelems % X_ALIGN;
5706
5707
0
  if (rndup)
5708
0
    rndup = X_ALIGN - rndup;
5709
5710
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
5711
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
5712
5713
0
  return NC_NOERR;
5714
5715
0
}
5716
int
5717
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5718
0
{
5719
0
    int status = NC_NOERR;
5720
0
    size_t rndup = nelems % X_ALIGN;
5721
0
    schar *xp = (schar *) *xpp;
5722
5723
0
    if (rndup)
5724
0
        rndup = X_ALIGN - rndup;
5725
5726
0
    while (nelems-- != 0) {
5727
        
5728
0
        if (*xp < 0) {
5729
0
#ifdef ERANGE_FILL
5730
0
            *tp = NC_FILL_UBYTE;
5731
0
#endif
5732
0
            status = NC_ERANGE; /* because tp is unsigned */
5733
            
5734
0
#ifdef ERANGE_FILL
5735
0
            xp++; tp++; continue;
5736
0
#endif
5737
0
        }
5738
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5739
0
    }
5740
5741
0
    *xpp = (void *)(xp + rndup);
5742
0
    return status;
5743
0
}
5744
5745
int
5746
ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5747
0
{
5748
0
    int status = NC_NOERR;
5749
0
    size_t rndup = nelems % X_ALIGN;
5750
0
    schar *xp = (schar *) *xpp;
5751
5752
0
    if (rndup)
5753
0
        rndup = X_ALIGN - rndup;
5754
5755
0
    while (nelems-- != 0) {
5756
        
5757
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5758
0
    }
5759
5760
0
    *xpp = (void *)(xp + rndup);
5761
0
    return status;
5762
0
}
5763
5764
int
5765
ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5766
0
{
5767
0
    int status = NC_NOERR;
5768
0
    size_t rndup = nelems % X_ALIGN;
5769
0
    schar *xp = (schar *) *xpp;
5770
5771
0
    if (rndup)
5772
0
        rndup = X_ALIGN - rndup;
5773
5774
0
    while (nelems-- != 0) {
5775
        
5776
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5777
0
    }
5778
5779
0
    *xpp = (void *)(xp + rndup);
5780
0
    return status;
5781
0
}
5782
5783
int
5784
ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5785
0
{
5786
0
    int status = NC_NOERR;
5787
0
    size_t rndup = nelems % X_ALIGN;
5788
0
    schar *xp = (schar *) *xpp;
5789
5790
0
    if (rndup)
5791
0
        rndup = X_ALIGN - rndup;
5792
5793
0
    while (nelems-- != 0) {
5794
        
5795
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5796
0
    }
5797
5798
0
    *xpp = (void *)(xp + rndup);
5799
0
    return status;
5800
0
}
5801
5802
int
5803
ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5804
0
{
5805
0
    int status = NC_NOERR;
5806
0
    size_t rndup = nelems % X_ALIGN;
5807
0
    schar *xp = (schar *) *xpp;
5808
5809
0
    if (rndup)
5810
0
        rndup = X_ALIGN - rndup;
5811
5812
0
    while (nelems-- != 0) {
5813
        
5814
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5815
0
    }
5816
5817
0
    *xpp = (void *)(xp + rndup);
5818
0
    return status;
5819
0
}
5820
5821
int
5822
ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5823
0
{
5824
0
    int status = NC_NOERR;
5825
0
    size_t rndup = nelems % X_ALIGN;
5826
0
    schar *xp = (schar *) *xpp;
5827
5828
0
    if (rndup)
5829
0
        rndup = X_ALIGN - rndup;
5830
5831
0
    while (nelems-- != 0) {
5832
        
5833
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5834
0
    }
5835
5836
0
    *xpp = (void *)(xp + rndup);
5837
0
    return status;
5838
0
}
5839
5840
int
5841
ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5842
0
{
5843
0
    int status = NC_NOERR;
5844
0
    size_t rndup = nelems % X_ALIGN;
5845
0
    schar *xp = (schar *) *xpp;
5846
5847
0
    if (rndup)
5848
0
        rndup = X_ALIGN - rndup;
5849
5850
0
    while (nelems-- != 0) {
5851
        
5852
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5853
0
    }
5854
5855
0
    *xpp = (void *)(xp + rndup);
5856
0
    return status;
5857
0
}
5858
5859
int
5860
ncx_pad_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5861
0
{
5862
0
    int status = NC_NOERR;
5863
0
    size_t rndup = nelems % X_ALIGN;
5864
0
    schar *xp = (schar *) *xpp;
5865
5866
0
    if (rndup)
5867
0
        rndup = X_ALIGN - rndup;
5868
5869
0
    while (nelems-- != 0) {
5870
        
5871
0
        if (*xp < 0) {
5872
0
#ifdef ERANGE_FILL
5873
0
            *tp = NC_FILL_USHORT;
5874
0
#endif
5875
0
            status = NC_ERANGE; /* because tp is unsigned */
5876
            
5877
0
#ifdef ERANGE_FILL
5878
0
            xp++; tp++; continue;
5879
0
#endif
5880
0
        }
5881
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5882
0
    }
5883
5884
0
    *xpp = (void *)(xp + rndup);
5885
0
    return status;
5886
0
}
5887
5888
int
5889
ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5890
0
{
5891
0
    int status = NC_NOERR;
5892
0
    size_t rndup = nelems % X_ALIGN;
5893
0
    schar *xp = (schar *) *xpp;
5894
5895
0
    if (rndup)
5896
0
        rndup = X_ALIGN - rndup;
5897
5898
0
    while (nelems-- != 0) {
5899
        
5900
0
        if (*xp < 0) {
5901
0
#ifdef ERANGE_FILL
5902
0
            *tp = NC_FILL_UINT;
5903
0
#endif
5904
0
            status = NC_ERANGE; /* because tp is unsigned */
5905
            
5906
0
#ifdef ERANGE_FILL
5907
0
            xp++; tp++; continue;
5908
0
#endif
5909
0
        }
5910
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5911
0
    }
5912
5913
0
    *xpp = (void *)(xp + rndup);
5914
0
    return status;
5915
0
}
5916
5917
int
5918
ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5919
0
{
5920
0
    int status = NC_NOERR;
5921
0
    size_t rndup = nelems % X_ALIGN;
5922
0
    schar *xp = (schar *) *xpp;
5923
5924
0
    if (rndup)
5925
0
        rndup = X_ALIGN - rndup;
5926
5927
0
    while (nelems-- != 0) {
5928
        
5929
0
        if (*xp < 0) {
5930
0
#ifdef ERANGE_FILL
5931
0
            *tp = NC_FILL_UINT64;
5932
0
#endif
5933
0
            status = NC_ERANGE; /* because tp is unsigned */
5934
            
5935
0
#ifdef ERANGE_FILL
5936
0
            xp++; tp++; continue;
5937
0
#endif
5938
0
        }
5939
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5940
0
    }
5941
5942
0
    *xpp = (void *)(xp + rndup);
5943
0
    return status;
5944
0
}
5945
5946
5947
int
5948
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
5949
0
{
5950
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
5951
0
  *xpp = (void *)((char *)(*xpp) + nelems);
5952
5953
0
  return NC_NOERR;
5954
5955
0
}
5956
int
5957
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
5958
0
{
5959
0
    int status = NC_NOERR;
5960
0
    schar *xp = (schar *) *xpp;
5961
5962
0
    while (nelems-- != 0) {
5963
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
5964
            
5965
0
#ifdef ERANGE_FILL
5966
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
5967
0
#endif
5968
0
            status = NC_ERANGE;
5969
            
5970
0
#ifdef ERANGE_FILL
5971
0
            xp++; tp++; continue;
5972
0
#endif
5973
0
        }
5974
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
5975
0
    }
5976
5977
0
    *xpp = (void *)xp;
5978
0
    return status;
5979
0
}
5980
5981
int
5982
ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
5983
0
{
5984
0
    int status = NC_NOERR;
5985
0
    schar *xp = (schar *) *xpp;
5986
5987
0
    while (nelems-- != 0) {
5988
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
5989
            
5990
0
#ifdef ERANGE_FILL
5991
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
5992
0
#endif
5993
0
            status = NC_ERANGE;
5994
            
5995
0
#ifdef ERANGE_FILL
5996
0
            xp++; tp++; continue;
5997
0
#endif
5998
0
        }
5999
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6000
0
    }
6001
6002
0
    *xpp = (void *)xp;
6003
0
    return status;
6004
0
}
6005
6006
int
6007
ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6008
0
{
6009
0
    int status = NC_NOERR;
6010
0
    schar *xp = (schar *) *xpp;
6011
6012
0
    while (nelems-- != 0) {
6013
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6014
            
6015
0
#ifdef ERANGE_FILL
6016
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6017
0
#endif
6018
0
            status = NC_ERANGE;
6019
            
6020
0
#ifdef ERANGE_FILL
6021
0
            xp++; tp++; continue;
6022
0
#endif
6023
0
        }
6024
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6025
0
    }
6026
6027
0
    *xpp = (void *)xp;
6028
0
    return status;
6029
0
}
6030
6031
int
6032
ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6033
0
{
6034
0
    int status = NC_NOERR;
6035
0
    schar *xp = (schar *) *xpp;
6036
6037
0
    while (nelems-- != 0) {
6038
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6039
            
6040
0
#ifdef ERANGE_FILL
6041
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6042
0
#endif
6043
0
            status = NC_ERANGE;
6044
            
6045
0
#ifdef ERANGE_FILL
6046
0
            xp++; tp++; continue;
6047
0
#endif
6048
0
        }
6049
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6050
0
    }
6051
6052
0
    *xpp = (void *)xp;
6053
0
    return status;
6054
0
}
6055
6056
int
6057
ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6058
0
{
6059
0
    int status = NC_NOERR;
6060
0
    schar *xp = (schar *) *xpp;
6061
6062
0
    while (nelems-- != 0) {
6063
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6064
            
6065
0
#ifdef ERANGE_FILL
6066
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6067
0
#endif
6068
0
            status = NC_ERANGE;
6069
            
6070
0
#ifdef ERANGE_FILL
6071
0
            xp++; tp++; continue;
6072
0
#endif
6073
0
        }
6074
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6075
0
    }
6076
6077
0
    *xpp = (void *)xp;
6078
0
    return status;
6079
0
}
6080
6081
int
6082
ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6083
0
{
6084
0
    int status = NC_NOERR;
6085
0
    schar *xp = (schar *) *xpp;
6086
6087
0
    while (nelems-- != 0) {
6088
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6089
            
6090
0
#ifdef ERANGE_FILL
6091
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6092
0
#endif
6093
0
            status = NC_ERANGE;
6094
            
6095
0
#ifdef ERANGE_FILL
6096
0
            xp++; tp++; continue;
6097
0
#endif
6098
0
        }
6099
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6100
0
    }
6101
6102
0
    *xpp = (void *)xp;
6103
0
    return status;
6104
0
}
6105
6106
int
6107
ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6108
0
{
6109
0
    int status = NC_NOERR;
6110
0
    schar *xp = (schar *) *xpp;
6111
6112
0
    while (nelems-- != 0) {
6113
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6114
            
6115
0
#ifdef ERANGE_FILL
6116
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6117
0
#endif
6118
0
            status = NC_ERANGE;
6119
            
6120
0
#ifdef ERANGE_FILL
6121
0
            xp++; tp++; continue;
6122
0
#endif
6123
0
        }
6124
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6125
0
    }
6126
6127
0
    *xpp = (void *)xp;
6128
0
    return status;
6129
0
}
6130
6131
int
6132
ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6133
0
{
6134
0
    int status = NC_NOERR;
6135
0
    schar *xp = (schar *) *xpp;
6136
6137
0
    while (nelems-- != 0) {
6138
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6139
            
6140
0
#ifdef ERANGE_FILL
6141
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6142
0
#endif
6143
0
            status = NC_ERANGE;
6144
            
6145
0
#ifdef ERANGE_FILL
6146
0
            xp++; tp++; continue;
6147
0
#endif
6148
0
        }
6149
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6150
0
    }
6151
6152
0
    *xpp = (void *)xp;
6153
0
    return status;
6154
0
}
6155
6156
int
6157
ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6158
0
{
6159
0
    int status = NC_NOERR;
6160
0
    schar *xp = (schar *) *xpp;
6161
6162
0
    while (nelems-- != 0) {
6163
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6164
            
6165
0
#ifdef ERANGE_FILL
6166
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6167
0
#endif
6168
0
            status = NC_ERANGE;
6169
            
6170
0
#ifdef ERANGE_FILL
6171
0
            xp++; tp++; continue;
6172
0
#endif
6173
0
        }
6174
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6175
0
    }
6176
6177
0
    *xpp = (void *)xp;
6178
0
    return status;
6179
0
}
6180
6181
int
6182
ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6183
0
{
6184
0
    int status = NC_NOERR;
6185
0
    schar *xp = (schar *) *xpp;
6186
6187
0
    while (nelems-- != 0) {
6188
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6189
            
6190
0
#ifdef ERANGE_FILL
6191
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6192
0
#endif
6193
0
            status = NC_ERANGE;
6194
            
6195
0
#ifdef ERANGE_FILL
6196
0
            xp++; tp++; continue;
6197
0
#endif
6198
0
        }
6199
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6200
0
    }
6201
6202
0
    *xpp = (void *)xp;
6203
0
    return status;
6204
0
}
6205
6206
6207
int
6208
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6209
0
{
6210
0
    size_t rndup = nelems % X_ALIGN;
6211
6212
0
  if (rndup)
6213
0
    rndup = X_ALIGN - rndup;
6214
6215
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
6216
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6217
6218
0
  if (rndup)
6219
0
  {
6220
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
6221
0
    *xpp = (void *)((char *)(*xpp) + rndup);
6222
0
  }
6223
6224
0
  return NC_NOERR;
6225
6226
0
}
6227
int
6228
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6229
0
{
6230
0
    int status = NC_NOERR;
6231
0
    size_t rndup = nelems % X_ALIGN;
6232
0
    schar *xp = (schar *) *xpp;
6233
6234
0
    if (rndup) rndup = X_ALIGN - rndup;
6235
6236
0
    while (nelems-- != 0) {
6237
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
6238
            
6239
0
#ifdef ERANGE_FILL
6240
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6241
0
#endif
6242
0
            status = NC_ERANGE;
6243
            
6244
0
#ifdef ERANGE_FILL
6245
0
            xp++; tp++; continue;
6246
0
#endif
6247
0
        }
6248
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6249
0
    }
6250
6251
6252
0
    if (rndup) {
6253
0
        (void) memcpy(xp, nada, (size_t)rndup);
6254
0
        xp += rndup;
6255
0
    }
6256
6257
0
    *xpp = (void *)xp;
6258
0
    return status;
6259
0
}
6260
6261
int
6262
ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6263
0
{
6264
0
    int status = NC_NOERR;
6265
0
    size_t rndup = nelems % X_ALIGN;
6266
0
    schar *xp = (schar *) *xpp;
6267
6268
0
    if (rndup) rndup = X_ALIGN - rndup;
6269
6270
0
    while (nelems-- != 0) {
6271
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6272
            
6273
0
#ifdef ERANGE_FILL
6274
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6275
0
#endif
6276
0
            status = NC_ERANGE;
6277
            
6278
0
#ifdef ERANGE_FILL
6279
0
            xp++; tp++; continue;
6280
0
#endif
6281
0
        }
6282
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6283
0
    }
6284
6285
6286
0
    if (rndup) {
6287
0
        (void) memcpy(xp, nada, (size_t)rndup);
6288
0
        xp += rndup;
6289
0
    }
6290
6291
0
    *xpp = (void *)xp;
6292
0
    return status;
6293
0
}
6294
6295
int
6296
ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6297
0
{
6298
0
    int status = NC_NOERR;
6299
0
    size_t rndup = nelems % X_ALIGN;
6300
0
    schar *xp = (schar *) *xpp;
6301
6302
0
    if (rndup) rndup = X_ALIGN - rndup;
6303
6304
0
    while (nelems-- != 0) {
6305
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6306
            
6307
0
#ifdef ERANGE_FILL
6308
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6309
0
#endif
6310
0
            status = NC_ERANGE;
6311
            
6312
0
#ifdef ERANGE_FILL
6313
0
            xp++; tp++; continue;
6314
0
#endif
6315
0
        }
6316
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6317
0
    }
6318
6319
6320
0
    if (rndup) {
6321
0
        (void) memcpy(xp, nada, (size_t)rndup);
6322
0
        xp += rndup;
6323
0
    }
6324
6325
0
    *xpp = (void *)xp;
6326
0
    return status;
6327
0
}
6328
6329
int
6330
ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6331
0
{
6332
0
    int status = NC_NOERR;
6333
0
    size_t rndup = nelems % X_ALIGN;
6334
0
    schar *xp = (schar *) *xpp;
6335
6336
0
    if (rndup) rndup = X_ALIGN - rndup;
6337
6338
0
    while (nelems-- != 0) {
6339
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6340
            
6341
0
#ifdef ERANGE_FILL
6342
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6343
0
#endif
6344
0
            status = NC_ERANGE;
6345
            
6346
0
#ifdef ERANGE_FILL
6347
0
            xp++; tp++; continue;
6348
0
#endif
6349
0
        }
6350
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6351
0
    }
6352
6353
6354
0
    if (rndup) {
6355
0
        (void) memcpy(xp, nada, (size_t)rndup);
6356
0
        xp += rndup;
6357
0
    }
6358
6359
0
    *xpp = (void *)xp;
6360
0
    return status;
6361
0
}
6362
6363
int
6364
ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6365
0
{
6366
0
    int status = NC_NOERR;
6367
0
    size_t rndup = nelems % X_ALIGN;
6368
0
    schar *xp = (schar *) *xpp;
6369
6370
0
    if (rndup) rndup = X_ALIGN - rndup;
6371
6372
0
    while (nelems-- != 0) {
6373
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6374
            
6375
0
#ifdef ERANGE_FILL
6376
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6377
0
#endif
6378
0
            status = NC_ERANGE;
6379
            
6380
0
#ifdef ERANGE_FILL
6381
0
            xp++; tp++; continue;
6382
0
#endif
6383
0
        }
6384
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6385
0
    }
6386
6387
6388
0
    if (rndup) {
6389
0
        (void) memcpy(xp, nada, (size_t)rndup);
6390
0
        xp += rndup;
6391
0
    }
6392
6393
0
    *xpp = (void *)xp;
6394
0
    return status;
6395
0
}
6396
6397
int
6398
ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6399
0
{
6400
0
    int status = NC_NOERR;
6401
0
    size_t rndup = nelems % X_ALIGN;
6402
0
    schar *xp = (schar *) *xpp;
6403
6404
0
    if (rndup) rndup = X_ALIGN - rndup;
6405
6406
0
    while (nelems-- != 0) {
6407
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6408
            
6409
0
#ifdef ERANGE_FILL
6410
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6411
0
#endif
6412
0
            status = NC_ERANGE;
6413
            
6414
0
#ifdef ERANGE_FILL
6415
0
            xp++; tp++; continue;
6416
0
#endif
6417
0
        }
6418
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6419
0
    }
6420
6421
6422
0
    if (rndup) {
6423
0
        (void) memcpy(xp, nada, (size_t)rndup);
6424
0
        xp += rndup;
6425
0
    }
6426
6427
0
    *xpp = (void *)xp;
6428
0
    return status;
6429
0
}
6430
6431
int
6432
ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6433
0
{
6434
0
    int status = NC_NOERR;
6435
0
    size_t rndup = nelems % X_ALIGN;
6436
0
    schar *xp = (schar *) *xpp;
6437
6438
0
    if (rndup) rndup = X_ALIGN - rndup;
6439
6440
0
    while (nelems-- != 0) {
6441
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6442
            
6443
0
#ifdef ERANGE_FILL
6444
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6445
0
#endif
6446
0
            status = NC_ERANGE;
6447
            
6448
0
#ifdef ERANGE_FILL
6449
0
            xp++; tp++; continue;
6450
0
#endif
6451
0
        }
6452
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6453
0
    }
6454
6455
6456
0
    if (rndup) {
6457
0
        (void) memcpy(xp, nada, (size_t)rndup);
6458
0
        xp += rndup;
6459
0
    }
6460
6461
0
    *xpp = (void *)xp;
6462
0
    return status;
6463
0
}
6464
6465
int
6466
ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6467
0
{
6468
0
    int status = NC_NOERR;
6469
0
    size_t rndup = nelems % X_ALIGN;
6470
0
    schar *xp = (schar *) *xpp;
6471
6472
0
    if (rndup) rndup = X_ALIGN - rndup;
6473
6474
0
    while (nelems-- != 0) {
6475
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6476
            
6477
0
#ifdef ERANGE_FILL
6478
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6479
0
#endif
6480
0
            status = NC_ERANGE;
6481
            
6482
0
#ifdef ERANGE_FILL
6483
0
            xp++; tp++; continue;
6484
0
#endif
6485
0
        }
6486
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6487
0
    }
6488
6489
6490
0
    if (rndup) {
6491
0
        (void) memcpy(xp, nada, (size_t)rndup);
6492
0
        xp += rndup;
6493
0
    }
6494
6495
0
    *xpp = (void *)xp;
6496
0
    return status;
6497
0
}
6498
6499
int
6500
ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6501
0
{
6502
0
    int status = NC_NOERR;
6503
0
    size_t rndup = nelems % X_ALIGN;
6504
0
    schar *xp = (schar *) *xpp;
6505
6506
0
    if (rndup) rndup = X_ALIGN - rndup;
6507
6508
0
    while (nelems-- != 0) {
6509
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6510
            
6511
0
#ifdef ERANGE_FILL
6512
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6513
0
#endif
6514
0
            status = NC_ERANGE;
6515
            
6516
0
#ifdef ERANGE_FILL
6517
0
            xp++; tp++; continue;
6518
0
#endif
6519
0
        }
6520
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6521
0
    }
6522
6523
6524
0
    if (rndup) {
6525
0
        (void) memcpy(xp, nada, (size_t)rndup);
6526
0
        xp += rndup;
6527
0
    }
6528
6529
0
    *xpp = (void *)xp;
6530
0
    return status;
6531
0
}
6532
6533
int
6534
ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6535
0
{
6536
0
    int status = NC_NOERR;
6537
0
    size_t rndup = nelems % X_ALIGN;
6538
0
    schar *xp = (schar *) *xpp;
6539
6540
0
    if (rndup) rndup = X_ALIGN - rndup;
6541
6542
0
    while (nelems-- != 0) {
6543
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6544
            
6545
0
#ifdef ERANGE_FILL
6546
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6547
0
#endif
6548
0
            status = NC_ERANGE;
6549
            
6550
0
#ifdef ERANGE_FILL
6551
0
            xp++; tp++; continue;
6552
0
#endif
6553
0
        }
6554
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6555
0
    }
6556
6557
6558
0
    if (rndup) {
6559
0
        (void) memcpy(xp, nada, (size_t)rndup);
6560
0
        xp += rndup;
6561
0
    }
6562
6563
0
    *xpp = (void *)xp;
6564
0
    return status;
6565
0
}
6566
6567
6568
6569
/* uchar ---------------------------------------------------------------------*/
6570
int
6571
ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6572
0
{
6573
0
    int status = NC_NOERR;
6574
0
    uchar *xp = (uchar *)(*xpp);
6575
6576
0
    while (nelems-- != 0) {
6577
0
        if (*xp > SCHAR_MAX) {
6578
0
            *tp = NC_FILL_BYTE;
6579
0
            status = NC_ERANGE;
6580
            
6581
0
#ifdef ERANGE_FILL
6582
0
            xp++; tp++; continue;
6583
0
#endif
6584
0
        }
6585
0
  *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6586
0
    }
6587
6588
0
    *xpp = (const void *)xp;
6589
0
    return status;
6590
0
}
6591
int
6592
ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6593
0
{
6594
0
    (void) memcpy(tp, *xpp, (size_t)nelems);
6595
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6596
0
  return NC_NOERR;
6597
6598
0
}
6599
int
6600
ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6601
0
{
6602
0
    int status = NC_NOERR;
6603
0
    uchar *xp = (uchar *)(*xpp);
6604
6605
0
    while (nelems-- != 0) {
6606
        
6607
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6608
0
    }
6609
6610
0
    *xpp = (const void *)xp;
6611
0
    return status;
6612
0
}
6613
6614
int
6615
ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6616
0
{
6617
0
    int status = NC_NOERR;
6618
0
    uchar *xp = (uchar *)(*xpp);
6619
6620
0
    while (nelems-- != 0) {
6621
        
6622
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6623
0
    }
6624
6625
0
    *xpp = (const void *)xp;
6626
0
    return status;
6627
0
}
6628
6629
int
6630
ncx_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6631
0
{
6632
0
    int status = NC_NOERR;
6633
0
    uchar *xp = (uchar *)(*xpp);
6634
6635
0
    while (nelems-- != 0) {
6636
        
6637
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6638
0
    }
6639
6640
0
    *xpp = (const void *)xp;
6641
0
    return status;
6642
0
}
6643
6644
int
6645
ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6646
0
{
6647
0
    int status = NC_NOERR;
6648
0
    uchar *xp = (uchar *)(*xpp);
6649
6650
0
    while (nelems-- != 0) {
6651
        
6652
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6653
0
    }
6654
6655
0
    *xpp = (const void *)xp;
6656
0
    return status;
6657
0
}
6658
6659
int
6660
ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6661
0
{
6662
0
    int status = NC_NOERR;
6663
0
    uchar *xp = (uchar *)(*xpp);
6664
6665
0
    while (nelems-- != 0) {
6666
        
6667
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6668
0
    }
6669
6670
0
    *xpp = (const void *)xp;
6671
0
    return status;
6672
0
}
6673
6674
int
6675
ncx_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6676
0
{
6677
0
    int status = NC_NOERR;
6678
0
    uchar *xp = (uchar *)(*xpp);
6679
6680
0
    while (nelems-- != 0) {
6681
        
6682
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6683
0
    }
6684
6685
0
    *xpp = (const void *)xp;
6686
0
    return status;
6687
0
}
6688
6689
int
6690
ncx_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6691
0
{
6692
0
    int status = NC_NOERR;
6693
0
    uchar *xp = (uchar *)(*xpp);
6694
6695
0
    while (nelems-- != 0) {
6696
        
6697
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6698
0
    }
6699
6700
0
    *xpp = (const void *)xp;
6701
0
    return status;
6702
0
}
6703
6704
int
6705
ncx_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6706
0
{
6707
0
    int status = NC_NOERR;
6708
0
    uchar *xp = (uchar *)(*xpp);
6709
6710
0
    while (nelems-- != 0) {
6711
        
6712
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6713
0
    }
6714
6715
0
    *xpp = (const void *)xp;
6716
0
    return status;
6717
0
}
6718
6719
int
6720
ncx_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6721
0
{
6722
0
    int status = NC_NOERR;
6723
0
    uchar *xp = (uchar *)(*xpp);
6724
6725
0
    while (nelems-- != 0) {
6726
        
6727
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6728
0
    }
6729
6730
0
    *xpp = (const void *)xp;
6731
0
    return status;
6732
0
}
6733
6734
6735
int
6736
ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6737
0
{
6738
0
    int status = NC_NOERR;
6739
0
    size_t rndup = nelems % X_ALIGN;
6740
0
    uchar *xp = (uchar *) *xpp;
6741
6742
0
    if (rndup) rndup = X_ALIGN - rndup;
6743
6744
0
    while (nelems-- != 0) {
6745
0
        if (*xp > SCHAR_MAX) {
6746
0
            *tp = NC_FILL_BYTE;
6747
0
            status = NC_ERANGE;
6748
            
6749
0
#ifdef ERANGE_FILL
6750
0
            xp++; tp++; continue;
6751
0
#endif
6752
0
        }
6753
0
        *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6754
0
    }
6755
6756
0
    *xpp = (void *)(xp + rndup);
6757
0
    return status;
6758
0
}
6759
int
6760
ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6761
0
{
6762
0
    size_t rndup = nelems % X_ALIGN;
6763
6764
0
  if (rndup)
6765
0
    rndup = X_ALIGN - rndup;
6766
6767
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
6768
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
6769
6770
0
  return NC_NOERR;
6771
6772
0
}
6773
int
6774
ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6775
0
{
6776
0
    int status = NC_NOERR;
6777
0
    size_t rndup = nelems % X_ALIGN;
6778
0
    uchar *xp = (uchar *) *xpp;
6779
6780
0
    if (rndup)
6781
0
        rndup = X_ALIGN - rndup;
6782
6783
0
    while (nelems-- != 0) {
6784
        
6785
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6786
0
    }
6787
6788
0
    *xpp = (void *)(xp + rndup);
6789
0
    return status;
6790
0
}
6791
6792
int
6793
ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6794
0
{
6795
0
    int status = NC_NOERR;
6796
0
    size_t rndup = nelems % X_ALIGN;
6797
0
    uchar *xp = (uchar *) *xpp;
6798
6799
0
    if (rndup)
6800
0
        rndup = X_ALIGN - rndup;
6801
6802
0
    while (nelems-- != 0) {
6803
        
6804
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6805
0
    }
6806
6807
0
    *xpp = (void *)(xp + rndup);
6808
0
    return status;
6809
0
}
6810
6811
int
6812
ncx_pad_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6813
0
{
6814
0
    int status = NC_NOERR;
6815
0
    size_t rndup = nelems % X_ALIGN;
6816
0
    uchar *xp = (uchar *) *xpp;
6817
6818
0
    if (rndup)
6819
0
        rndup = X_ALIGN - rndup;
6820
6821
0
    while (nelems-- != 0) {
6822
        
6823
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6824
0
    }
6825
6826
0
    *xpp = (void *)(xp + rndup);
6827
0
    return status;
6828
0
}
6829
6830
int
6831
ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6832
0
{
6833
0
    int status = NC_NOERR;
6834
0
    size_t rndup = nelems % X_ALIGN;
6835
0
    uchar *xp = (uchar *) *xpp;
6836
6837
0
    if (rndup)
6838
0
        rndup = X_ALIGN - rndup;
6839
6840
0
    while (nelems-- != 0) {
6841
        
6842
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6843
0
    }
6844
6845
0
    *xpp = (void *)(xp + rndup);
6846
0
    return status;
6847
0
}
6848
6849
int
6850
ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6851
0
{
6852
0
    int status = NC_NOERR;
6853
0
    size_t rndup = nelems % X_ALIGN;
6854
0
    uchar *xp = (uchar *) *xpp;
6855
6856
0
    if (rndup)
6857
0
        rndup = X_ALIGN - rndup;
6858
6859
0
    while (nelems-- != 0) {
6860
        
6861
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6862
0
    }
6863
6864
0
    *xpp = (void *)(xp + rndup);
6865
0
    return status;
6866
0
}
6867
6868
int
6869
ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6870
0
{
6871
0
    int status = NC_NOERR;
6872
0
    size_t rndup = nelems % X_ALIGN;
6873
0
    uchar *xp = (uchar *) *xpp;
6874
6875
0
    if (rndup)
6876
0
        rndup = X_ALIGN - rndup;
6877
6878
0
    while (nelems-- != 0) {
6879
        
6880
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6881
0
    }
6882
6883
0
    *xpp = (void *)(xp + rndup);
6884
0
    return status;
6885
0
}
6886
6887
int
6888
ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6889
0
{
6890
0
    int status = NC_NOERR;
6891
0
    size_t rndup = nelems % X_ALIGN;
6892
0
    uchar *xp = (uchar *) *xpp;
6893
6894
0
    if (rndup)
6895
0
        rndup = X_ALIGN - rndup;
6896
6897
0
    while (nelems-- != 0) {
6898
        
6899
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6900
0
    }
6901
6902
0
    *xpp = (void *)(xp + rndup);
6903
0
    return status;
6904
0
}
6905
6906
int
6907
ncx_pad_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6908
0
{
6909
0
    int status = NC_NOERR;
6910
0
    size_t rndup = nelems % X_ALIGN;
6911
0
    uchar *xp = (uchar *) *xpp;
6912
6913
0
    if (rndup)
6914
0
        rndup = X_ALIGN - rndup;
6915
6916
0
    while (nelems-- != 0) {
6917
        
6918
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6919
0
    }
6920
6921
0
    *xpp = (void *)(xp + rndup);
6922
0
    return status;
6923
0
}
6924
6925
int
6926
ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6927
0
{
6928
0
    int status = NC_NOERR;
6929
0
    size_t rndup = nelems % X_ALIGN;
6930
0
    uchar *xp = (uchar *) *xpp;
6931
6932
0
    if (rndup)
6933
0
        rndup = X_ALIGN - rndup;
6934
6935
0
    while (nelems-- != 0) {
6936
        
6937
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6938
0
    }
6939
6940
0
    *xpp = (void *)(xp + rndup);
6941
0
    return status;
6942
0
}
6943
6944
6945
int
6946
ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6947
0
{
6948
0
    int status = NC_NOERR;
6949
0
    uchar *xp = (uchar *) *xpp;
6950
6951
0
    while (nelems-- != 0) {
6952
0
        if (*tp < 0) {
6953
            
6954
0
#ifdef ERANGE_FILL
6955
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6956
0
#endif
6957
0
            status = NC_ERANGE;
6958
            
6959
0
#ifdef ERANGE_FILL
6960
0
            xp++; tp++; continue;
6961
0
#endif
6962
0
        }
6963
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
6964
0
    }
6965
6966
0
    *xpp = (void *)xp;
6967
0
    return status;
6968
0
}
6969
int
6970
ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6971
0
{
6972
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
6973
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6974
6975
0
  return NC_NOERR;
6976
6977
0
}
6978
int
6979
ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6980
0
{
6981
0
    int status = NC_NOERR;
6982
0
    uchar *xp = (uchar *) *xpp;
6983
6984
0
    while (nelems-- != 0) {
6985
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
6986
            
6987
0
#ifdef ERANGE_FILL
6988
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
6989
0
#endif
6990
0
            status = NC_ERANGE;
6991
            
6992
0
#ifdef ERANGE_FILL
6993
0
            xp++; tp++; continue;
6994
0
#endif
6995
0
        }
6996
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
6997
0
    }
6998
6999
0
    *xpp = (void *)xp;
7000
0
    return status;
7001
0
}
7002
7003
int
7004
ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7005
0
{
7006
0
    int status = NC_NOERR;
7007
0
    uchar *xp = (uchar *) *xpp;
7008
7009
0
    while (nelems-- != 0) {
7010
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7011
            
7012
0
#ifdef ERANGE_FILL
7013
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7014
0
#endif
7015
0
            status = NC_ERANGE;
7016
            
7017
0
#ifdef ERANGE_FILL
7018
0
            xp++; tp++; continue;
7019
0
#endif
7020
0
        }
7021
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7022
0
    }
7023
7024
0
    *xpp = (void *)xp;
7025
0
    return status;
7026
0
}
7027
7028
int
7029
ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7030
0
{
7031
0
    int status = NC_NOERR;
7032
0
    uchar *xp = (uchar *) *xpp;
7033
7034
0
    while (nelems-- != 0) {
7035
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7036
            
7037
0
#ifdef ERANGE_FILL
7038
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7039
0
#endif
7040
0
            status = NC_ERANGE;
7041
            
7042
0
#ifdef ERANGE_FILL
7043
0
            xp++; tp++; continue;
7044
0
#endif
7045
0
        }
7046
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7047
0
    }
7048
7049
0
    *xpp = (void *)xp;
7050
0
    return status;
7051
0
}
7052
7053
int
7054
ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7055
0
{
7056
0
    int status = NC_NOERR;
7057
0
    uchar *xp = (uchar *) *xpp;
7058
7059
0
    while (nelems-- != 0) {
7060
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7061
            
7062
0
#ifdef ERANGE_FILL
7063
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7064
0
#endif
7065
0
            status = NC_ERANGE;
7066
            
7067
0
#ifdef ERANGE_FILL
7068
0
            xp++; tp++; continue;
7069
0
#endif
7070
0
        }
7071
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7072
0
    }
7073
7074
0
    *xpp = (void *)xp;
7075
0
    return status;
7076
0
}
7077
7078
int
7079
ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7080
0
{
7081
0
    int status = NC_NOERR;
7082
0
    uchar *xp = (uchar *) *xpp;
7083
7084
0
    while (nelems-- != 0) {
7085
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7086
            
7087
0
#ifdef ERANGE_FILL
7088
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7089
0
#endif
7090
0
            status = NC_ERANGE;
7091
            
7092
0
#ifdef ERANGE_FILL
7093
0
            xp++; tp++; continue;
7094
0
#endif
7095
0
        }
7096
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7097
0
    }
7098
7099
0
    *xpp = (void *)xp;
7100
0
    return status;
7101
0
}
7102
7103
int
7104
ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7105
0
{
7106
0
    int status = NC_NOERR;
7107
0
    uchar *xp = (uchar *) *xpp;
7108
7109
0
    while (nelems-- != 0) {
7110
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7111
            
7112
0
#ifdef ERANGE_FILL
7113
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7114
0
#endif
7115
0
            status = NC_ERANGE;
7116
            
7117
0
#ifdef ERANGE_FILL
7118
0
            xp++; tp++; continue;
7119
0
#endif
7120
0
        }
7121
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7122
0
    }
7123
7124
0
    *xpp = (void *)xp;
7125
0
    return status;
7126
0
}
7127
7128
int
7129
ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7130
0
{
7131
0
    int status = NC_NOERR;
7132
0
    uchar *xp = (uchar *) *xpp;
7133
7134
0
    while (nelems-- != 0) {
7135
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7136
            
7137
0
#ifdef ERANGE_FILL
7138
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7139
0
#endif
7140
0
            status = NC_ERANGE;
7141
            
7142
0
#ifdef ERANGE_FILL
7143
0
            xp++; tp++; continue;
7144
0
#endif
7145
0
        }
7146
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7147
0
    }
7148
7149
0
    *xpp = (void *)xp;
7150
0
    return status;
7151
0
}
7152
7153
int
7154
ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7155
0
{
7156
0
    int status = NC_NOERR;
7157
0
    uchar *xp = (uchar *) *xpp;
7158
7159
0
    while (nelems-- != 0) {
7160
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7161
            
7162
0
#ifdef ERANGE_FILL
7163
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7164
0
#endif
7165
0
            status = NC_ERANGE;
7166
            
7167
0
#ifdef ERANGE_FILL
7168
0
            xp++; tp++; continue;
7169
0
#endif
7170
0
        }
7171
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7172
0
    }
7173
7174
0
    *xpp = (void *)xp;
7175
0
    return status;
7176
0
}
7177
7178
int
7179
ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7180
0
{
7181
0
    int status = NC_NOERR;
7182
0
    uchar *xp = (uchar *) *xpp;
7183
7184
0
    while (nelems-- != 0) {
7185
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7186
            
7187
0
#ifdef ERANGE_FILL
7188
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7189
0
#endif
7190
0
            status = NC_ERANGE;
7191
            
7192
0
#ifdef ERANGE_FILL
7193
0
            xp++; tp++; continue;
7194
0
#endif
7195
0
        }
7196
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7197
0
    }
7198
7199
0
    *xpp = (void *)xp;
7200
0
    return status;
7201
0
}
7202
7203
7204
int
7205
ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7206
0
{
7207
0
    int status = NC_NOERR;
7208
0
    size_t rndup = nelems % X_ALIGN;
7209
0
    uchar *xp = (uchar *) *xpp;
7210
7211
0
    if (rndup) rndup = X_ALIGN - rndup;
7212
7213
0
    while (nelems-- != 0) {
7214
0
        if (*tp < 0) {
7215
            
7216
0
#ifdef ERANGE_FILL
7217
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7218
0
#endif
7219
0
            status = NC_ERANGE;
7220
            
7221
0
#ifdef ERANGE_FILL
7222
0
            xp++; tp++; continue;
7223
0
#endif
7224
0
        }
7225
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7226
0
    }
7227
7228
0
    if (rndup) {
7229
0
        (void) memcpy(xp, nada, (size_t)rndup);
7230
0
        xp += rndup;
7231
0
    }
7232
7233
0
    *xpp = (void *)xp;
7234
0
    return status;
7235
0
}
7236
int
7237
ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7238
0
{
7239
0
    size_t rndup = nelems % X_ALIGN;
7240
7241
0
  if (rndup)
7242
0
    rndup = X_ALIGN - rndup;
7243
7244
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
7245
0
  *xpp = (void *)((char *)(*xpp) + nelems);
7246
7247
0
  if (rndup)
7248
0
  {
7249
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
7250
0
    *xpp = (void *)((char *)(*xpp) + rndup);
7251
0
  }
7252
7253
0
  return NC_NOERR;
7254
7255
0
}
7256
int
7257
ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7258
0
{
7259
0
    int status = NC_NOERR;
7260
0
    size_t rndup = nelems % X_ALIGN;
7261
0
    uchar *xp = (uchar *) *xpp;
7262
7263
0
    if (rndup) rndup = X_ALIGN - rndup;
7264
7265
0
    while (nelems-- != 0) {
7266
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7267
            
7268
0
#ifdef ERANGE_FILL
7269
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7270
0
#endif
7271
0
            status = NC_ERANGE;
7272
            
7273
0
#ifdef ERANGE_FILL
7274
0
            xp++; tp++; continue;
7275
0
#endif
7276
0
        }
7277
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7278
0
    }
7279
7280
7281
0
    if (rndup) {
7282
0
        (void) memcpy(xp, nada, (size_t)rndup);
7283
0
        xp += rndup;
7284
0
    }
7285
7286
0
    *xpp = (void *)xp;
7287
0
    return status;
7288
0
}
7289
7290
int
7291
ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7292
0
{
7293
0
    int status = NC_NOERR;
7294
0
    size_t rndup = nelems % X_ALIGN;
7295
0
    uchar *xp = (uchar *) *xpp;
7296
7297
0
    if (rndup) rndup = X_ALIGN - rndup;
7298
7299
0
    while (nelems-- != 0) {
7300
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7301
            
7302
0
#ifdef ERANGE_FILL
7303
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7304
0
#endif
7305
0
            status = NC_ERANGE;
7306
            
7307
0
#ifdef ERANGE_FILL
7308
0
            xp++; tp++; continue;
7309
0
#endif
7310
0
        }
7311
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7312
0
    }
7313
7314
7315
0
    if (rndup) {
7316
0
        (void) memcpy(xp, nada, (size_t)rndup);
7317
0
        xp += rndup;
7318
0
    }
7319
7320
0
    *xpp = (void *)xp;
7321
0
    return status;
7322
0
}
7323
7324
int
7325
ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7326
0
{
7327
0
    int status = NC_NOERR;
7328
0
    size_t rndup = nelems % X_ALIGN;
7329
0
    uchar *xp = (uchar *) *xpp;
7330
7331
0
    if (rndup) rndup = X_ALIGN - rndup;
7332
7333
0
    while (nelems-- != 0) {
7334
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7335
            
7336
0
#ifdef ERANGE_FILL
7337
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7338
0
#endif
7339
0
            status = NC_ERANGE;
7340
            
7341
0
#ifdef ERANGE_FILL
7342
0
            xp++; tp++; continue;
7343
0
#endif
7344
0
        }
7345
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7346
0
    }
7347
7348
7349
0
    if (rndup) {
7350
0
        (void) memcpy(xp, nada, (size_t)rndup);
7351
0
        xp += rndup;
7352
0
    }
7353
7354
0
    *xpp = (void *)xp;
7355
0
    return status;
7356
0
}
7357
7358
int
7359
ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7360
0
{
7361
0
    int status = NC_NOERR;
7362
0
    size_t rndup = nelems % X_ALIGN;
7363
0
    uchar *xp = (uchar *) *xpp;
7364
7365
0
    if (rndup) rndup = X_ALIGN - rndup;
7366
7367
0
    while (nelems-- != 0) {
7368
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7369
            
7370
0
#ifdef ERANGE_FILL
7371
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7372
0
#endif
7373
0
            status = NC_ERANGE;
7374
            
7375
0
#ifdef ERANGE_FILL
7376
0
            xp++; tp++; continue;
7377
0
#endif
7378
0
        }
7379
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7380
0
    }
7381
7382
7383
0
    if (rndup) {
7384
0
        (void) memcpy(xp, nada, (size_t)rndup);
7385
0
        xp += rndup;
7386
0
    }
7387
7388
0
    *xpp = (void *)xp;
7389
0
    return status;
7390
0
}
7391
7392
int
7393
ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7394
0
{
7395
0
    int status = NC_NOERR;
7396
0
    size_t rndup = nelems % X_ALIGN;
7397
0
    uchar *xp = (uchar *) *xpp;
7398
7399
0
    if (rndup) rndup = X_ALIGN - rndup;
7400
7401
0
    while (nelems-- != 0) {
7402
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7403
            
7404
0
#ifdef ERANGE_FILL
7405
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7406
0
#endif
7407
0
            status = NC_ERANGE;
7408
            
7409
0
#ifdef ERANGE_FILL
7410
0
            xp++; tp++; continue;
7411
0
#endif
7412
0
        }
7413
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7414
0
    }
7415
7416
7417
0
    if (rndup) {
7418
0
        (void) memcpy(xp, nada, (size_t)rndup);
7419
0
        xp += rndup;
7420
0
    }
7421
7422
0
    *xpp = (void *)xp;
7423
0
    return status;
7424
0
}
7425
7426
int
7427
ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7428
0
{
7429
0
    int status = NC_NOERR;
7430
0
    size_t rndup = nelems % X_ALIGN;
7431
0
    uchar *xp = (uchar *) *xpp;
7432
7433
0
    if (rndup) rndup = X_ALIGN - rndup;
7434
7435
0
    while (nelems-- != 0) {
7436
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7437
            
7438
0
#ifdef ERANGE_FILL
7439
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7440
0
#endif
7441
0
            status = NC_ERANGE;
7442
            
7443
0
#ifdef ERANGE_FILL
7444
0
            xp++; tp++; continue;
7445
0
#endif
7446
0
        }
7447
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7448
0
    }
7449
7450
7451
0
    if (rndup) {
7452
0
        (void) memcpy(xp, nada, (size_t)rndup);
7453
0
        xp += rndup;
7454
0
    }
7455
7456
0
    *xpp = (void *)xp;
7457
0
    return status;
7458
0
}
7459
7460
int
7461
ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7462
0
{
7463
0
    int status = NC_NOERR;
7464
0
    size_t rndup = nelems % X_ALIGN;
7465
0
    uchar *xp = (uchar *) *xpp;
7466
7467
0
    if (rndup) rndup = X_ALIGN - rndup;
7468
7469
0
    while (nelems-- != 0) {
7470
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7471
            
7472
0
#ifdef ERANGE_FILL
7473
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7474
0
#endif
7475
0
            status = NC_ERANGE;
7476
            
7477
0
#ifdef ERANGE_FILL
7478
0
            xp++; tp++; continue;
7479
0
#endif
7480
0
        }
7481
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7482
0
    }
7483
7484
7485
0
    if (rndup) {
7486
0
        (void) memcpy(xp, nada, (size_t)rndup);
7487
0
        xp += rndup;
7488
0
    }
7489
7490
0
    *xpp = (void *)xp;
7491
0
    return status;
7492
0
}
7493
7494
int
7495
ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7496
0
{
7497
0
    int status = NC_NOERR;
7498
0
    size_t rndup = nelems % X_ALIGN;
7499
0
    uchar *xp = (uchar *) *xpp;
7500
7501
0
    if (rndup) rndup = X_ALIGN - rndup;
7502
7503
0
    while (nelems-- != 0) {
7504
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7505
            
7506
0
#ifdef ERANGE_FILL
7507
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7508
0
#endif
7509
0
            status = NC_ERANGE;
7510
            
7511
0
#ifdef ERANGE_FILL
7512
0
            xp++; tp++; continue;
7513
0
#endif
7514
0
        }
7515
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7516
0
    }
7517
7518
7519
0
    if (rndup) {
7520
0
        (void) memcpy(xp, nada, (size_t)rndup);
7521
0
        xp += rndup;
7522
0
    }
7523
7524
0
    *xpp = (void *)xp;
7525
0
    return status;
7526
0
}
7527
7528
int
7529
ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7530
0
{
7531
0
    int status = NC_NOERR;
7532
0
    size_t rndup = nelems % X_ALIGN;
7533
0
    uchar *xp = (uchar *) *xpp;
7534
7535
0
    if (rndup) rndup = X_ALIGN - rndup;
7536
7537
0
    while (nelems-- != 0) {
7538
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7539
            
7540
0
#ifdef ERANGE_FILL
7541
0
            if (fillp != NULL) memcpy(xp, fillp, 1);
7542
0
#endif
7543
0
            status = NC_ERANGE;
7544
            
7545
0
#ifdef ERANGE_FILL
7546
0
            xp++; tp++; continue;
7547
0
#endif
7548
0
        }
7549
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7550
0
    }
7551
7552
7553
0
    if (rndup) {
7554
0
        (void) memcpy(xp, nada, (size_t)rndup);
7555
0
        xp += rndup;
7556
0
    }
7557
7558
0
    *xpp = (void *)xp;
7559
0
    return status;
7560
0
}
7561
7562
7563
/* short ---------------------------------------------------------------------*/
7564
7565
#if X_SIZEOF_SHORT == SIZEOF_SHORT
7566
/* optimized version */
7567
int
7568
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7569
0
{
7570
#ifdef WORDS_BIGENDIAN
7571
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
7572
# else
7573
0
  swapn2b(tp, *xpp, nelems);
7574
0
# endif
7575
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
7576
0
  return NC_NOERR;
7577
0
}
7578
#else
7579
int
7580
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7581
{
7582
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7583
7584
 /* basic algorithm is:
7585
  *   - ensure sane alignment of input data
7586
  *   - copy (conversion happens automatically) input data
7587
  *     to output
7588
  *   - update xpp to point at next unconverted input, and tp to point
7589
  *     at next location for converted output
7590
  */
7591
  long i, j, ni;
7592
  short tmp[LOOPCNT];        /* in case input is misaligned */
7593
  short *xp;
7594
  int nrange = 0;         /* number of range errors */
7595
  int realign = 0;        /* "do we need to fix input data alignment?" */
7596
  long cxp = (long) *((char**)xpp);
7597
7598
  realign = (cxp & 7) % SIZEOF_SHORT;
7599
  /* sjl: manually stripmine so we can limit amount of
7600
   * vector work space reserved to LOOPCNT elements. Also
7601
   * makes vectorisation easy */
7602
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7603
    ni=Min(nelems-j,LOOPCNT);
7604
    if (realign) {
7605
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7606
      xp = tmp;
7607
    } else {
7608
      xp = (short *) *xpp;
7609
    }
7610
   /* copy the next block */
7611
#pragma cdir loopcnt=LOOPCNT
7612
#pragma cdir shortloop
7613
    for (i=0; i<ni; i++) {
7614
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
7615
     /* test for range errors (not always needed but do it anyway) */
7616
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7617
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7618
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
7619
    }
7620
   /* update xpp and tp */
7621
    if (realign) xp = (short *) *xpp;
7622
    xp += ni;
7623
    tp += ni;
7624
    *xpp = (void*)xp;
7625
  }
7626
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7627
7628
#else   /* not SX */
7629
  const char *xp = (const char *) *xpp;
7630
  int status = NC_NOERR;
7631
7632
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7633
  {
7634
    const int lstatus = ncx_get_short_short(xp, tp);
7635
    if (status == NC_NOERR) /* report the first encountered error */
7636
      status = lstatus;
7637
  }
7638
7639
  *xpp = (const void *)xp;
7640
  return status;
7641
#endif
7642
}
7643
7644
#endif
7645
int
7646
ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
7647
0
{
7648
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7649
7650
 /* basic algorithm is:
7651
  *   - ensure sane alignment of input data
7652
  *   - copy (conversion happens automatically) input data
7653
  *     to output
7654
  *   - update xpp to point at next unconverted input, and tp to point
7655
  *     at next location for converted output
7656
  */
7657
  long i, j, ni;
7658
  short tmp[LOOPCNT];        /* in case input is misaligned */
7659
  short *xp;
7660
  int nrange = 0;         /* number of range errors */
7661
  int realign = 0;        /* "do we need to fix input data alignment?" */
7662
  long cxp = (long) *((char**)xpp);
7663
7664
  realign = (cxp & 7) % SIZEOF_SHORT;
7665
  /* sjl: manually stripmine so we can limit amount of
7666
   * vector work space reserved to LOOPCNT elements. Also
7667
   * makes vectorisation easy */
7668
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7669
    ni=Min(nelems-j,LOOPCNT);
7670
    if (realign) {
7671
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7672
      xp = tmp;
7673
    } else {
7674
      xp = (short *) *xpp;
7675
    }
7676
   /* copy the next block */
7677
#pragma cdir loopcnt=LOOPCNT
7678
#pragma cdir shortloop
7679
    for (i=0; i<ni; i++) {
7680
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
7681
     /* test for range errors (not always needed but do it anyway) */
7682
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7683
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7684
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
7685
    }
7686
   /* update xpp and tp */
7687
    if (realign) xp = (short *) *xpp;
7688
    xp += ni;
7689
    tp += ni;
7690
    *xpp = (void*)xp;
7691
  }
7692
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7693
7694
#else   /* not SX */
7695
0
  const char *xp = (const char *) *xpp;
7696
0
  int status = NC_NOERR;
7697
7698
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7699
0
  {
7700
0
    const int lstatus = ncx_get_short_schar(xp, tp);
7701
0
    if (status == NC_NOERR) /* report the first encountered error */
7702
0
      status = lstatus;
7703
0
  }
7704
7705
0
  *xpp = (const void *)xp;
7706
0
  return status;
7707
0
#endif
7708
0
}
7709
7710
int
7711
ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
7712
0
{
7713
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7714
7715
 /* basic algorithm is:
7716
  *   - ensure sane alignment of input data
7717
  *   - copy (conversion happens automatically) input data
7718
  *     to output
7719
  *   - update xpp to point at next unconverted input, and tp to point
7720
  *     at next location for converted output
7721
  */
7722
  long i, j, ni;
7723
  short tmp[LOOPCNT];        /* in case input is misaligned */
7724
  short *xp;
7725
  int nrange = 0;         /* number of range errors */
7726
  int realign = 0;        /* "do we need to fix input data alignment?" */
7727
  long cxp = (long) *((char**)xpp);
7728
7729
  realign = (cxp & 7) % SIZEOF_SHORT;
7730
  /* sjl: manually stripmine so we can limit amount of
7731
   * vector work space reserved to LOOPCNT elements. Also
7732
   * makes vectorisation easy */
7733
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7734
    ni=Min(nelems-j,LOOPCNT);
7735
    if (realign) {
7736
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7737
      xp = tmp;
7738
    } else {
7739
      xp = (short *) *xpp;
7740
    }
7741
   /* copy the next block */
7742
#pragma cdir loopcnt=LOOPCNT
7743
#pragma cdir shortloop
7744
    for (i=0; i<ni; i++) {
7745
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
7746
     /* test for range errors (not always needed but do it anyway) */
7747
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7748
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7749
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
7750
    }
7751
   /* update xpp and tp */
7752
    if (realign) xp = (short *) *xpp;
7753
    xp += ni;
7754
    tp += ni;
7755
    *xpp = (void*)xp;
7756
  }
7757
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7758
7759
#else   /* not SX */
7760
0
  const char *xp = (const char *) *xpp;
7761
0
  int status = NC_NOERR;
7762
7763
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7764
0
  {
7765
0
    const int lstatus = ncx_get_short_int(xp, tp);
7766
0
    if (status == NC_NOERR) /* report the first encountered error */
7767
0
      status = lstatus;
7768
0
  }
7769
7770
0
  *xpp = (const void *)xp;
7771
0
  return status;
7772
0
#endif
7773
0
}
7774
7775
int
7776
ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
7777
0
{
7778
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7779
7780
 /* basic algorithm is:
7781
  *   - ensure sane alignment of input data
7782
  *   - copy (conversion happens automatically) input data
7783
  *     to output
7784
  *   - update xpp to point at next unconverted input, and tp to point
7785
  *     at next location for converted output
7786
  */
7787
  long i, j, ni;
7788
  short tmp[LOOPCNT];        /* in case input is misaligned */
7789
  short *xp;
7790
  int nrange = 0;         /* number of range errors */
7791
  int realign = 0;        /* "do we need to fix input data alignment?" */
7792
  long cxp = (long) *((char**)xpp);
7793
7794
  realign = (cxp & 7) % SIZEOF_SHORT;
7795
  /* sjl: manually stripmine so we can limit amount of
7796
   * vector work space reserved to LOOPCNT elements. Also
7797
   * makes vectorisation easy */
7798
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7799
    ni=Min(nelems-j,LOOPCNT);
7800
    if (realign) {
7801
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7802
      xp = tmp;
7803
    } else {
7804
      xp = (short *) *xpp;
7805
    }
7806
   /* copy the next block */
7807
#pragma cdir loopcnt=LOOPCNT
7808
#pragma cdir shortloop
7809
    for (i=0; i<ni; i++) {
7810
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
7811
     /* test for range errors (not always needed but do it anyway) */
7812
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7813
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7814
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
7815
    }
7816
   /* update xpp and tp */
7817
    if (realign) xp = (short *) *xpp;
7818
    xp += ni;
7819
    tp += ni;
7820
    *xpp = (void*)xp;
7821
  }
7822
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7823
7824
#else   /* not SX */
7825
0
  const char *xp = (const char *) *xpp;
7826
0
  int status = NC_NOERR;
7827
7828
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7829
0
  {
7830
0
    const int lstatus = ncx_get_short_long(xp, tp);
7831
0
    if (status == NC_NOERR) /* report the first encountered error */
7832
0
      status = lstatus;
7833
0
  }
7834
7835
0
  *xpp = (const void *)xp;
7836
0
  return status;
7837
0
#endif
7838
0
}
7839
7840
int
7841
ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
7842
0
{
7843
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7844
7845
 /* basic algorithm is:
7846
  *   - ensure sane alignment of input data
7847
  *   - copy (conversion happens automatically) input data
7848
  *     to output
7849
  *   - update xpp to point at next unconverted input, and tp to point
7850
  *     at next location for converted output
7851
  */
7852
  long i, j, ni;
7853
  short tmp[LOOPCNT];        /* in case input is misaligned */
7854
  short *xp;
7855
  int nrange = 0;         /* number of range errors */
7856
  int realign = 0;        /* "do we need to fix input data alignment?" */
7857
  long cxp = (long) *((char**)xpp);
7858
7859
  realign = (cxp & 7) % SIZEOF_SHORT;
7860
  /* sjl: manually stripmine so we can limit amount of
7861
   * vector work space reserved to LOOPCNT elements. Also
7862
   * makes vectorisation easy */
7863
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7864
    ni=Min(nelems-j,LOOPCNT);
7865
    if (realign) {
7866
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7867
      xp = tmp;
7868
    } else {
7869
      xp = (short *) *xpp;
7870
    }
7871
   /* copy the next block */
7872
#pragma cdir loopcnt=LOOPCNT
7873
#pragma cdir shortloop
7874
    for (i=0; i<ni; i++) {
7875
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
7876
     /* test for range errors (not always needed but do it anyway) */
7877
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7878
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7879
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
7880
    }
7881
   /* update xpp and tp */
7882
    if (realign) xp = (short *) *xpp;
7883
    xp += ni;
7884
    tp += ni;
7885
    *xpp = (void*)xp;
7886
  }
7887
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7888
7889
#else   /* not SX */
7890
0
  const char *xp = (const char *) *xpp;
7891
0
  int status = NC_NOERR;
7892
7893
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7894
0
  {
7895
0
    const int lstatus = ncx_get_short_float(xp, tp);
7896
0
    if (status == NC_NOERR) /* report the first encountered error */
7897
0
      status = lstatus;
7898
0
  }
7899
7900
0
  *xpp = (const void *)xp;
7901
0
  return status;
7902
0
#endif
7903
0
}
7904
7905
int
7906
ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
7907
0
{
7908
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7909
7910
 /* basic algorithm is:
7911
  *   - ensure sane alignment of input data
7912
  *   - copy (conversion happens automatically) input data
7913
  *     to output
7914
  *   - update xpp to point at next unconverted input, and tp to point
7915
  *     at next location for converted output
7916
  */
7917
  long i, j, ni;
7918
  short tmp[LOOPCNT];        /* in case input is misaligned */
7919
  short *xp;
7920
  int nrange = 0;         /* number of range errors */
7921
  int realign = 0;        /* "do we need to fix input data alignment?" */
7922
  long cxp = (long) *((char**)xpp);
7923
7924
  realign = (cxp & 7) % SIZEOF_SHORT;
7925
  /* sjl: manually stripmine so we can limit amount of
7926
   * vector work space reserved to LOOPCNT elements. Also
7927
   * makes vectorisation easy */
7928
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7929
    ni=Min(nelems-j,LOOPCNT);
7930
    if (realign) {
7931
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7932
      xp = tmp;
7933
    } else {
7934
      xp = (short *) *xpp;
7935
    }
7936
   /* copy the next block */
7937
#pragma cdir loopcnt=LOOPCNT
7938
#pragma cdir shortloop
7939
    for (i=0; i<ni; i++) {
7940
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
7941
     /* test for range errors (not always needed but do it anyway) */
7942
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7943
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7944
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
7945
    }
7946
   /* update xpp and tp */
7947
    if (realign) xp = (short *) *xpp;
7948
    xp += ni;
7949
    tp += ni;
7950
    *xpp = (void*)xp;
7951
  }
7952
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7953
7954
#else   /* not SX */
7955
0
  const char *xp = (const char *) *xpp;
7956
0
  int status = NC_NOERR;
7957
7958
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7959
0
  {
7960
0
    const int lstatus = ncx_get_short_double(xp, tp);
7961
0
    if (status == NC_NOERR) /* report the first encountered error */
7962
0
      status = lstatus;
7963
0
  }
7964
7965
0
  *xpp = (const void *)xp;
7966
0
  return status;
7967
0
#endif
7968
0
}
7969
7970
int
7971
ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
7972
0
{
7973
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7974
7975
 /* basic algorithm is:
7976
  *   - ensure sane alignment of input data
7977
  *   - copy (conversion happens automatically) input data
7978
  *     to output
7979
  *   - update xpp to point at next unconverted input, and tp to point
7980
  *     at next location for converted output
7981
  */
7982
  long i, j, ni;
7983
  short tmp[LOOPCNT];        /* in case input is misaligned */
7984
  short *xp;
7985
  int nrange = 0;         /* number of range errors */
7986
  int realign = 0;        /* "do we need to fix input data alignment?" */
7987
  long cxp = (long) *((char**)xpp);
7988
7989
  realign = (cxp & 7) % SIZEOF_SHORT;
7990
  /* sjl: manually stripmine so we can limit amount of
7991
   * vector work space reserved to LOOPCNT elements. Also
7992
   * makes vectorisation easy */
7993
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7994
    ni=Min(nelems-j,LOOPCNT);
7995
    if (realign) {
7996
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7997
      xp = tmp;
7998
    } else {
7999
      xp = (short *) *xpp;
8000
    }
8001
   /* copy the next block */
8002
#pragma cdir loopcnt=LOOPCNT
8003
#pragma cdir shortloop
8004
    for (i=0; i<ni; i++) {
8005
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
8006
     /* test for range errors (not always needed but do it anyway) */
8007
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8008
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8009
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
8010
    }
8011
   /* update xpp and tp */
8012
    if (realign) xp = (short *) *xpp;
8013
    xp += ni;
8014
    tp += ni;
8015
    *xpp = (void*)xp;
8016
  }
8017
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8018
8019
#else   /* not SX */
8020
0
  const char *xp = (const char *) *xpp;
8021
0
  int status = NC_NOERR;
8022
8023
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8024
0
  {
8025
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8026
0
    if (status == NC_NOERR) /* report the first encountered error */
8027
0
      status = lstatus;
8028
0
  }
8029
8030
0
  *xpp = (const void *)xp;
8031
0
  return status;
8032
0
#endif
8033
0
}
8034
8035
int
8036
ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8037
0
{
8038
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8039
8040
 /* basic algorithm is:
8041
  *   - ensure sane alignment of input data
8042
  *   - copy (conversion happens automatically) input data
8043
  *     to output
8044
  *   - update xpp to point at next unconverted input, and tp to point
8045
  *     at next location for converted output
8046
  */
8047
  long i, j, ni;
8048
  short tmp[LOOPCNT];        /* in case input is misaligned */
8049
  short *xp;
8050
  int nrange = 0;         /* number of range errors */
8051
  int realign = 0;        /* "do we need to fix input data alignment?" */
8052
  long cxp = (long) *((char**)xpp);
8053
8054
  realign = (cxp & 7) % SIZEOF_SHORT;
8055
  /* sjl: manually stripmine so we can limit amount of
8056
   * vector work space reserved to LOOPCNT elements. Also
8057
   * makes vectorisation easy */
8058
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8059
    ni=Min(nelems-j,LOOPCNT);
8060
    if (realign) {
8061
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8062
      xp = tmp;
8063
    } else {
8064
      xp = (short *) *xpp;
8065
    }
8066
   /* copy the next block */
8067
#pragma cdir loopcnt=LOOPCNT
8068
#pragma cdir shortloop
8069
    for (i=0; i<ni; i++) {
8070
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
8071
     /* test for range errors (not always needed but do it anyway) */
8072
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8073
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8074
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
8075
    }
8076
   /* update xpp and tp */
8077
    if (realign) xp = (short *) *xpp;
8078
    xp += ni;
8079
    tp += ni;
8080
    *xpp = (void*)xp;
8081
  }
8082
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8083
8084
#else   /* not SX */
8085
0
  const char *xp = (const char *) *xpp;
8086
0
  int status = NC_NOERR;
8087
8088
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8089
0
  {
8090
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8091
0
    if (status == NC_NOERR) /* report the first encountered error */
8092
0
      status = lstatus;
8093
0
  }
8094
8095
0
  *xpp = (const void *)xp;
8096
0
  return status;
8097
0
#endif
8098
0
}
8099
8100
int
8101
ncx_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8102
0
{
8103
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8104
8105
 /* basic algorithm is:
8106
  *   - ensure sane alignment of input data
8107
  *   - copy (conversion happens automatically) input data
8108
  *     to output
8109
  *   - update xpp to point at next unconverted input, and tp to point
8110
  *     at next location for converted output
8111
  */
8112
  long i, j, ni;
8113
  short tmp[LOOPCNT];        /* in case input is misaligned */
8114
  short *xp;
8115
  int nrange = 0;         /* number of range errors */
8116
  int realign = 0;        /* "do we need to fix input data alignment?" */
8117
  long cxp = (long) *((char**)xpp);
8118
8119
  realign = (cxp & 7) % SIZEOF_SHORT;
8120
  /* sjl: manually stripmine so we can limit amount of
8121
   * vector work space reserved to LOOPCNT elements. Also
8122
   * makes vectorisation easy */
8123
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8124
    ni=Min(nelems-j,LOOPCNT);
8125
    if (realign) {
8126
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8127
      xp = tmp;
8128
    } else {
8129
      xp = (short *) *xpp;
8130
    }
8131
   /* copy the next block */
8132
#pragma cdir loopcnt=LOOPCNT
8133
#pragma cdir shortloop
8134
    for (i=0; i<ni; i++) {
8135
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
8136
     /* test for range errors (not always needed but do it anyway) */
8137
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8138
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8139
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
8140
    }
8141
   /* update xpp and tp */
8142
    if (realign) xp = (short *) *xpp;
8143
    xp += ni;
8144
    tp += ni;
8145
    *xpp = (void*)xp;
8146
  }
8147
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8148
8149
#else   /* not SX */
8150
0
  const char *xp = (const char *) *xpp;
8151
0
  int status = NC_NOERR;
8152
8153
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8154
0
  {
8155
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8156
0
    if (status == NC_NOERR) /* report the first encountered error */
8157
0
      status = lstatus;
8158
0
  }
8159
8160
0
  *xpp = (const void *)xp;
8161
0
  return status;
8162
0
#endif
8163
0
}
8164
8165
int
8166
ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8167
0
{
8168
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8169
8170
 /* basic algorithm is:
8171
  *   - ensure sane alignment of input data
8172
  *   - copy (conversion happens automatically) input data
8173
  *     to output
8174
  *   - update xpp to point at next unconverted input, and tp to point
8175
  *     at next location for converted output
8176
  */
8177
  long i, j, ni;
8178
  short tmp[LOOPCNT];        /* in case input is misaligned */
8179
  short *xp;
8180
  int nrange = 0;         /* number of range errors */
8181
  int realign = 0;        /* "do we need to fix input data alignment?" */
8182
  long cxp = (long) *((char**)xpp);
8183
8184
  realign = (cxp & 7) % SIZEOF_SHORT;
8185
  /* sjl: manually stripmine so we can limit amount of
8186
   * vector work space reserved to LOOPCNT elements. Also
8187
   * makes vectorisation easy */
8188
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8189
    ni=Min(nelems-j,LOOPCNT);
8190
    if (realign) {
8191
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8192
      xp = tmp;
8193
    } else {
8194
      xp = (short *) *xpp;
8195
    }
8196
   /* copy the next block */
8197
#pragma cdir loopcnt=LOOPCNT
8198
#pragma cdir shortloop
8199
    for (i=0; i<ni; i++) {
8200
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
8201
     /* test for range errors (not always needed but do it anyway) */
8202
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8203
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8204
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
8205
    }
8206
   /* update xpp and tp */
8207
    if (realign) xp = (short *) *xpp;
8208
    xp += ni;
8209
    tp += ni;
8210
    *xpp = (void*)xp;
8211
  }
8212
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8213
8214
#else   /* not SX */
8215
0
  const char *xp = (const char *) *xpp;
8216
0
  int status = NC_NOERR;
8217
8218
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8219
0
  {
8220
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8221
0
    if (status == NC_NOERR) /* report the first encountered error */
8222
0
      status = lstatus;
8223
0
  }
8224
8225
0
  *xpp = (const void *)xp;
8226
0
  return status;
8227
0
#endif
8228
0
}
8229
8230
int
8231
ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8232
0
{
8233
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8234
8235
 /* basic algorithm is:
8236
  *   - ensure sane alignment of input data
8237
  *   - copy (conversion happens automatically) input data
8238
  *     to output
8239
  *   - update xpp to point at next unconverted input, and tp to point
8240
  *     at next location for converted output
8241
  */
8242
  long i, j, ni;
8243
  short tmp[LOOPCNT];        /* in case input is misaligned */
8244
  short *xp;
8245
  int nrange = 0;         /* number of range errors */
8246
  int realign = 0;        /* "do we need to fix input data alignment?" */
8247
  long cxp = (long) *((char**)xpp);
8248
8249
  realign = (cxp & 7) % SIZEOF_SHORT;
8250
  /* sjl: manually stripmine so we can limit amount of
8251
   * vector work space reserved to LOOPCNT elements. Also
8252
   * makes vectorisation easy */
8253
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8254
    ni=Min(nelems-j,LOOPCNT);
8255
    if (realign) {
8256
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8257
      xp = tmp;
8258
    } else {
8259
      xp = (short *) *xpp;
8260
    }
8261
   /* copy the next block */
8262
#pragma cdir loopcnt=LOOPCNT
8263
#pragma cdir shortloop
8264
    for (i=0; i<ni; i++) {
8265
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
8266
     /* test for range errors (not always needed but do it anyway) */
8267
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8268
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8269
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
8270
    }
8271
   /* update xpp and tp */
8272
    if (realign) xp = (short *) *xpp;
8273
    xp += ni;
8274
    tp += ni;
8275
    *xpp = (void*)xp;
8276
  }
8277
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8278
8279
#else   /* not SX */
8280
0
  const char *xp = (const char *) *xpp;
8281
0
  int status = NC_NOERR;
8282
8283
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8284
0
  {
8285
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8286
0
    if (status == NC_NOERR) /* report the first encountered error */
8287
0
      status = lstatus;
8288
0
  }
8289
8290
0
  *xpp = (const void *)xp;
8291
0
  return status;
8292
0
#endif
8293
0
}
8294
8295
8296
int
8297
ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
8298
0
{
8299
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8300
8301
0
  const char *xp = (const char *) *xpp;
8302
0
  int status = NC_NOERR;
8303
8304
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8305
0
  {
8306
0
    const int lstatus = ncx_get_short_schar(xp, tp);
8307
0
    if (status == NC_NOERR) /* report the first encountered error */
8308
0
      status = lstatus;
8309
0
  }
8310
8311
0
  if (rndup != 0)
8312
0
    xp += X_SIZEOF_SHORT;
8313
8314
0
  *xpp = (void *)xp;
8315
0
  return status;
8316
0
}
8317
8318
int
8319
ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8320
0
{
8321
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8322
8323
0
  const char *xp = (const char *) *xpp;
8324
0
  int status = NC_NOERR;
8325
8326
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8327
0
  {
8328
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8329
0
    if (status == NC_NOERR) /* report the first encountered error */
8330
0
      status = lstatus;
8331
0
  }
8332
8333
0
  if (rndup != 0)
8334
0
    xp += X_SIZEOF_SHORT;
8335
8336
0
  *xpp = (void *)xp;
8337
0
  return status;
8338
0
}
8339
8340
int
8341
ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
8342
0
{
8343
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8344
8345
0
  const char *xp = (const char *) *xpp;
8346
0
  int status = NC_NOERR;
8347
8348
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8349
0
  {
8350
0
    const int lstatus = ncx_get_short_short(xp, tp);
8351
0
    if (status == NC_NOERR) /* report the first encountered error */
8352
0
      status = lstatus;
8353
0
  }
8354
8355
0
  if (rndup != 0)
8356
0
    xp += X_SIZEOF_SHORT;
8357
8358
0
  *xpp = (void *)xp;
8359
0
  return status;
8360
0
}
8361
8362
int
8363
ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
8364
0
{
8365
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8366
8367
0
  const char *xp = (const char *) *xpp;
8368
0
  int status = NC_NOERR;
8369
8370
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8371
0
  {
8372
0
    const int lstatus = ncx_get_short_int(xp, tp);
8373
0
    if (status == NC_NOERR) /* report the first encountered error */
8374
0
      status = lstatus;
8375
0
  }
8376
8377
0
  if (rndup != 0)
8378
0
    xp += X_SIZEOF_SHORT;
8379
8380
0
  *xpp = (void *)xp;
8381
0
  return status;
8382
0
}
8383
8384
int
8385
ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
8386
0
{
8387
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8388
8389
0
  const char *xp = (const char *) *xpp;
8390
0
  int status = NC_NOERR;
8391
8392
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8393
0
  {
8394
0
    const int lstatus = ncx_get_short_long(xp, tp);
8395
0
    if (status == NC_NOERR) /* report the first encountered error */
8396
0
      status = lstatus;
8397
0
  }
8398
8399
0
  if (rndup != 0)
8400
0
    xp += X_SIZEOF_SHORT;
8401
8402
0
  *xpp = (void *)xp;
8403
0
  return status;
8404
0
}
8405
8406
int
8407
ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
8408
0
{
8409
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8410
8411
0
  const char *xp = (const char *) *xpp;
8412
0
  int status = NC_NOERR;
8413
8414
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8415
0
  {
8416
0
    const int lstatus = ncx_get_short_float(xp, tp);
8417
0
    if (status == NC_NOERR) /* report the first encountered error */
8418
0
      status = lstatus;
8419
0
  }
8420
8421
0
  if (rndup != 0)
8422
0
    xp += X_SIZEOF_SHORT;
8423
8424
0
  *xpp = (void *)xp;
8425
0
  return status;
8426
0
}
8427
8428
int
8429
ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
8430
0
{
8431
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8432
8433
0
  const char *xp = (const char *) *xpp;
8434
0
  int status = NC_NOERR;
8435
8436
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8437
0
  {
8438
0
    const int lstatus = ncx_get_short_double(xp, tp);
8439
0
    if (status == NC_NOERR) /* report the first encountered error */
8440
0
      status = lstatus;
8441
0
  }
8442
8443
0
  if (rndup != 0)
8444
0
    xp += X_SIZEOF_SHORT;
8445
8446
0
  *xpp = (void *)xp;
8447
0
  return status;
8448
0
}
8449
8450
int
8451
ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8452
0
{
8453
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8454
8455
0
  const char *xp = (const char *) *xpp;
8456
0
  int status = NC_NOERR;
8457
8458
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8459
0
  {
8460
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8461
0
    if (status == NC_NOERR) /* report the first encountered error */
8462
0
      status = lstatus;
8463
0
  }
8464
8465
0
  if (rndup != 0)
8466
0
    xp += X_SIZEOF_SHORT;
8467
8468
0
  *xpp = (void *)xp;
8469
0
  return status;
8470
0
}
8471
8472
int
8473
ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8474
0
{
8475
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8476
8477
0
  const char *xp = (const char *) *xpp;
8478
0
  int status = NC_NOERR;
8479
8480
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8481
0
  {
8482
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8483
0
    if (status == NC_NOERR) /* report the first encountered error */
8484
0
      status = lstatus;
8485
0
  }
8486
8487
0
  if (rndup != 0)
8488
0
    xp += X_SIZEOF_SHORT;
8489
8490
0
  *xpp = (void *)xp;
8491
0
  return status;
8492
0
}
8493
8494
int
8495
ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8496
0
{
8497
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8498
8499
0
  const char *xp = (const char *) *xpp;
8500
0
  int status = NC_NOERR;
8501
8502
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8503
0
  {
8504
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8505
0
    if (status == NC_NOERR) /* report the first encountered error */
8506
0
      status = lstatus;
8507
0
  }
8508
8509
0
  if (rndup != 0)
8510
0
    xp += X_SIZEOF_SHORT;
8511
8512
0
  *xpp = (void *)xp;
8513
0
  return status;
8514
0
}
8515
8516
int
8517
ncx_pad_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8518
0
{
8519
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8520
8521
0
  const char *xp = (const char *) *xpp;
8522
0
  int status = NC_NOERR;
8523
8524
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8525
0
  {
8526
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8527
0
    if (status == NC_NOERR) /* report the first encountered error */
8528
0
      status = lstatus;
8529
0
  }
8530
8531
0
  if (rndup != 0)
8532
0
    xp += X_SIZEOF_SHORT;
8533
8534
0
  *xpp = (void *)xp;
8535
0
  return status;
8536
0
}
8537
8538
8539
#if X_SIZEOF_SHORT == SIZEOF_SHORT
8540
/* optimized version */
8541
int
8542
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8543
0
{
8544
#ifdef WORDS_BIGENDIAN
8545
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
8546
# else
8547
0
  swapn2b(*xpp, tp, nelems);
8548
0
# endif
8549
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
8550
0
  return NC_NOERR;
8551
0
}
8552
#else
8553
int
8554
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8555
{
8556
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8557
8558
 /* basic algorithm is:
8559
  *   - ensure sane alignment of output data
8560
  *   - copy (conversion happens automatically) input data
8561
  *     to output
8562
  *   - update tp to point at next unconverted input, and xpp to point
8563
  *     at next location for converted output
8564
  */
8565
  long i, j, ni;
8566
  short tmp[LOOPCNT];        /* in case input is misaligned */
8567
  short *xp;
8568
  int nrange = 0;         /* number of range errors */
8569
  int realign = 0;        /* "do we need to fix input data alignment?" */
8570
  long cxp = (long) *((char**)xpp);
8571
8572
  realign = (cxp & 7) % SIZEOF_SHORT;
8573
  /* sjl: manually stripmine so we can limit amount of
8574
   * vector work space reserved to LOOPCNT elements. Also
8575
   * makes vectorisation easy */
8576
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8577
    ni=Min(nelems-j,LOOPCNT);
8578
    if (realign) {
8579
      xp = tmp;
8580
    } else {
8581
      xp = (short *) *xpp;
8582
    }
8583
   /* copy the next block */
8584
#pragma cdir loopcnt=LOOPCNT
8585
#pragma cdir shortloop
8586
    for (i=0; i<ni; i++) {
8587
      /* the normal case: */
8588
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8589
     /* test for range errors (not always needed but do it anyway) */
8590
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8591
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8592
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8593
    }
8594
   /* copy workspace back if necessary */
8595
    if (realign) {
8596
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8597
      xp = (short *) *xpp;
8598
    }
8599
   /* update xpp and tp */
8600
    xp += ni;
8601
    tp += ni;
8602
    *xpp = (void*)xp;
8603
  }
8604
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8605
8606
#else   /* not SX */
8607
8608
  char *xp = (char *) *xpp;
8609
  int status = NC_NOERR;
8610
8611
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8612
  {
8613
    int lstatus = ncx_put_short_short(xp, tp, fillp);
8614
    if (status == NC_NOERR) /* report the first encountered error */
8615
      status = lstatus;
8616
  }
8617
8618
  *xpp = (void *)xp;
8619
  return status;
8620
#endif
8621
}
8622
8623
#endif
8624
int
8625
ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
8626
0
{
8627
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8628
8629
 /* basic algorithm is:
8630
  *   - ensure sane alignment of output data
8631
  *   - copy (conversion happens automatically) input data
8632
  *     to output
8633
  *   - update tp to point at next unconverted input, and xpp to point
8634
  *     at next location for converted output
8635
  */
8636
  long i, j, ni;
8637
  short tmp[LOOPCNT];        /* in case input is misaligned */
8638
  short *xp;
8639
  int nrange = 0;         /* number of range errors */
8640
  int realign = 0;        /* "do we need to fix input data alignment?" */
8641
  long cxp = (long) *((char**)xpp);
8642
8643
  realign = (cxp & 7) % SIZEOF_SHORT;
8644
  /* sjl: manually stripmine so we can limit amount of
8645
   * vector work space reserved to LOOPCNT elements. Also
8646
   * makes vectorisation easy */
8647
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8648
    ni=Min(nelems-j,LOOPCNT);
8649
    if (realign) {
8650
      xp = tmp;
8651
    } else {
8652
      xp = (short *) *xpp;
8653
    }
8654
   /* copy the next block */
8655
#pragma cdir loopcnt=LOOPCNT
8656
#pragma cdir shortloop
8657
    for (i=0; i<ni; i++) {
8658
      /* the normal case: */
8659
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8660
     /* test for range errors (not always needed but do it anyway) */
8661
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8662
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8663
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8664
    }
8665
   /* copy workspace back if necessary */
8666
    if (realign) {
8667
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8668
      xp = (short *) *xpp;
8669
    }
8670
   /* update xpp and tp */
8671
    xp += ni;
8672
    tp += ni;
8673
    *xpp = (void*)xp;
8674
  }
8675
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8676
8677
#else   /* not SX */
8678
8679
0
  char *xp = (char *) *xpp;
8680
0
  int status = NC_NOERR;
8681
8682
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8683
0
  {
8684
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
8685
0
    if (status == NC_NOERR) /* report the first encountered error */
8686
0
      status = lstatus;
8687
0
  }
8688
8689
0
  *xpp = (void *)xp;
8690
0
  return status;
8691
0
#endif
8692
0
}
8693
8694
int
8695
ncx_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
8696
0
{
8697
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8698
8699
 /* basic algorithm is:
8700
  *   - ensure sane alignment of output data
8701
  *   - copy (conversion happens automatically) input data
8702
  *     to output
8703
  *   - update tp to point at next unconverted input, and xpp to point
8704
  *     at next location for converted output
8705
  */
8706
  long i, j, ni;
8707
  short tmp[LOOPCNT];        /* in case input is misaligned */
8708
  short *xp;
8709
  int nrange = 0;         /* number of range errors */
8710
  int realign = 0;        /* "do we need to fix input data alignment?" */
8711
  long cxp = (long) *((char**)xpp);
8712
8713
  realign = (cxp & 7) % SIZEOF_SHORT;
8714
  /* sjl: manually stripmine so we can limit amount of
8715
   * vector work space reserved to LOOPCNT elements. Also
8716
   * makes vectorisation easy */
8717
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8718
    ni=Min(nelems-j,LOOPCNT);
8719
    if (realign) {
8720
      xp = tmp;
8721
    } else {
8722
      xp = (short *) *xpp;
8723
    }
8724
   /* copy the next block */
8725
#pragma cdir loopcnt=LOOPCNT
8726
#pragma cdir shortloop
8727
    for (i=0; i<ni; i++) {
8728
      /* the normal case: */
8729
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8730
     /* test for range errors (not always needed but do it anyway) */
8731
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8732
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8733
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8734
    }
8735
   /* copy workspace back if necessary */
8736
    if (realign) {
8737
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8738
      xp = (short *) *xpp;
8739
    }
8740
   /* update xpp and tp */
8741
    xp += ni;
8742
    tp += ni;
8743
    *xpp = (void*)xp;
8744
  }
8745
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8746
8747
#else   /* not SX */
8748
8749
0
  char *xp = (char *) *xpp;
8750
0
  int status = NC_NOERR;
8751
8752
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8753
0
  {
8754
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
8755
0
    if (status == NC_NOERR) /* report the first encountered error */
8756
0
      status = lstatus;
8757
0
  }
8758
8759
0
  *xpp = (void *)xp;
8760
0
  return status;
8761
0
#endif
8762
0
}
8763
8764
int
8765
ncx_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
8766
0
{
8767
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8768
8769
 /* basic algorithm is:
8770
  *   - ensure sane alignment of output data
8771
  *   - copy (conversion happens automatically) input data
8772
  *     to output
8773
  *   - update tp to point at next unconverted input, and xpp to point
8774
  *     at next location for converted output
8775
  */
8776
  long i, j, ni;
8777
  short tmp[LOOPCNT];        /* in case input is misaligned */
8778
  short *xp;
8779
  int nrange = 0;         /* number of range errors */
8780
  int realign = 0;        /* "do we need to fix input data alignment?" */
8781
  long cxp = (long) *((char**)xpp);
8782
8783
  realign = (cxp & 7) % SIZEOF_SHORT;
8784
  /* sjl: manually stripmine so we can limit amount of
8785
   * vector work space reserved to LOOPCNT elements. Also
8786
   * makes vectorisation easy */
8787
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8788
    ni=Min(nelems-j,LOOPCNT);
8789
    if (realign) {
8790
      xp = tmp;
8791
    } else {
8792
      xp = (short *) *xpp;
8793
    }
8794
   /* copy the next block */
8795
#pragma cdir loopcnt=LOOPCNT
8796
#pragma cdir shortloop
8797
    for (i=0; i<ni; i++) {
8798
      /* the normal case: */
8799
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8800
     /* test for range errors (not always needed but do it anyway) */
8801
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8802
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8803
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8804
    }
8805
   /* copy workspace back if necessary */
8806
    if (realign) {
8807
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8808
      xp = (short *) *xpp;
8809
    }
8810
   /* update xpp and tp */
8811
    xp += ni;
8812
    tp += ni;
8813
    *xpp = (void*)xp;
8814
  }
8815
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8816
8817
#else   /* not SX */
8818
8819
0
  char *xp = (char *) *xpp;
8820
0
  int status = NC_NOERR;
8821
8822
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8823
0
  {
8824
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
8825
0
    if (status == NC_NOERR) /* report the first encountered error */
8826
0
      status = lstatus;
8827
0
  }
8828
8829
0
  *xpp = (void *)xp;
8830
0
  return status;
8831
0
#endif
8832
0
}
8833
8834
int
8835
ncx_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
8836
0
{
8837
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8838
8839
 /* basic algorithm is:
8840
  *   - ensure sane alignment of output data
8841
  *   - copy (conversion happens automatically) input data
8842
  *     to output
8843
  *   - update tp to point at next unconverted input, and xpp to point
8844
  *     at next location for converted output
8845
  */
8846
  long i, j, ni;
8847
  short tmp[LOOPCNT];        /* in case input is misaligned */
8848
  short *xp;
8849
  int nrange = 0;         /* number of range errors */
8850
  int realign = 0;        /* "do we need to fix input data alignment?" */
8851
  long cxp = (long) *((char**)xpp);
8852
8853
  realign = (cxp & 7) % SIZEOF_SHORT;
8854
  /* sjl: manually stripmine so we can limit amount of
8855
   * vector work space reserved to LOOPCNT elements. Also
8856
   * makes vectorisation easy */
8857
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8858
    ni=Min(nelems-j,LOOPCNT);
8859
    if (realign) {
8860
      xp = tmp;
8861
    } else {
8862
      xp = (short *) *xpp;
8863
    }
8864
   /* copy the next block */
8865
#pragma cdir loopcnt=LOOPCNT
8866
#pragma cdir shortloop
8867
    for (i=0; i<ni; i++) {
8868
      /* the normal case: */
8869
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8870
     /* test for range errors (not always needed but do it anyway) */
8871
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8872
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8873
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8874
    }
8875
   /* copy workspace back if necessary */
8876
    if (realign) {
8877
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8878
      xp = (short *) *xpp;
8879
    }
8880
   /* update xpp and tp */
8881
    xp += ni;
8882
    tp += ni;
8883
    *xpp = (void*)xp;
8884
  }
8885
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8886
8887
#else   /* not SX */
8888
8889
0
  char *xp = (char *) *xpp;
8890
0
  int status = NC_NOERR;
8891
8892
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8893
0
  {
8894
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
8895
0
    if (status == NC_NOERR) /* report the first encountered error */
8896
0
      status = lstatus;
8897
0
  }
8898
8899
0
  *xpp = (void *)xp;
8900
0
  return status;
8901
0
#endif
8902
0
}
8903
8904
int
8905
ncx_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
8906
0
{
8907
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8908
8909
 /* basic algorithm is:
8910
  *   - ensure sane alignment of output data
8911
  *   - copy (conversion happens automatically) input data
8912
  *     to output
8913
  *   - update tp to point at next unconverted input, and xpp to point
8914
  *     at next location for converted output
8915
  */
8916
  long i, j, ni;
8917
  short tmp[LOOPCNT];        /* in case input is misaligned */
8918
  short *xp;
8919
  int nrange = 0;         /* number of range errors */
8920
  int realign = 0;        /* "do we need to fix input data alignment?" */
8921
  long cxp = (long) *((char**)xpp);
8922
8923
  realign = (cxp & 7) % SIZEOF_SHORT;
8924
  /* sjl: manually stripmine so we can limit amount of
8925
   * vector work space reserved to LOOPCNT elements. Also
8926
   * makes vectorisation easy */
8927
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8928
    ni=Min(nelems-j,LOOPCNT);
8929
    if (realign) {
8930
      xp = tmp;
8931
    } else {
8932
      xp = (short *) *xpp;
8933
    }
8934
   /* copy the next block */
8935
#pragma cdir loopcnt=LOOPCNT
8936
#pragma cdir shortloop
8937
    for (i=0; i<ni; i++) {
8938
      /* the normal case: */
8939
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8940
     /* test for range errors (not always needed but do it anyway) */
8941
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8942
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8943
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8944
    }
8945
   /* copy workspace back if necessary */
8946
    if (realign) {
8947
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8948
      xp = (short *) *xpp;
8949
    }
8950
   /* update xpp and tp */
8951
    xp += ni;
8952
    tp += ni;
8953
    *xpp = (void*)xp;
8954
  }
8955
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8956
8957
#else   /* not SX */
8958
8959
0
  char *xp = (char *) *xpp;
8960
0
  int status = NC_NOERR;
8961
8962
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8963
0
  {
8964
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
8965
0
    if (status == NC_NOERR) /* report the first encountered error */
8966
0
      status = lstatus;
8967
0
  }
8968
8969
0
  *xpp = (void *)xp;
8970
0
  return status;
8971
0
#endif
8972
0
}
8973
8974
int
8975
ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
8976
0
{
8977
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8978
8979
 /* basic algorithm is:
8980
  *   - ensure sane alignment of output data
8981
  *   - copy (conversion happens automatically) input data
8982
  *     to output
8983
  *   - update tp to point at next unconverted input, and xpp to point
8984
  *     at next location for converted output
8985
  */
8986
  long i, j, ni;
8987
  short tmp[LOOPCNT];        /* in case input is misaligned */
8988
  short *xp;
8989
  int nrange = 0;         /* number of range errors */
8990
  int realign = 0;        /* "do we need to fix input data alignment?" */
8991
  long cxp = (long) *((char**)xpp);
8992
8993
  realign = (cxp & 7) % SIZEOF_SHORT;
8994
  /* sjl: manually stripmine so we can limit amount of
8995
   * vector work space reserved to LOOPCNT elements. Also
8996
   * makes vectorisation easy */
8997
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8998
    ni=Min(nelems-j,LOOPCNT);
8999
    if (realign) {
9000
      xp = tmp;
9001
    } else {
9002
      xp = (short *) *xpp;
9003
    }
9004
   /* copy the next block */
9005
#pragma cdir loopcnt=LOOPCNT
9006
#pragma cdir shortloop
9007
    for (i=0; i<ni; i++) {
9008
      /* the normal case: */
9009
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9010
     /* test for range errors (not always needed but do it anyway) */
9011
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9012
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9013
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9014
    }
9015
   /* copy workspace back if necessary */
9016
    if (realign) {
9017
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9018
      xp = (short *) *xpp;
9019
    }
9020
   /* update xpp and tp */
9021
    xp += ni;
9022
    tp += ni;
9023
    *xpp = (void*)xp;
9024
  }
9025
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9026
9027
#else   /* not SX */
9028
9029
0
  char *xp = (char *) *xpp;
9030
0
  int status = NC_NOERR;
9031
9032
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9033
0
  {
9034
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9035
0
    if (status == NC_NOERR) /* report the first encountered error */
9036
0
      status = lstatus;
9037
0
  }
9038
9039
0
  *xpp = (void *)xp;
9040
0
  return status;
9041
0
#endif
9042
0
}
9043
9044
int
9045
ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9046
0
{
9047
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9048
9049
 /* basic algorithm is:
9050
  *   - ensure sane alignment of output data
9051
  *   - copy (conversion happens automatically) input data
9052
  *     to output
9053
  *   - update tp to point at next unconverted input, and xpp to point
9054
  *     at next location for converted output
9055
  */
9056
  long i, j, ni;
9057
  short tmp[LOOPCNT];        /* in case input is misaligned */
9058
  short *xp;
9059
  int nrange = 0;         /* number of range errors */
9060
  int realign = 0;        /* "do we need to fix input data alignment?" */
9061
  long cxp = (long) *((char**)xpp);
9062
9063
  realign = (cxp & 7) % SIZEOF_SHORT;
9064
  /* sjl: manually stripmine so we can limit amount of
9065
   * vector work space reserved to LOOPCNT elements. Also
9066
   * makes vectorisation easy */
9067
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9068
    ni=Min(nelems-j,LOOPCNT);
9069
    if (realign) {
9070
      xp = tmp;
9071
    } else {
9072
      xp = (short *) *xpp;
9073
    }
9074
   /* copy the next block */
9075
#pragma cdir loopcnt=LOOPCNT
9076
#pragma cdir shortloop
9077
    for (i=0; i<ni; i++) {
9078
      /* the normal case: */
9079
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9080
     /* test for range errors (not always needed but do it anyway) */
9081
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9082
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9083
      nrange += tp[i] > X_SHORT_MAX ;
9084
    }
9085
   /* copy workspace back if necessary */
9086
    if (realign) {
9087
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9088
      xp = (short *) *xpp;
9089
    }
9090
   /* update xpp and tp */
9091
    xp += ni;
9092
    tp += ni;
9093
    *xpp = (void*)xp;
9094
  }
9095
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9096
9097
#else   /* not SX */
9098
9099
0
  char *xp = (char *) *xpp;
9100
0
  int status = NC_NOERR;
9101
9102
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9103
0
  {
9104
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9105
0
    if (status == NC_NOERR) /* report the first encountered error */
9106
0
      status = lstatus;
9107
0
  }
9108
9109
0
  *xpp = (void *)xp;
9110
0
  return status;
9111
0
#endif
9112
0
}
9113
9114
int
9115
ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9116
0
{
9117
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9118
9119
 /* basic algorithm is:
9120
  *   - ensure sane alignment of output data
9121
  *   - copy (conversion happens automatically) input data
9122
  *     to output
9123
  *   - update tp to point at next unconverted input, and xpp to point
9124
  *     at next location for converted output
9125
  */
9126
  long i, j, ni;
9127
  short tmp[LOOPCNT];        /* in case input is misaligned */
9128
  short *xp;
9129
  int nrange = 0;         /* number of range errors */
9130
  int realign = 0;        /* "do we need to fix input data alignment?" */
9131
  long cxp = (long) *((char**)xpp);
9132
9133
  realign = (cxp & 7) % SIZEOF_SHORT;
9134
  /* sjl: manually stripmine so we can limit amount of
9135
   * vector work space reserved to LOOPCNT elements. Also
9136
   * makes vectorisation easy */
9137
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9138
    ni=Min(nelems-j,LOOPCNT);
9139
    if (realign) {
9140
      xp = tmp;
9141
    } else {
9142
      xp = (short *) *xpp;
9143
    }
9144
   /* copy the next block */
9145
#pragma cdir loopcnt=LOOPCNT
9146
#pragma cdir shortloop
9147
    for (i=0; i<ni; i++) {
9148
      /* the normal case: */
9149
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9150
     /* test for range errors (not always needed but do it anyway) */
9151
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9152
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9153
      nrange += tp[i] > X_SHORT_MAX ;
9154
    }
9155
   /* copy workspace back if necessary */
9156
    if (realign) {
9157
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9158
      xp = (short *) *xpp;
9159
    }
9160
   /* update xpp and tp */
9161
    xp += ni;
9162
    tp += ni;
9163
    *xpp = (void*)xp;
9164
  }
9165
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9166
9167
#else   /* not SX */
9168
9169
0
  char *xp = (char *) *xpp;
9170
0
  int status = NC_NOERR;
9171
9172
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9173
0
  {
9174
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9175
0
    if (status == NC_NOERR) /* report the first encountered error */
9176
0
      status = lstatus;
9177
0
  }
9178
9179
0
  *xpp = (void *)xp;
9180
0
  return status;
9181
0
#endif
9182
0
}
9183
9184
int
9185
ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9186
0
{
9187
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9188
9189
 /* basic algorithm is:
9190
  *   - ensure sane alignment of output data
9191
  *   - copy (conversion happens automatically) input data
9192
  *     to output
9193
  *   - update tp to point at next unconverted input, and xpp to point
9194
  *     at next location for converted output
9195
  */
9196
  long i, j, ni;
9197
  short tmp[LOOPCNT];        /* in case input is misaligned */
9198
  short *xp;
9199
  int nrange = 0;         /* number of range errors */
9200
  int realign = 0;        /* "do we need to fix input data alignment?" */
9201
  long cxp = (long) *((char**)xpp);
9202
9203
  realign = (cxp & 7) % SIZEOF_SHORT;
9204
  /* sjl: manually stripmine so we can limit amount of
9205
   * vector work space reserved to LOOPCNT elements. Also
9206
   * makes vectorisation easy */
9207
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9208
    ni=Min(nelems-j,LOOPCNT);
9209
    if (realign) {
9210
      xp = tmp;
9211
    } else {
9212
      xp = (short *) *xpp;
9213
    }
9214
   /* copy the next block */
9215
#pragma cdir loopcnt=LOOPCNT
9216
#pragma cdir shortloop
9217
    for (i=0; i<ni; i++) {
9218
      /* the normal case: */
9219
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9220
     /* test for range errors (not always needed but do it anyway) */
9221
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9222
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9223
      nrange += tp[i] > X_SHORT_MAX ;
9224
    }
9225
   /* copy workspace back if necessary */
9226
    if (realign) {
9227
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9228
      xp = (short *) *xpp;
9229
    }
9230
   /* update xpp and tp */
9231
    xp += ni;
9232
    tp += ni;
9233
    *xpp = (void*)xp;
9234
  }
9235
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9236
9237
#else   /* not SX */
9238
9239
0
  char *xp = (char *) *xpp;
9240
0
  int status = NC_NOERR;
9241
9242
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9243
0
  {
9244
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9245
0
    if (status == NC_NOERR) /* report the first encountered error */
9246
0
      status = lstatus;
9247
0
  }
9248
9249
0
  *xpp = (void *)xp;
9250
0
  return status;
9251
0
#endif
9252
0
}
9253
9254
int
9255
ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9256
0
{
9257
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9258
9259
 /* basic algorithm is:
9260
  *   - ensure sane alignment of output data
9261
  *   - copy (conversion happens automatically) input data
9262
  *     to output
9263
  *   - update tp to point at next unconverted input, and xpp to point
9264
  *     at next location for converted output
9265
  */
9266
  long i, j, ni;
9267
  short tmp[LOOPCNT];        /* in case input is misaligned */
9268
  short *xp;
9269
  int nrange = 0;         /* number of range errors */
9270
  int realign = 0;        /* "do we need to fix input data alignment?" */
9271
  long cxp = (long) *((char**)xpp);
9272
9273
  realign = (cxp & 7) % SIZEOF_SHORT;
9274
  /* sjl: manually stripmine so we can limit amount of
9275
   * vector work space reserved to LOOPCNT elements. Also
9276
   * makes vectorisation easy */
9277
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9278
    ni=Min(nelems-j,LOOPCNT);
9279
    if (realign) {
9280
      xp = tmp;
9281
    } else {
9282
      xp = (short *) *xpp;
9283
    }
9284
   /* copy the next block */
9285
#pragma cdir loopcnt=LOOPCNT
9286
#pragma cdir shortloop
9287
    for (i=0; i<ni; i++) {
9288
      /* the normal case: */
9289
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9290
     /* test for range errors (not always needed but do it anyway) */
9291
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9292
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9293
      nrange += tp[i] > X_SHORT_MAX ;
9294
    }
9295
   /* copy workspace back if necessary */
9296
    if (realign) {
9297
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9298
      xp = (short *) *xpp;
9299
    }
9300
   /* update xpp and tp */
9301
    xp += ni;
9302
    tp += ni;
9303
    *xpp = (void*)xp;
9304
  }
9305
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9306
9307
#else   /* not SX */
9308
9309
0
  char *xp = (char *) *xpp;
9310
0
  int status = NC_NOERR;
9311
9312
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9313
0
  {
9314
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9315
0
    if (status == NC_NOERR) /* report the first encountered error */
9316
0
      status = lstatus;
9317
0
  }
9318
9319
0
  *xpp = (void *)xp;
9320
0
  return status;
9321
0
#endif
9322
0
}
9323
9324
9325
int
9326
ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
9327
0
{
9328
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9329
9330
0
  char *xp = (char *) *xpp;
9331
0
  int status = NC_NOERR;
9332
9333
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9334
0
  {
9335
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
9336
0
    if (status == NC_NOERR) /* report the first encountered error */
9337
0
      status = lstatus;
9338
0
  }
9339
9340
0
  if (rndup != 0)
9341
0
  {
9342
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9343
0
    xp += X_SIZEOF_SHORT;
9344
0
  }
9345
9346
0
  *xpp = (void *)xp;
9347
0
  return status;
9348
0
}
9349
9350
int
9351
ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9352
0
{
9353
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9354
9355
0
  char *xp = (char *) *xpp;
9356
0
  int status = NC_NOERR;
9357
9358
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9359
0
  {
9360
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9361
0
    if (status == NC_NOERR) /* report the first encountered error */
9362
0
      status = lstatus;
9363
0
  }
9364
9365
0
  if (rndup != 0)
9366
0
  {
9367
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9368
0
    xp += X_SIZEOF_SHORT;
9369
0
  }
9370
9371
0
  *xpp = (void *)xp;
9372
0
  return status;
9373
0
}
9374
9375
int
9376
ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
9377
0
{
9378
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9379
9380
0
  char *xp = (char *) *xpp;
9381
0
  int status = NC_NOERR;
9382
9383
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9384
0
  {
9385
0
    int lstatus = ncx_put_short_short(xp, tp, fillp);
9386
0
    if (status == NC_NOERR) /* report the first encountered error */
9387
0
      status = lstatus;
9388
0
  }
9389
9390
0
  if (rndup != 0)
9391
0
  {
9392
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9393
0
    xp += X_SIZEOF_SHORT;
9394
0
  }
9395
9396
0
  *xpp = (void *)xp;
9397
0
  return status;
9398
0
}
9399
9400
int
9401
ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
9402
0
{
9403
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9404
9405
0
  char *xp = (char *) *xpp;
9406
0
  int status = NC_NOERR;
9407
9408
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9409
0
  {
9410
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
9411
0
    if (status == NC_NOERR) /* report the first encountered error */
9412
0
      status = lstatus;
9413
0
  }
9414
9415
0
  if (rndup != 0)
9416
0
  {
9417
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9418
0
    xp += X_SIZEOF_SHORT;
9419
0
  }
9420
9421
0
  *xpp = (void *)xp;
9422
0
  return status;
9423
0
}
9424
9425
int
9426
ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
9427
0
{
9428
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9429
9430
0
  char *xp = (char *) *xpp;
9431
0
  int status = NC_NOERR;
9432
9433
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9434
0
  {
9435
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
9436
0
    if (status == NC_NOERR) /* report the first encountered error */
9437
0
      status = lstatus;
9438
0
  }
9439
9440
0
  if (rndup != 0)
9441
0
  {
9442
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9443
0
    xp += X_SIZEOF_SHORT;
9444
0
  }
9445
9446
0
  *xpp = (void *)xp;
9447
0
  return status;
9448
0
}
9449
9450
int
9451
ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9452
0
{
9453
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9454
9455
0
  char *xp = (char *) *xpp;
9456
0
  int status = NC_NOERR;
9457
9458
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9459
0
  {
9460
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
9461
0
    if (status == NC_NOERR) /* report the first encountered error */
9462
0
      status = lstatus;
9463
0
  }
9464
9465
0
  if (rndup != 0)
9466
0
  {
9467
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9468
0
    xp += X_SIZEOF_SHORT;
9469
0
  }
9470
9471
0
  *xpp = (void *)xp;
9472
0
  return status;
9473
0
}
9474
9475
int
9476
ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9477
0
{
9478
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9479
9480
0
  char *xp = (char *) *xpp;
9481
0
  int status = NC_NOERR;
9482
9483
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9484
0
  {
9485
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
9486
0
    if (status == NC_NOERR) /* report the first encountered error */
9487
0
      status = lstatus;
9488
0
  }
9489
9490
0
  if (rndup != 0)
9491
0
  {
9492
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9493
0
    xp += X_SIZEOF_SHORT;
9494
0
  }
9495
9496
0
  *xpp = (void *)xp;
9497
0
  return status;
9498
0
}
9499
9500
int
9501
ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9502
0
{
9503
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9504
9505
0
  char *xp = (char *) *xpp;
9506
0
  int status = NC_NOERR;
9507
9508
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9509
0
  {
9510
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9511
0
    if (status == NC_NOERR) /* report the first encountered error */
9512
0
      status = lstatus;
9513
0
  }
9514
9515
0
  if (rndup != 0)
9516
0
  {
9517
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9518
0
    xp += X_SIZEOF_SHORT;
9519
0
  }
9520
9521
0
  *xpp = (void *)xp;
9522
0
  return status;
9523
0
}
9524
9525
int
9526
ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9527
0
{
9528
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9529
9530
0
  char *xp = (char *) *xpp;
9531
0
  int status = NC_NOERR;
9532
9533
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9534
0
  {
9535
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9536
0
    if (status == NC_NOERR) /* report the first encountered error */
9537
0
      status = lstatus;
9538
0
  }
9539
9540
0
  if (rndup != 0)
9541
0
  {
9542
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9543
0
    xp += X_SIZEOF_SHORT;
9544
0
  }
9545
9546
0
  *xpp = (void *)xp;
9547
0
  return status;
9548
0
}
9549
9550
int
9551
ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9552
0
{
9553
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9554
9555
0
  char *xp = (char *) *xpp;
9556
0
  int status = NC_NOERR;
9557
9558
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9559
0
  {
9560
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9561
0
    if (status == NC_NOERR) /* report the first encountered error */
9562
0
      status = lstatus;
9563
0
  }
9564
9565
0
  if (rndup != 0)
9566
0
  {
9567
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9568
0
    xp += X_SIZEOF_SHORT;
9569
0
  }
9570
9571
0
  *xpp = (void *)xp;
9572
0
  return status;
9573
0
}
9574
9575
int
9576
ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9577
0
{
9578
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9579
9580
0
  char *xp = (char *) *xpp;
9581
0
  int status = NC_NOERR;
9582
9583
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9584
0
  {
9585
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9586
0
    if (status == NC_NOERR) /* report the first encountered error */
9587
0
      status = lstatus;
9588
0
  }
9589
9590
0
  if (rndup != 0)
9591
0
  {
9592
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9593
0
    xp += X_SIZEOF_SHORT;
9594
0
  }
9595
9596
0
  *xpp = (void *)xp;
9597
0
  return status;
9598
0
}
9599
9600
9601
9602
/* ushort --------------------------------------------------------------------*/
9603
9604
#if X_SIZEOF_USHORT == SIZEOF_USHORT
9605
/* optimized version */
9606
int
9607
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
9608
0
{
9609
#ifdef WORDS_BIGENDIAN
9610
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
9611
# else
9612
0
  swapn2b(tp, *xpp, nelems);
9613
0
# endif
9614
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
9615
0
  return NC_NOERR;
9616
0
}
9617
#else
9618
int
9619
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
9620
{
9621
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9622
9623
 /* basic algorithm is:
9624
  *   - ensure sane alignment of input data
9625
  *   - copy (conversion happens automatically) input data
9626
  *     to output
9627
  *   - update xpp to point at next unconverted input, and tp to point
9628
  *     at next location for converted output
9629
  */
9630
  long i, j, ni;
9631
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9632
  ushort *xp;
9633
  int nrange = 0;         /* number of range errors */
9634
  int realign = 0;        /* "do we need to fix input data alignment?" */
9635
  long cxp = (long) *((char**)xpp);
9636
9637
  realign = (cxp & 7) % SIZEOF_USHORT;
9638
  /* sjl: manually stripmine so we can limit amount of
9639
   * vector work space reserved to LOOPCNT elements. Also
9640
   * makes vectorisation easy */
9641
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9642
    ni=Min(nelems-j,LOOPCNT);
9643
    if (realign) {
9644
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9645
      xp = tmp;
9646
    } else {
9647
      xp = (ushort *) *xpp;
9648
    }
9649
   /* copy the next block */
9650
#pragma cdir loopcnt=LOOPCNT
9651
#pragma cdir shortloop
9652
    for (i=0; i<ni; i++) {
9653
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
9654
     /* test for range errors (not always needed but do it anyway) */
9655
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9656
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9657
      nrange += xp[i] > USHORT_MAX ;
9658
    }
9659
   /* update xpp and tp */
9660
    if (realign) xp = (ushort *) *xpp;
9661
    xp += ni;
9662
    tp += ni;
9663
    *xpp = (void*)xp;
9664
  }
9665
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9666
9667
#else   /* not SX */
9668
  const char *xp = (const char *) *xpp;
9669
  int status = NC_NOERR;
9670
9671
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9672
  {
9673
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
9674
    if (status == NC_NOERR) /* report the first encountered error */
9675
      status = lstatus;
9676
  }
9677
9678
  *xpp = (const void *)xp;
9679
  return status;
9680
#endif
9681
}
9682
9683
#endif
9684
int
9685
ncx_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
9686
0
{
9687
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9688
9689
 /* basic algorithm is:
9690
  *   - ensure sane alignment of input data
9691
  *   - copy (conversion happens automatically) input data
9692
  *     to output
9693
  *   - update xpp to point at next unconverted input, and tp to point
9694
  *     at next location for converted output
9695
  */
9696
  long i, j, ni;
9697
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9698
  ushort *xp;
9699
  int nrange = 0;         /* number of range errors */
9700
  int realign = 0;        /* "do we need to fix input data alignment?" */
9701
  long cxp = (long) *((char**)xpp);
9702
9703
  realign = (cxp & 7) % SIZEOF_USHORT;
9704
  /* sjl: manually stripmine so we can limit amount of
9705
   * vector work space reserved to LOOPCNT elements. Also
9706
   * makes vectorisation easy */
9707
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9708
    ni=Min(nelems-j,LOOPCNT);
9709
    if (realign) {
9710
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9711
      xp = tmp;
9712
    } else {
9713
      xp = (ushort *) *xpp;
9714
    }
9715
   /* copy the next block */
9716
#pragma cdir loopcnt=LOOPCNT
9717
#pragma cdir shortloop
9718
    for (i=0; i<ni; i++) {
9719
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
9720
     /* test for range errors (not always needed but do it anyway) */
9721
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9722
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9723
      nrange += xp[i] > SCHAR_MAX ;
9724
    }
9725
   /* update xpp and tp */
9726
    if (realign) xp = (ushort *) *xpp;
9727
    xp += ni;
9728
    tp += ni;
9729
    *xpp = (void*)xp;
9730
  }
9731
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9732
9733
#else   /* not SX */
9734
0
  const char *xp = (const char *) *xpp;
9735
0
  int status = NC_NOERR;
9736
9737
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9738
0
  {
9739
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
9740
0
    if (status == NC_NOERR) /* report the first encountered error */
9741
0
      status = lstatus;
9742
0
  }
9743
9744
0
  *xpp = (const void *)xp;
9745
0
  return status;
9746
0
#endif
9747
0
}
9748
9749
int
9750
ncx_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
9751
0
{
9752
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9753
9754
 /* basic algorithm is:
9755
  *   - ensure sane alignment of input data
9756
  *   - copy (conversion happens automatically) input data
9757
  *     to output
9758
  *   - update xpp to point at next unconverted input, and tp to point
9759
  *     at next location for converted output
9760
  */
9761
  long i, j, ni;
9762
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9763
  ushort *xp;
9764
  int nrange = 0;         /* number of range errors */
9765
  int realign = 0;        /* "do we need to fix input data alignment?" */
9766
  long cxp = (long) *((char**)xpp);
9767
9768
  realign = (cxp & 7) % SIZEOF_USHORT;
9769
  /* sjl: manually stripmine so we can limit amount of
9770
   * vector work space reserved to LOOPCNT elements. Also
9771
   * makes vectorisation easy */
9772
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9773
    ni=Min(nelems-j,LOOPCNT);
9774
    if (realign) {
9775
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9776
      xp = tmp;
9777
    } else {
9778
      xp = (ushort *) *xpp;
9779
    }
9780
   /* copy the next block */
9781
#pragma cdir loopcnt=LOOPCNT
9782
#pragma cdir shortloop
9783
    for (i=0; i<ni; i++) {
9784
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
9785
     /* test for range errors (not always needed but do it anyway) */
9786
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9787
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9788
      nrange += xp[i] > SHORT_MAX ;
9789
    }
9790
   /* update xpp and tp */
9791
    if (realign) xp = (ushort *) *xpp;
9792
    xp += ni;
9793
    tp += ni;
9794
    *xpp = (void*)xp;
9795
  }
9796
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9797
9798
#else   /* not SX */
9799
0
  const char *xp = (const char *) *xpp;
9800
0
  int status = NC_NOERR;
9801
9802
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9803
0
  {
9804
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
9805
0
    if (status == NC_NOERR) /* report the first encountered error */
9806
0
      status = lstatus;
9807
0
  }
9808
9809
0
  *xpp = (const void *)xp;
9810
0
  return status;
9811
0
#endif
9812
0
}
9813
9814
int
9815
ncx_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
9816
0
{
9817
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9818
9819
 /* basic algorithm is:
9820
  *   - ensure sane alignment of input data
9821
  *   - copy (conversion happens automatically) input data
9822
  *     to output
9823
  *   - update xpp to point at next unconverted input, and tp to point
9824
  *     at next location for converted output
9825
  */
9826
  long i, j, ni;
9827
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9828
  ushort *xp;
9829
  int nrange = 0;         /* number of range errors */
9830
  int realign = 0;        /* "do we need to fix input data alignment?" */
9831
  long cxp = (long) *((char**)xpp);
9832
9833
  realign = (cxp & 7) % SIZEOF_USHORT;
9834
  /* sjl: manually stripmine so we can limit amount of
9835
   * vector work space reserved to LOOPCNT elements. Also
9836
   * makes vectorisation easy */
9837
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9838
    ni=Min(nelems-j,LOOPCNT);
9839
    if (realign) {
9840
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9841
      xp = tmp;
9842
    } else {
9843
      xp = (ushort *) *xpp;
9844
    }
9845
   /* copy the next block */
9846
#pragma cdir loopcnt=LOOPCNT
9847
#pragma cdir shortloop
9848
    for (i=0; i<ni; i++) {
9849
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
9850
     /* test for range errors (not always needed but do it anyway) */
9851
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9852
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9853
      nrange += xp[i] > INT_MAX ;
9854
    }
9855
   /* update xpp and tp */
9856
    if (realign) xp = (ushort *) *xpp;
9857
    xp += ni;
9858
    tp += ni;
9859
    *xpp = (void*)xp;
9860
  }
9861
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9862
9863
#else   /* not SX */
9864
0
  const char *xp = (const char *) *xpp;
9865
0
  int status = NC_NOERR;
9866
9867
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9868
0
  {
9869
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
9870
0
    if (status == NC_NOERR) /* report the first encountered error */
9871
0
      status = lstatus;
9872
0
  }
9873
9874
0
  *xpp = (const void *)xp;
9875
0
  return status;
9876
0
#endif
9877
0
}
9878
9879
int
9880
ncx_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
9881
0
{
9882
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9883
9884
 /* basic algorithm is:
9885
  *   - ensure sane alignment of input data
9886
  *   - copy (conversion happens automatically) input data
9887
  *     to output
9888
  *   - update xpp to point at next unconverted input, and tp to point
9889
  *     at next location for converted output
9890
  */
9891
  long i, j, ni;
9892
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9893
  ushort *xp;
9894
  int nrange = 0;         /* number of range errors */
9895
  int realign = 0;        /* "do we need to fix input data alignment?" */
9896
  long cxp = (long) *((char**)xpp);
9897
9898
  realign = (cxp & 7) % SIZEOF_USHORT;
9899
  /* sjl: manually stripmine so we can limit amount of
9900
   * vector work space reserved to LOOPCNT elements. Also
9901
   * makes vectorisation easy */
9902
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9903
    ni=Min(nelems-j,LOOPCNT);
9904
    if (realign) {
9905
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9906
      xp = tmp;
9907
    } else {
9908
      xp = (ushort *) *xpp;
9909
    }
9910
   /* copy the next block */
9911
#pragma cdir loopcnt=LOOPCNT
9912
#pragma cdir shortloop
9913
    for (i=0; i<ni; i++) {
9914
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
9915
     /* test for range errors (not always needed but do it anyway) */
9916
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9917
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9918
      nrange += xp[i] > LONG_MAX ;
9919
    }
9920
   /* update xpp and tp */
9921
    if (realign) xp = (ushort *) *xpp;
9922
    xp += ni;
9923
    tp += ni;
9924
    *xpp = (void*)xp;
9925
  }
9926
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9927
9928
#else   /* not SX */
9929
0
  const char *xp = (const char *) *xpp;
9930
0
  int status = NC_NOERR;
9931
9932
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9933
0
  {
9934
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
9935
0
    if (status == NC_NOERR) /* report the first encountered error */
9936
0
      status = lstatus;
9937
0
  }
9938
9939
0
  *xpp = (const void *)xp;
9940
0
  return status;
9941
0
#endif
9942
0
}
9943
9944
int
9945
ncx_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
9946
0
{
9947
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9948
9949
 /* basic algorithm is:
9950
  *   - ensure sane alignment of input data
9951
  *   - copy (conversion happens automatically) input data
9952
  *     to output
9953
  *   - update xpp to point at next unconverted input, and tp to point
9954
  *     at next location for converted output
9955
  */
9956
  long i, j, ni;
9957
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9958
  ushort *xp;
9959
  int nrange = 0;         /* number of range errors */
9960
  int realign = 0;        /* "do we need to fix input data alignment?" */
9961
  long cxp = (long) *((char**)xpp);
9962
9963
  realign = (cxp & 7) % SIZEOF_USHORT;
9964
  /* sjl: manually stripmine so we can limit amount of
9965
   * vector work space reserved to LOOPCNT elements. Also
9966
   * makes vectorisation easy */
9967
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9968
    ni=Min(nelems-j,LOOPCNT);
9969
    if (realign) {
9970
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9971
      xp = tmp;
9972
    } else {
9973
      xp = (ushort *) *xpp;
9974
    }
9975
   /* copy the next block */
9976
#pragma cdir loopcnt=LOOPCNT
9977
#pragma cdir shortloop
9978
    for (i=0; i<ni; i++) {
9979
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
9980
     /* test for range errors (not always needed but do it anyway) */
9981
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9982
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9983
      nrange += xp[i] > FLOAT_MAX ;
9984
    }
9985
   /* update xpp and tp */
9986
    if (realign) xp = (ushort *) *xpp;
9987
    xp += ni;
9988
    tp += ni;
9989
    *xpp = (void*)xp;
9990
  }
9991
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9992
9993
#else   /* not SX */
9994
0
  const char *xp = (const char *) *xpp;
9995
0
  int status = NC_NOERR;
9996
9997
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9998
0
  {
9999
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10000
0
    if (status == NC_NOERR) /* report the first encountered error */
10001
0
      status = lstatus;
10002
0
  }
10003
10004
0
  *xpp = (const void *)xp;
10005
0
  return status;
10006
0
#endif
10007
0
}
10008
10009
int
10010
ncx_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10011
0
{
10012
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10013
10014
 /* basic algorithm is:
10015
  *   - ensure sane alignment of input data
10016
  *   - copy (conversion happens automatically) input data
10017
  *     to output
10018
  *   - update xpp to point at next unconverted input, and tp to point
10019
  *     at next location for converted output
10020
  */
10021
  long i, j, ni;
10022
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10023
  ushort *xp;
10024
  int nrange = 0;         /* number of range errors */
10025
  int realign = 0;        /* "do we need to fix input data alignment?" */
10026
  long cxp = (long) *((char**)xpp);
10027
10028
  realign = (cxp & 7) % SIZEOF_USHORT;
10029
  /* sjl: manually stripmine so we can limit amount of
10030
   * vector work space reserved to LOOPCNT elements. Also
10031
   * makes vectorisation easy */
10032
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10033
    ni=Min(nelems-j,LOOPCNT);
10034
    if (realign) {
10035
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10036
      xp = tmp;
10037
    } else {
10038
      xp = (ushort *) *xpp;
10039
    }
10040
   /* copy the next block */
10041
#pragma cdir loopcnt=LOOPCNT
10042
#pragma cdir shortloop
10043
    for (i=0; i<ni; i++) {
10044
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
10045
     /* test for range errors (not always needed but do it anyway) */
10046
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10047
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10048
      nrange += xp[i] > DOUBLE_MAX ;
10049
    }
10050
   /* update xpp and tp */
10051
    if (realign) xp = (ushort *) *xpp;
10052
    xp += ni;
10053
    tp += ni;
10054
    *xpp = (void*)xp;
10055
  }
10056
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10057
10058
#else   /* not SX */
10059
0
  const char *xp = (const char *) *xpp;
10060
0
  int status = NC_NOERR;
10061
10062
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10063
0
  {
10064
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10065
0
    if (status == NC_NOERR) /* report the first encountered error */
10066
0
      status = lstatus;
10067
0
  }
10068
10069
0
  *xpp = (const void *)xp;
10070
0
  return status;
10071
0
#endif
10072
0
}
10073
10074
int
10075
ncx_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10076
0
{
10077
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10078
10079
 /* basic algorithm is:
10080
  *   - ensure sane alignment of input data
10081
  *   - copy (conversion happens automatically) input data
10082
  *     to output
10083
  *   - update xpp to point at next unconverted input, and tp to point
10084
  *     at next location for converted output
10085
  */
10086
  long i, j, ni;
10087
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10088
  ushort *xp;
10089
  int nrange = 0;         /* number of range errors */
10090
  int realign = 0;        /* "do we need to fix input data alignment?" */
10091
  long cxp = (long) *((char**)xpp);
10092
10093
  realign = (cxp & 7) % SIZEOF_USHORT;
10094
  /* sjl: manually stripmine so we can limit amount of
10095
   * vector work space reserved to LOOPCNT elements. Also
10096
   * makes vectorisation easy */
10097
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10098
    ni=Min(nelems-j,LOOPCNT);
10099
    if (realign) {
10100
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10101
      xp = tmp;
10102
    } else {
10103
      xp = (ushort *) *xpp;
10104
    }
10105
   /* copy the next block */
10106
#pragma cdir loopcnt=LOOPCNT
10107
#pragma cdir shortloop
10108
    for (i=0; i<ni; i++) {
10109
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
10110
     /* test for range errors (not always needed but do it anyway) */
10111
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10112
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10113
      nrange += xp[i] > LONGLONG_MAX ;
10114
    }
10115
   /* update xpp and tp */
10116
    if (realign) xp = (ushort *) *xpp;
10117
    xp += ni;
10118
    tp += ni;
10119
    *xpp = (void*)xp;
10120
  }
10121
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10122
10123
#else   /* not SX */
10124
0
  const char *xp = (const char *) *xpp;
10125
0
  int status = NC_NOERR;
10126
10127
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10128
0
  {
10129
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10130
0
    if (status == NC_NOERR) /* report the first encountered error */
10131
0
      status = lstatus;
10132
0
  }
10133
10134
0
  *xpp = (const void *)xp;
10135
0
  return status;
10136
0
#endif
10137
0
}
10138
10139
int
10140
ncx_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10141
0
{
10142
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10143
10144
 /* basic algorithm is:
10145
  *   - ensure sane alignment of input data
10146
  *   - copy (conversion happens automatically) input data
10147
  *     to output
10148
  *   - update xpp to point at next unconverted input, and tp to point
10149
  *     at next location for converted output
10150
  */
10151
  long i, j, ni;
10152
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10153
  ushort *xp;
10154
  int nrange = 0;         /* number of range errors */
10155
  int realign = 0;        /* "do we need to fix input data alignment?" */
10156
  long cxp = (long) *((char**)xpp);
10157
10158
  realign = (cxp & 7) % SIZEOF_USHORT;
10159
  /* sjl: manually stripmine so we can limit amount of
10160
   * vector work space reserved to LOOPCNT elements. Also
10161
   * makes vectorisation easy */
10162
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10163
    ni=Min(nelems-j,LOOPCNT);
10164
    if (realign) {
10165
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10166
      xp = tmp;
10167
    } else {
10168
      xp = (ushort *) *xpp;
10169
    }
10170
   /* copy the next block */
10171
#pragma cdir loopcnt=LOOPCNT
10172
#pragma cdir shortloop
10173
    for (i=0; i<ni; i++) {
10174
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
10175
     /* test for range errors (not always needed but do it anyway) */
10176
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10177
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10178
      nrange += xp[i] > UCHAR_MAX ;
10179
    }
10180
   /* update xpp and tp */
10181
    if (realign) xp = (ushort *) *xpp;
10182
    xp += ni;
10183
    tp += ni;
10184
    *xpp = (void*)xp;
10185
  }
10186
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10187
10188
#else   /* not SX */
10189
0
  const char *xp = (const char *) *xpp;
10190
0
  int status = NC_NOERR;
10191
10192
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10193
0
  {
10194
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10195
0
    if (status == NC_NOERR) /* report the first encountered error */
10196
0
      status = lstatus;
10197
0
  }
10198
10199
0
  *xpp = (const void *)xp;
10200
0
  return status;
10201
0
#endif
10202
0
}
10203
10204
int
10205
ncx_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10206
0
{
10207
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10208
10209
 /* basic algorithm is:
10210
  *   - ensure sane alignment of input data
10211
  *   - copy (conversion happens automatically) input data
10212
  *     to output
10213
  *   - update xpp to point at next unconverted input, and tp to point
10214
  *     at next location for converted output
10215
  */
10216
  long i, j, ni;
10217
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10218
  ushort *xp;
10219
  int nrange = 0;         /* number of range errors */
10220
  int realign = 0;        /* "do we need to fix input data alignment?" */
10221
  long cxp = (long) *((char**)xpp);
10222
10223
  realign = (cxp & 7) % SIZEOF_USHORT;
10224
  /* sjl: manually stripmine so we can limit amount of
10225
   * vector work space reserved to LOOPCNT elements. Also
10226
   * makes vectorisation easy */
10227
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10228
    ni=Min(nelems-j,LOOPCNT);
10229
    if (realign) {
10230
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10231
      xp = tmp;
10232
    } else {
10233
      xp = (ushort *) *xpp;
10234
    }
10235
   /* copy the next block */
10236
#pragma cdir loopcnt=LOOPCNT
10237
#pragma cdir shortloop
10238
    for (i=0; i<ni; i++) {
10239
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
10240
     /* test for range errors (not always needed but do it anyway) */
10241
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10242
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10243
      nrange += xp[i] > UINT_MAX ;
10244
    }
10245
   /* update xpp and tp */
10246
    if (realign) xp = (ushort *) *xpp;
10247
    xp += ni;
10248
    tp += ni;
10249
    *xpp = (void*)xp;
10250
  }
10251
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10252
10253
#else   /* not SX */
10254
0
  const char *xp = (const char *) *xpp;
10255
0
  int status = NC_NOERR;
10256
10257
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10258
0
  {
10259
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10260
0
    if (status == NC_NOERR) /* report the first encountered error */
10261
0
      status = lstatus;
10262
0
  }
10263
10264
0
  *xpp = (const void *)xp;
10265
0
  return status;
10266
0
#endif
10267
0
}
10268
10269
int
10270
ncx_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10271
0
{
10272
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10273
10274
 /* basic algorithm is:
10275
  *   - ensure sane alignment of input data
10276
  *   - copy (conversion happens automatically) input data
10277
  *     to output
10278
  *   - update xpp to point at next unconverted input, and tp to point
10279
  *     at next location for converted output
10280
  */
10281
  long i, j, ni;
10282
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10283
  ushort *xp;
10284
  int nrange = 0;         /* number of range errors */
10285
  int realign = 0;        /* "do we need to fix input data alignment?" */
10286
  long cxp = (long) *((char**)xpp);
10287
10288
  realign = (cxp & 7) % SIZEOF_USHORT;
10289
  /* sjl: manually stripmine so we can limit amount of
10290
   * vector work space reserved to LOOPCNT elements. Also
10291
   * makes vectorisation easy */
10292
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10293
    ni=Min(nelems-j,LOOPCNT);
10294
    if (realign) {
10295
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10296
      xp = tmp;
10297
    } else {
10298
      xp = (ushort *) *xpp;
10299
    }
10300
   /* copy the next block */
10301
#pragma cdir loopcnt=LOOPCNT
10302
#pragma cdir shortloop
10303
    for (i=0; i<ni; i++) {
10304
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
10305
     /* test for range errors (not always needed but do it anyway) */
10306
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10307
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10308
      nrange += xp[i] > ULONGLONG_MAX ;
10309
    }
10310
   /* update xpp and tp */
10311
    if (realign) xp = (ushort *) *xpp;
10312
    xp += ni;
10313
    tp += ni;
10314
    *xpp = (void*)xp;
10315
  }
10316
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10317
10318
#else   /* not SX */
10319
0
  const char *xp = (const char *) *xpp;
10320
0
  int status = NC_NOERR;
10321
10322
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10323
0
  {
10324
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10325
0
    if (status == NC_NOERR) /* report the first encountered error */
10326
0
      status = lstatus;
10327
0
  }
10328
10329
0
  *xpp = (const void *)xp;
10330
0
  return status;
10331
0
#endif
10332
0
}
10333
10334
10335
int
10336
ncx_pad_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
10337
0
{
10338
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10339
10340
0
  const char *xp = (const char *) *xpp;
10341
0
  int status = NC_NOERR;
10342
10343
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10344
0
  {
10345
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
10346
0
    if (status == NC_NOERR) /* report the first encountered error */
10347
0
      status = lstatus;
10348
0
  }
10349
10350
0
  if (rndup != 0)
10351
0
    xp += X_SIZEOF_USHORT;
10352
10353
0
  *xpp = (void *)xp;
10354
0
  return status;
10355
0
}
10356
10357
int
10358
ncx_pad_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
10359
0
{
10360
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10361
10362
0
  const char *xp = (const char *) *xpp;
10363
0
  int status = NC_NOERR;
10364
10365
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10366
0
  {
10367
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
10368
0
    if (status == NC_NOERR) /* report the first encountered error */
10369
0
      status = lstatus;
10370
0
  }
10371
10372
0
  if (rndup != 0)
10373
0
    xp += X_SIZEOF_USHORT;
10374
10375
0
  *xpp = (void *)xp;
10376
0
  return status;
10377
0
}
10378
10379
int
10380
ncx_pad_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10381
0
{
10382
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10383
10384
0
  const char *xp = (const char *) *xpp;
10385
0
  int status = NC_NOERR;
10386
10387
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10388
0
  {
10389
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
10390
0
    if (status == NC_NOERR) /* report the first encountered error */
10391
0
      status = lstatus;
10392
0
  }
10393
10394
0
  if (rndup != 0)
10395
0
    xp += X_SIZEOF_USHORT;
10396
10397
0
  *xpp = (void *)xp;
10398
0
  return status;
10399
0
}
10400
10401
int
10402
ncx_pad_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10403
0
{
10404
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10405
10406
0
  const char *xp = (const char *) *xpp;
10407
0
  int status = NC_NOERR;
10408
10409
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10410
0
  {
10411
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
10412
0
    if (status == NC_NOERR) /* report the first encountered error */
10413
0
      status = lstatus;
10414
0
  }
10415
10416
0
  if (rndup != 0)
10417
0
    xp += X_SIZEOF_USHORT;
10418
10419
0
  *xpp = (void *)xp;
10420
0
  return status;
10421
0
}
10422
10423
int
10424
ncx_pad_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10425
0
{
10426
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10427
10428
0
  const char *xp = (const char *) *xpp;
10429
0
  int status = NC_NOERR;
10430
10431
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10432
0
  {
10433
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10434
0
    if (status == NC_NOERR) /* report the first encountered error */
10435
0
      status = lstatus;
10436
0
  }
10437
10438
0
  if (rndup != 0)
10439
0
    xp += X_SIZEOF_USHORT;
10440
10441
0
  *xpp = (void *)xp;
10442
0
  return status;
10443
0
}
10444
10445
int
10446
ncx_pad_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10447
0
{
10448
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10449
10450
0
  const char *xp = (const char *) *xpp;
10451
0
  int status = NC_NOERR;
10452
10453
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10454
0
  {
10455
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10456
0
    if (status == NC_NOERR) /* report the first encountered error */
10457
0
      status = lstatus;
10458
0
  }
10459
10460
0
  if (rndup != 0)
10461
0
    xp += X_SIZEOF_USHORT;
10462
10463
0
  *xpp = (void *)xp;
10464
0
  return status;
10465
0
}
10466
10467
int
10468
ncx_pad_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10469
0
{
10470
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10471
10472
0
  const char *xp = (const char *) *xpp;
10473
0
  int status = NC_NOERR;
10474
10475
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10476
0
  {
10477
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10478
0
    if (status == NC_NOERR) /* report the first encountered error */
10479
0
      status = lstatus;
10480
0
  }
10481
10482
0
  if (rndup != 0)
10483
0
    xp += X_SIZEOF_USHORT;
10484
10485
0
  *xpp = (void *)xp;
10486
0
  return status;
10487
0
}
10488
10489
int
10490
ncx_pad_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
10491
0
{
10492
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10493
10494
0
  const char *xp = (const char *) *xpp;
10495
0
  int status = NC_NOERR;
10496
10497
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10498
0
  {
10499
0
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
10500
0
    if (status == NC_NOERR) /* report the first encountered error */
10501
0
      status = lstatus;
10502
0
  }
10503
10504
0
  if (rndup != 0)
10505
0
    xp += X_SIZEOF_USHORT;
10506
10507
0
  *xpp = (void *)xp;
10508
0
  return status;
10509
0
}
10510
10511
int
10512
ncx_pad_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10513
0
{
10514
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10515
10516
0
  const char *xp = (const char *) *xpp;
10517
0
  int status = NC_NOERR;
10518
10519
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10520
0
  {
10521
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10522
0
    if (status == NC_NOERR) /* report the first encountered error */
10523
0
      status = lstatus;
10524
0
  }
10525
10526
0
  if (rndup != 0)
10527
0
    xp += X_SIZEOF_USHORT;
10528
10529
0
  *xpp = (void *)xp;
10530
0
  return status;
10531
0
}
10532
10533
int
10534
ncx_pad_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10535
0
{
10536
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10537
10538
0
  const char *xp = (const char *) *xpp;
10539
0
  int status = NC_NOERR;
10540
10541
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10542
0
  {
10543
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10544
0
    if (status == NC_NOERR) /* report the first encountered error */
10545
0
      status = lstatus;
10546
0
  }
10547
10548
0
  if (rndup != 0)
10549
0
    xp += X_SIZEOF_USHORT;
10550
10551
0
  *xpp = (void *)xp;
10552
0
  return status;
10553
0
}
10554
10555
int
10556
ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10557
0
{
10558
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10559
10560
0
  const char *xp = (const char *) *xpp;
10561
0
  int status = NC_NOERR;
10562
10563
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10564
0
  {
10565
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10566
0
    if (status == NC_NOERR) /* report the first encountered error */
10567
0
      status = lstatus;
10568
0
  }
10569
10570
0
  if (rndup != 0)
10571
0
    xp += X_SIZEOF_USHORT;
10572
10573
0
  *xpp = (void *)xp;
10574
0
  return status;
10575
0
}
10576
10577
10578
#if X_SIZEOF_USHORT == SIZEOF_USHORT
10579
/* optimized version */
10580
int
10581
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp, void *fillp)
10582
0
{
10583
#ifdef WORDS_BIGENDIAN
10584
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
10585
# else
10586
0
  swapn2b(*xpp, tp, nelems);
10587
0
# endif
10588
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
10589
0
  return NC_NOERR;
10590
0
}
10591
#else
10592
int
10593
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
10594
{
10595
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10596
10597
 /* basic algorithm is:
10598
  *   - ensure sane alignment of output data
10599
  *   - copy (conversion happens automatically) input data
10600
  *     to output
10601
  *   - update tp to point at next unconverted input, and xpp to point
10602
  *     at next location for converted output
10603
  */
10604
  long i, j, ni;
10605
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10606
  ushort *xp;
10607
  int nrange = 0;         /* number of range errors */
10608
  int realign = 0;        /* "do we need to fix input data alignment?" */
10609
  long cxp = (long) *((char**)xpp);
10610
10611
  realign = (cxp & 7) % SIZEOF_USHORT;
10612
  /* sjl: manually stripmine so we can limit amount of
10613
   * vector work space reserved to LOOPCNT elements. Also
10614
   * makes vectorisation easy */
10615
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10616
    ni=Min(nelems-j,LOOPCNT);
10617
    if (realign) {
10618
      xp = tmp;
10619
    } else {
10620
      xp = (ushort *) *xpp;
10621
    }
10622
   /* copy the next block */
10623
#pragma cdir loopcnt=LOOPCNT
10624
#pragma cdir shortloop
10625
    for (i=0; i<ni; i++) {
10626
      /* the normal case: */
10627
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10628
     /* test for range errors (not always needed but do it anyway) */
10629
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10630
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10631
      nrange += tp[i] > X_USHORT_MAX ;
10632
    }
10633
   /* copy workspace back if necessary */
10634
    if (realign) {
10635
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10636
      xp = (ushort *) *xpp;
10637
    }
10638
   /* update xpp and tp */
10639
    xp += ni;
10640
    tp += ni;
10641
    *xpp = (void*)xp;
10642
  }
10643
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10644
10645
#else   /* not SX */
10646
10647
  char *xp = (char *) *xpp;
10648
  int status = NC_NOERR;
10649
10650
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10651
  {
10652
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
10653
    if (status == NC_NOERR) /* report the first encountered error */
10654
      status = lstatus;
10655
  }
10656
10657
  *xpp = (void *)xp;
10658
  return status;
10659
#endif
10660
}
10661
10662
#endif
10663
int
10664
ncx_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
10665
0
{
10666
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10667
10668
 /* basic algorithm is:
10669
  *   - ensure sane alignment of output data
10670
  *   - copy (conversion happens automatically) input data
10671
  *     to output
10672
  *   - update tp to point at next unconverted input, and xpp to point
10673
  *     at next location for converted output
10674
  */
10675
  long i, j, ni;
10676
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10677
  ushort *xp;
10678
  int nrange = 0;         /* number of range errors */
10679
  int realign = 0;        /* "do we need to fix input data alignment?" */
10680
  long cxp = (long) *((char**)xpp);
10681
10682
  realign = (cxp & 7) % SIZEOF_USHORT;
10683
  /* sjl: manually stripmine so we can limit amount of
10684
   * vector work space reserved to LOOPCNT elements. Also
10685
   * makes vectorisation easy */
10686
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10687
    ni=Min(nelems-j,LOOPCNT);
10688
    if (realign) {
10689
      xp = tmp;
10690
    } else {
10691
      xp = (ushort *) *xpp;
10692
    }
10693
   /* copy the next block */
10694
#pragma cdir loopcnt=LOOPCNT
10695
#pragma cdir shortloop
10696
    for (i=0; i<ni; i++) {
10697
      /* the normal case: */
10698
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10699
     /* test for range errors (not always needed but do it anyway) */
10700
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10701
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10702
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10703
    }
10704
   /* copy workspace back if necessary */
10705
    if (realign) {
10706
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10707
      xp = (ushort *) *xpp;
10708
    }
10709
   /* update xpp and tp */
10710
    xp += ni;
10711
    tp += ni;
10712
    *xpp = (void*)xp;
10713
  }
10714
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10715
10716
#else   /* not SX */
10717
10718
0
  char *xp = (char *) *xpp;
10719
0
  int status = NC_NOERR;
10720
10721
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10722
0
  {
10723
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
10724
0
    if (status == NC_NOERR) /* report the first encountered error */
10725
0
      status = lstatus;
10726
0
  }
10727
10728
0
  *xpp = (void *)xp;
10729
0
  return status;
10730
0
#endif
10731
0
}
10732
10733
int
10734
ncx_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
10735
0
{
10736
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10737
10738
 /* basic algorithm is:
10739
  *   - ensure sane alignment of output data
10740
  *   - copy (conversion happens automatically) input data
10741
  *     to output
10742
  *   - update tp to point at next unconverted input, and xpp to point
10743
  *     at next location for converted output
10744
  */
10745
  long i, j, ni;
10746
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10747
  ushort *xp;
10748
  int nrange = 0;         /* number of range errors */
10749
  int realign = 0;        /* "do we need to fix input data alignment?" */
10750
  long cxp = (long) *((char**)xpp);
10751
10752
  realign = (cxp & 7) % SIZEOF_USHORT;
10753
  /* sjl: manually stripmine so we can limit amount of
10754
   * vector work space reserved to LOOPCNT elements. Also
10755
   * makes vectorisation easy */
10756
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10757
    ni=Min(nelems-j,LOOPCNT);
10758
    if (realign) {
10759
      xp = tmp;
10760
    } else {
10761
      xp = (ushort *) *xpp;
10762
    }
10763
   /* copy the next block */
10764
#pragma cdir loopcnt=LOOPCNT
10765
#pragma cdir shortloop
10766
    for (i=0; i<ni; i++) {
10767
      /* the normal case: */
10768
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10769
     /* test for range errors (not always needed but do it anyway) */
10770
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10771
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10772
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10773
    }
10774
   /* copy workspace back if necessary */
10775
    if (realign) {
10776
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10777
      xp = (ushort *) *xpp;
10778
    }
10779
   /* update xpp and tp */
10780
    xp += ni;
10781
    tp += ni;
10782
    *xpp = (void*)xp;
10783
  }
10784
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10785
10786
#else   /* not SX */
10787
10788
0
  char *xp = (char *) *xpp;
10789
0
  int status = NC_NOERR;
10790
10791
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10792
0
  {
10793
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
10794
0
    if (status == NC_NOERR) /* report the first encountered error */
10795
0
      status = lstatus;
10796
0
  }
10797
10798
0
  *xpp = (void *)xp;
10799
0
  return status;
10800
0
#endif
10801
0
}
10802
10803
int
10804
ncx_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
10805
0
{
10806
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10807
10808
 /* basic algorithm is:
10809
  *   - ensure sane alignment of output data
10810
  *   - copy (conversion happens automatically) input data
10811
  *     to output
10812
  *   - update tp to point at next unconverted input, and xpp to point
10813
  *     at next location for converted output
10814
  */
10815
  long i, j, ni;
10816
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10817
  ushort *xp;
10818
  int nrange = 0;         /* number of range errors */
10819
  int realign = 0;        /* "do we need to fix input data alignment?" */
10820
  long cxp = (long) *((char**)xpp);
10821
10822
  realign = (cxp & 7) % SIZEOF_USHORT;
10823
  /* sjl: manually stripmine so we can limit amount of
10824
   * vector work space reserved to LOOPCNT elements. Also
10825
   * makes vectorisation easy */
10826
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10827
    ni=Min(nelems-j,LOOPCNT);
10828
    if (realign) {
10829
      xp = tmp;
10830
    } else {
10831
      xp = (ushort *) *xpp;
10832
    }
10833
   /* copy the next block */
10834
#pragma cdir loopcnt=LOOPCNT
10835
#pragma cdir shortloop
10836
    for (i=0; i<ni; i++) {
10837
      /* the normal case: */
10838
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10839
     /* test for range errors (not always needed but do it anyway) */
10840
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10841
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10842
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10843
    }
10844
   /* copy workspace back if necessary */
10845
    if (realign) {
10846
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10847
      xp = (ushort *) *xpp;
10848
    }
10849
   /* update xpp and tp */
10850
    xp += ni;
10851
    tp += ni;
10852
    *xpp = (void*)xp;
10853
  }
10854
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10855
10856
#else   /* not SX */
10857
10858
0
  char *xp = (char *) *xpp;
10859
0
  int status = NC_NOERR;
10860
10861
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10862
0
  {
10863
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
10864
0
    if (status == NC_NOERR) /* report the first encountered error */
10865
0
      status = lstatus;
10866
0
  }
10867
10868
0
  *xpp = (void *)xp;
10869
0
  return status;
10870
0
#endif
10871
0
}
10872
10873
int
10874
ncx_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
10875
0
{
10876
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10877
10878
 /* basic algorithm is:
10879
  *   - ensure sane alignment of output data
10880
  *   - copy (conversion happens automatically) input data
10881
  *     to output
10882
  *   - update tp to point at next unconverted input, and xpp to point
10883
  *     at next location for converted output
10884
  */
10885
  long i, j, ni;
10886
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10887
  ushort *xp;
10888
  int nrange = 0;         /* number of range errors */
10889
  int realign = 0;        /* "do we need to fix input data alignment?" */
10890
  long cxp = (long) *((char**)xpp);
10891
10892
  realign = (cxp & 7) % SIZEOF_USHORT;
10893
  /* sjl: manually stripmine so we can limit amount of
10894
   * vector work space reserved to LOOPCNT elements. Also
10895
   * makes vectorisation easy */
10896
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10897
    ni=Min(nelems-j,LOOPCNT);
10898
    if (realign) {
10899
      xp = tmp;
10900
    } else {
10901
      xp = (ushort *) *xpp;
10902
    }
10903
   /* copy the next block */
10904
#pragma cdir loopcnt=LOOPCNT
10905
#pragma cdir shortloop
10906
    for (i=0; i<ni; i++) {
10907
      /* the normal case: */
10908
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10909
     /* test for range errors (not always needed but do it anyway) */
10910
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10911
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10912
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10913
    }
10914
   /* copy workspace back if necessary */
10915
    if (realign) {
10916
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10917
      xp = (ushort *) *xpp;
10918
    }
10919
   /* update xpp and tp */
10920
    xp += ni;
10921
    tp += ni;
10922
    *xpp = (void*)xp;
10923
  }
10924
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10925
10926
#else   /* not SX */
10927
10928
0
  char *xp = (char *) *xpp;
10929
0
  int status = NC_NOERR;
10930
10931
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10932
0
  {
10933
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
10934
0
    if (status == NC_NOERR) /* report the first encountered error */
10935
0
      status = lstatus;
10936
0
  }
10937
10938
0
  *xpp = (void *)xp;
10939
0
  return status;
10940
0
#endif
10941
0
}
10942
10943
int
10944
ncx_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
10945
0
{
10946
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10947
10948
 /* basic algorithm is:
10949
  *   - ensure sane alignment of output data
10950
  *   - copy (conversion happens automatically) input data
10951
  *     to output
10952
  *   - update tp to point at next unconverted input, and xpp to point
10953
  *     at next location for converted output
10954
  */
10955
  long i, j, ni;
10956
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10957
  ushort *xp;
10958
  int nrange = 0;         /* number of range errors */
10959
  int realign = 0;        /* "do we need to fix input data alignment?" */
10960
  long cxp = (long) *((char**)xpp);
10961
10962
  realign = (cxp & 7) % SIZEOF_USHORT;
10963
  /* sjl: manually stripmine so we can limit amount of
10964
   * vector work space reserved to LOOPCNT elements. Also
10965
   * makes vectorisation easy */
10966
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10967
    ni=Min(nelems-j,LOOPCNT);
10968
    if (realign) {
10969
      xp = tmp;
10970
    } else {
10971
      xp = (ushort *) *xpp;
10972
    }
10973
   /* copy the next block */
10974
#pragma cdir loopcnt=LOOPCNT
10975
#pragma cdir shortloop
10976
    for (i=0; i<ni; i++) {
10977
      /* the normal case: */
10978
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10979
     /* test for range errors (not always needed but do it anyway) */
10980
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10981
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10982
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10983
    }
10984
   /* copy workspace back if necessary */
10985
    if (realign) {
10986
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10987
      xp = (ushort *) *xpp;
10988
    }
10989
   /* update xpp and tp */
10990
    xp += ni;
10991
    tp += ni;
10992
    *xpp = (void*)xp;
10993
  }
10994
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10995
10996
#else   /* not SX */
10997
10998
0
  char *xp = (char *) *xpp;
10999
0
  int status = NC_NOERR;
11000
11001
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11002
0
  {
11003
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11004
0
    if (status == NC_NOERR) /* report the first encountered error */
11005
0
      status = lstatus;
11006
0
  }
11007
11008
0
  *xpp = (void *)xp;
11009
0
  return status;
11010
0
#endif
11011
0
}
11012
11013
int
11014
ncx_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11015
0
{
11016
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11017
11018
 /* basic algorithm is:
11019
  *   - ensure sane alignment of output data
11020
  *   - copy (conversion happens automatically) input data
11021
  *     to output
11022
  *   - update tp to point at next unconverted input, and xpp to point
11023
  *     at next location for converted output
11024
  */
11025
  long i, j, ni;
11026
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11027
  ushort *xp;
11028
  int nrange = 0;         /* number of range errors */
11029
  int realign = 0;        /* "do we need to fix input data alignment?" */
11030
  long cxp = (long) *((char**)xpp);
11031
11032
  realign = (cxp & 7) % SIZEOF_USHORT;
11033
  /* sjl: manually stripmine so we can limit amount of
11034
   * vector work space reserved to LOOPCNT elements. Also
11035
   * makes vectorisation easy */
11036
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11037
    ni=Min(nelems-j,LOOPCNT);
11038
    if (realign) {
11039
      xp = tmp;
11040
    } else {
11041
      xp = (ushort *) *xpp;
11042
    }
11043
   /* copy the next block */
11044
#pragma cdir loopcnt=LOOPCNT
11045
#pragma cdir shortloop
11046
    for (i=0; i<ni; i++) {
11047
      /* the normal case: */
11048
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11049
     /* test for range errors (not always needed but do it anyway) */
11050
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11051
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11052
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11053
    }
11054
   /* copy workspace back if necessary */
11055
    if (realign) {
11056
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11057
      xp = (ushort *) *xpp;
11058
    }
11059
   /* update xpp and tp */
11060
    xp += ni;
11061
    tp += ni;
11062
    *xpp = (void*)xp;
11063
  }
11064
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11065
11066
#else   /* not SX */
11067
11068
0
  char *xp = (char *) *xpp;
11069
0
  int status = NC_NOERR;
11070
11071
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11072
0
  {
11073
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11074
0
    if (status == NC_NOERR) /* report the first encountered error */
11075
0
      status = lstatus;
11076
0
  }
11077
11078
0
  *xpp = (void *)xp;
11079
0
  return status;
11080
0
#endif
11081
0
}
11082
11083
int
11084
ncx_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11085
0
{
11086
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11087
11088
 /* basic algorithm is:
11089
  *   - ensure sane alignment of output data
11090
  *   - copy (conversion happens automatically) input data
11091
  *     to output
11092
  *   - update tp to point at next unconverted input, and xpp to point
11093
  *     at next location for converted output
11094
  */
11095
  long i, j, ni;
11096
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11097
  ushort *xp;
11098
  int nrange = 0;         /* number of range errors */
11099
  int realign = 0;        /* "do we need to fix input data alignment?" */
11100
  long cxp = (long) *((char**)xpp);
11101
11102
  realign = (cxp & 7) % SIZEOF_USHORT;
11103
  /* sjl: manually stripmine so we can limit amount of
11104
   * vector work space reserved to LOOPCNT elements. Also
11105
   * makes vectorisation easy */
11106
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11107
    ni=Min(nelems-j,LOOPCNT);
11108
    if (realign) {
11109
      xp = tmp;
11110
    } else {
11111
      xp = (ushort *) *xpp;
11112
    }
11113
   /* copy the next block */
11114
#pragma cdir loopcnt=LOOPCNT
11115
#pragma cdir shortloop
11116
    for (i=0; i<ni; i++) {
11117
      /* the normal case: */
11118
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11119
     /* test for range errors (not always needed but do it anyway) */
11120
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11121
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11122
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11123
    }
11124
   /* copy workspace back if necessary */
11125
    if (realign) {
11126
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11127
      xp = (ushort *) *xpp;
11128
    }
11129
   /* update xpp and tp */
11130
    xp += ni;
11131
    tp += ni;
11132
    *xpp = (void*)xp;
11133
  }
11134
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11135
11136
#else   /* not SX */
11137
11138
0
  char *xp = (char *) *xpp;
11139
0
  int status = NC_NOERR;
11140
11141
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11142
0
  {
11143
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11144
0
    if (status == NC_NOERR) /* report the first encountered error */
11145
0
      status = lstatus;
11146
0
  }
11147
11148
0
  *xpp = (void *)xp;
11149
0
  return status;
11150
0
#endif
11151
0
}
11152
11153
int
11154
ncx_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11155
0
{
11156
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11157
11158
 /* basic algorithm is:
11159
  *   - ensure sane alignment of output data
11160
  *   - copy (conversion happens automatically) input data
11161
  *     to output
11162
  *   - update tp to point at next unconverted input, and xpp to point
11163
  *     at next location for converted output
11164
  */
11165
  long i, j, ni;
11166
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11167
  ushort *xp;
11168
  int nrange = 0;         /* number of range errors */
11169
  int realign = 0;        /* "do we need to fix input data alignment?" */
11170
  long cxp = (long) *((char**)xpp);
11171
11172
  realign = (cxp & 7) % SIZEOF_USHORT;
11173
  /* sjl: manually stripmine so we can limit amount of
11174
   * vector work space reserved to LOOPCNT elements. Also
11175
   * makes vectorisation easy */
11176
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11177
    ni=Min(nelems-j,LOOPCNT);
11178
    if (realign) {
11179
      xp = tmp;
11180
    } else {
11181
      xp = (ushort *) *xpp;
11182
    }
11183
   /* copy the next block */
11184
#pragma cdir loopcnt=LOOPCNT
11185
#pragma cdir shortloop
11186
    for (i=0; i<ni; i++) {
11187
      /* the normal case: */
11188
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11189
     /* test for range errors (not always needed but do it anyway) */
11190
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11191
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11192
      nrange += tp[i] > X_USHORT_MAX ;
11193
    }
11194
   /* copy workspace back if necessary */
11195
    if (realign) {
11196
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11197
      xp = (ushort *) *xpp;
11198
    }
11199
   /* update xpp and tp */
11200
    xp += ni;
11201
    tp += ni;
11202
    *xpp = (void*)xp;
11203
  }
11204
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11205
11206
#else   /* not SX */
11207
11208
0
  char *xp = (char *) *xpp;
11209
0
  int status = NC_NOERR;
11210
11211
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11212
0
  {
11213
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11214
0
    if (status == NC_NOERR) /* report the first encountered error */
11215
0
      status = lstatus;
11216
0
  }
11217
11218
0
  *xpp = (void *)xp;
11219
0
  return status;
11220
0
#endif
11221
0
}
11222
11223
int
11224
ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11225
0
{
11226
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11227
11228
 /* basic algorithm is:
11229
  *   - ensure sane alignment of output data
11230
  *   - copy (conversion happens automatically) input data
11231
  *     to output
11232
  *   - update tp to point at next unconverted input, and xpp to point
11233
  *     at next location for converted output
11234
  */
11235
  long i, j, ni;
11236
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11237
  ushort *xp;
11238
  int nrange = 0;         /* number of range errors */
11239
  int realign = 0;        /* "do we need to fix input data alignment?" */
11240
  long cxp = (long) *((char**)xpp);
11241
11242
  realign = (cxp & 7) % SIZEOF_USHORT;
11243
  /* sjl: manually stripmine so we can limit amount of
11244
   * vector work space reserved to LOOPCNT elements. Also
11245
   * makes vectorisation easy */
11246
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11247
    ni=Min(nelems-j,LOOPCNT);
11248
    if (realign) {
11249
      xp = tmp;
11250
    } else {
11251
      xp = (ushort *) *xpp;
11252
    }
11253
   /* copy the next block */
11254
#pragma cdir loopcnt=LOOPCNT
11255
#pragma cdir shortloop
11256
    for (i=0; i<ni; i++) {
11257
      /* the normal case: */
11258
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11259
     /* test for range errors (not always needed but do it anyway) */
11260
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11261
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11262
      nrange += tp[i] > X_USHORT_MAX ;
11263
    }
11264
   /* copy workspace back if necessary */
11265
    if (realign) {
11266
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11267
      xp = (ushort *) *xpp;
11268
    }
11269
   /* update xpp and tp */
11270
    xp += ni;
11271
    tp += ni;
11272
    *xpp = (void*)xp;
11273
  }
11274
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11275
11276
#else   /* not SX */
11277
11278
0
  char *xp = (char *) *xpp;
11279
0
  int status = NC_NOERR;
11280
11281
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11282
0
  {
11283
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11284
0
    if (status == NC_NOERR) /* report the first encountered error */
11285
0
      status = lstatus;
11286
0
  }
11287
11288
0
  *xpp = (void *)xp;
11289
0
  return status;
11290
0
#endif
11291
0
}
11292
11293
int
11294
ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11295
0
{
11296
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11297
11298
 /* basic algorithm is:
11299
  *   - ensure sane alignment of output data
11300
  *   - copy (conversion happens automatically) input data
11301
  *     to output
11302
  *   - update tp to point at next unconverted input, and xpp to point
11303
  *     at next location for converted output
11304
  */
11305
  long i, j, ni;
11306
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11307
  ushort *xp;
11308
  int nrange = 0;         /* number of range errors */
11309
  int realign = 0;        /* "do we need to fix input data alignment?" */
11310
  long cxp = (long) *((char**)xpp);
11311
11312
  realign = (cxp & 7) % SIZEOF_USHORT;
11313
  /* sjl: manually stripmine so we can limit amount of
11314
   * vector work space reserved to LOOPCNT elements. Also
11315
   * makes vectorisation easy */
11316
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11317
    ni=Min(nelems-j,LOOPCNT);
11318
    if (realign) {
11319
      xp = tmp;
11320
    } else {
11321
      xp = (ushort *) *xpp;
11322
    }
11323
   /* copy the next block */
11324
#pragma cdir loopcnt=LOOPCNT
11325
#pragma cdir shortloop
11326
    for (i=0; i<ni; i++) {
11327
      /* the normal case: */
11328
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11329
     /* test for range errors (not always needed but do it anyway) */
11330
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11331
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11332
      nrange += tp[i] > X_USHORT_MAX ;
11333
    }
11334
   /* copy workspace back if necessary */
11335
    if (realign) {
11336
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11337
      xp = (ushort *) *xpp;
11338
    }
11339
   /* update xpp and tp */
11340
    xp += ni;
11341
    tp += ni;
11342
    *xpp = (void*)xp;
11343
  }
11344
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11345
11346
#else   /* not SX */
11347
11348
0
  char *xp = (char *) *xpp;
11349
0
  int status = NC_NOERR;
11350
11351
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11352
0
  {
11353
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11354
0
    if (status == NC_NOERR) /* report the first encountered error */
11355
0
      status = lstatus;
11356
0
  }
11357
11358
0
  *xpp = (void *)xp;
11359
0
  return status;
11360
0
#endif
11361
0
}
11362
11363
11364
int
11365
ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
11366
0
{
11367
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11368
11369
0
  char *xp = (char *) *xpp;
11370
0
  int status = NC_NOERR;
11371
11372
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11373
0
  {
11374
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
11375
0
    if (status == NC_NOERR) /* report the first encountered error */
11376
0
      status = lstatus;
11377
0
  }
11378
11379
0
  if (rndup != 0)
11380
0
  {
11381
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11382
0
    xp += X_SIZEOF_USHORT;
11383
0
  }
11384
11385
0
  *xpp = (void *)xp;
11386
0
  return status;
11387
0
}
11388
11389
int
11390
ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11391
0
{
11392
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11393
11394
0
  char *xp = (char *) *xpp;
11395
0
  int status = NC_NOERR;
11396
11397
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11398
0
  {
11399
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11400
0
    if (status == NC_NOERR) /* report the first encountered error */
11401
0
      status = lstatus;
11402
0
  }
11403
11404
0
  if (rndup != 0)
11405
0
  {
11406
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11407
0
    xp += X_SIZEOF_USHORT;
11408
0
  }
11409
11410
0
  *xpp = (void *)xp;
11411
0
  return status;
11412
0
}
11413
11414
int
11415
ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
11416
0
{
11417
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11418
11419
0
  char *xp = (char *) *xpp;
11420
0
  int status = NC_NOERR;
11421
11422
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11423
0
  {
11424
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11425
0
    if (status == NC_NOERR) /* report the first encountered error */
11426
0
      status = lstatus;
11427
0
  }
11428
11429
0
  if (rndup != 0)
11430
0
  {
11431
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11432
0
    xp += X_SIZEOF_USHORT;
11433
0
  }
11434
11435
0
  *xpp = (void *)xp;
11436
0
  return status;
11437
0
}
11438
11439
int
11440
ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11441
0
{
11442
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11443
11444
0
  char *xp = (char *) *xpp;
11445
0
  int status = NC_NOERR;
11446
11447
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11448
0
  {
11449
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11450
0
    if (status == NC_NOERR) /* report the first encountered error */
11451
0
      status = lstatus;
11452
0
  }
11453
11454
0
  if (rndup != 0)
11455
0
  {
11456
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11457
0
    xp += X_SIZEOF_USHORT;
11458
0
  }
11459
11460
0
  *xpp = (void *)xp;
11461
0
  return status;
11462
0
}
11463
11464
int
11465
ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11466
0
{
11467
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11468
11469
0
  char *xp = (char *) *xpp;
11470
0
  int status = NC_NOERR;
11471
11472
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11473
0
  {
11474
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11475
0
    if (status == NC_NOERR) /* report the first encountered error */
11476
0
      status = lstatus;
11477
0
  }
11478
11479
0
  if (rndup != 0)
11480
0
  {
11481
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11482
0
    xp += X_SIZEOF_USHORT;
11483
0
  }
11484
11485
0
  *xpp = (void *)xp;
11486
0
  return status;
11487
0
}
11488
11489
int
11490
ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11491
0
{
11492
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11493
11494
0
  char *xp = (char *) *xpp;
11495
0
  int status = NC_NOERR;
11496
11497
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11498
0
  {
11499
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11500
0
    if (status == NC_NOERR) /* report the first encountered error */
11501
0
      status = lstatus;
11502
0
  }
11503
11504
0
  if (rndup != 0)
11505
0
  {
11506
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11507
0
    xp += X_SIZEOF_USHORT;
11508
0
  }
11509
11510
0
  *xpp = (void *)xp;
11511
0
  return status;
11512
0
}
11513
11514
int
11515
ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11516
0
{
11517
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11518
11519
0
  char *xp = (char *) *xpp;
11520
0
  int status = NC_NOERR;
11521
11522
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11523
0
  {
11524
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11525
0
    if (status == NC_NOERR) /* report the first encountered error */
11526
0
      status = lstatus;
11527
0
  }
11528
11529
0
  if (rndup != 0)
11530
0
  {
11531
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11532
0
    xp += X_SIZEOF_USHORT;
11533
0
  }
11534
11535
0
  *xpp = (void *)xp;
11536
0
  return status;
11537
0
}
11538
11539
int
11540
ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11541
0
{
11542
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11543
11544
0
  char *xp = (char *) *xpp;
11545
0
  int status = NC_NOERR;
11546
11547
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11548
0
  {
11549
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11550
0
    if (status == NC_NOERR) /* report the first encountered error */
11551
0
      status = lstatus;
11552
0
  }
11553
11554
0
  if (rndup != 0)
11555
0
  {
11556
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11557
0
    xp += X_SIZEOF_USHORT;
11558
0
  }
11559
11560
0
  *xpp = (void *)xp;
11561
0
  return status;
11562
0
}
11563
11564
int
11565
ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11566
0
{
11567
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11568
11569
0
  char *xp = (char *) *xpp;
11570
0
  int status = NC_NOERR;
11571
11572
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11573
0
  {
11574
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11575
0
    if (status == NC_NOERR) /* report the first encountered error */
11576
0
      status = lstatus;
11577
0
  }
11578
11579
0
  if (rndup != 0)
11580
0
  {
11581
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11582
0
    xp += X_SIZEOF_USHORT;
11583
0
  }
11584
11585
0
  *xpp = (void *)xp;
11586
0
  return status;
11587
0
}
11588
11589
int
11590
ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11591
0
{
11592
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11593
11594
0
  char *xp = (char *) *xpp;
11595
0
  int status = NC_NOERR;
11596
11597
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11598
0
  {
11599
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11600
0
    if (status == NC_NOERR) /* report the first encountered error */
11601
0
      status = lstatus;
11602
0
  }
11603
11604
0
  if (rndup != 0)
11605
0
  {
11606
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11607
0
    xp += X_SIZEOF_USHORT;
11608
0
  }
11609
11610
0
  *xpp = (void *)xp;
11611
0
  return status;
11612
0
}
11613
11614
int
11615
ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
11616
0
{
11617
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11618
11619
0
  char *xp = (char *) *xpp;
11620
0
  int status = NC_NOERR;
11621
11622
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11623
0
  {
11624
0
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
11625
0
    if (status == NC_NOERR) /* report the first encountered error */
11626
0
      status = lstatus;
11627
0
  }
11628
11629
0
  if (rndup != 0)
11630
0
  {
11631
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11632
0
    xp += X_SIZEOF_USHORT;
11633
0
  }
11634
11635
0
  *xpp = (void *)xp;
11636
0
  return status;
11637
0
}
11638
11639
11640
11641
/* int -----------------------------------------------------------------------*/
11642
11643
#if X_SIZEOF_INT == SIZEOF_INT
11644
/* optimized version */
11645
int
11646
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11647
141k
{
11648
#ifdef WORDS_BIGENDIAN
11649
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
11650
# else
11651
141k
  swapn4b(tp, *xpp, nelems);
11652
141k
# endif
11653
141k
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
11654
141k
  return NC_NOERR;
11655
141k
}
11656
#else
11657
int
11658
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11659
{
11660
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11661
11662
 /* basic algorithm is:
11663
  *   - ensure sane alignment of input data
11664
  *   - copy (conversion happens automatically) input data
11665
  *     to output
11666
  *   - update xpp to point at next unconverted input, and tp to point
11667
  *     at next location for converted output
11668
  */
11669
  long i, j, ni;
11670
  int tmp[LOOPCNT];        /* in case input is misaligned */
11671
  int *xp;
11672
  int nrange = 0;         /* number of range errors */
11673
  int realign = 0;        /* "do we need to fix input data alignment?" */
11674
  long cxp = (long) *((char**)xpp);
11675
11676
  realign = (cxp & 7) % SIZEOF_INT;
11677
  /* sjl: manually stripmine so we can limit amount of
11678
   * vector work space reserved to LOOPCNT elements. Also
11679
   * makes vectorisation easy */
11680
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11681
    ni=Min(nelems-j,LOOPCNT);
11682
    if (realign) {
11683
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11684
      xp = tmp;
11685
    } else {
11686
      xp = (int *) *xpp;
11687
    }
11688
   /* copy the next block */
11689
#pragma cdir loopcnt=LOOPCNT
11690
#pragma cdir shortloop
11691
    for (i=0; i<ni; i++) {
11692
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
11693
     /* test for range errors (not always needed but do it anyway) */
11694
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11695
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11696
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
11697
    }
11698
   /* update xpp and tp */
11699
    if (realign) xp = (int *) *xpp;
11700
    xp += ni;
11701
    tp += ni;
11702
    *xpp = (void*)xp;
11703
  }
11704
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11705
11706
#else   /* not SX */
11707
  const char *xp = (const char *) *xpp;
11708
  int status = NC_NOERR;
11709
11710
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11711
  {
11712
    const int lstatus = ncx_get_int_int(xp, tp);
11713
    if (status == NC_NOERR) /* report the first encountered error */
11714
      status = lstatus;
11715
  }
11716
11717
  *xpp = (const void *)xp;
11718
  return status;
11719
#endif
11720
}
11721
11722
#endif
11723
int
11724
ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
11725
0
{
11726
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11727
11728
 /* basic algorithm is:
11729
  *   - ensure sane alignment of input data
11730
  *   - copy (conversion happens automatically) input data
11731
  *     to output
11732
  *   - update xpp to point at next unconverted input, and tp to point
11733
  *     at next location for converted output
11734
  */
11735
  long i, j, ni;
11736
  int tmp[LOOPCNT];        /* in case input is misaligned */
11737
  int *xp;
11738
  int nrange = 0;         /* number of range errors */
11739
  int realign = 0;        /* "do we need to fix input data alignment?" */
11740
  long cxp = (long) *((char**)xpp);
11741
11742
  realign = (cxp & 7) % SIZEOF_INT;
11743
  /* sjl: manually stripmine so we can limit amount of
11744
   * vector work space reserved to LOOPCNT elements. Also
11745
   * makes vectorisation easy */
11746
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11747
    ni=Min(nelems-j,LOOPCNT);
11748
    if (realign) {
11749
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11750
      xp = tmp;
11751
    } else {
11752
      xp = (int *) *xpp;
11753
    }
11754
   /* copy the next block */
11755
#pragma cdir loopcnt=LOOPCNT
11756
#pragma cdir shortloop
11757
    for (i=0; i<ni; i++) {
11758
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
11759
     /* test for range errors (not always needed but do it anyway) */
11760
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11761
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11762
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
11763
    }
11764
   /* update xpp and tp */
11765
    if (realign) xp = (int *) *xpp;
11766
    xp += ni;
11767
    tp += ni;
11768
    *xpp = (void*)xp;
11769
  }
11770
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11771
11772
#else   /* not SX */
11773
0
  const char *xp = (const char *) *xpp;
11774
0
  int status = NC_NOERR;
11775
11776
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11777
0
  {
11778
0
    const int lstatus = ncx_get_int_schar(xp, tp);
11779
0
    if (status == NC_NOERR) /* report the first encountered error */
11780
0
      status = lstatus;
11781
0
  }
11782
11783
0
  *xpp = (const void *)xp;
11784
0
  return status;
11785
0
#endif
11786
0
}
11787
11788
int
11789
ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
11790
0
{
11791
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11792
11793
 /* basic algorithm is:
11794
  *   - ensure sane alignment of input data
11795
  *   - copy (conversion happens automatically) input data
11796
  *     to output
11797
  *   - update xpp to point at next unconverted input, and tp to point
11798
  *     at next location for converted output
11799
  */
11800
  long i, j, ni;
11801
  int tmp[LOOPCNT];        /* in case input is misaligned */
11802
  int *xp;
11803
  int nrange = 0;         /* number of range errors */
11804
  int realign = 0;        /* "do we need to fix input data alignment?" */
11805
  long cxp = (long) *((char**)xpp);
11806
11807
  realign = (cxp & 7) % SIZEOF_INT;
11808
  /* sjl: manually stripmine so we can limit amount of
11809
   * vector work space reserved to LOOPCNT elements. Also
11810
   * makes vectorisation easy */
11811
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11812
    ni=Min(nelems-j,LOOPCNT);
11813
    if (realign) {
11814
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11815
      xp = tmp;
11816
    } else {
11817
      xp = (int *) *xpp;
11818
    }
11819
   /* copy the next block */
11820
#pragma cdir loopcnt=LOOPCNT
11821
#pragma cdir shortloop
11822
    for (i=0; i<ni; i++) {
11823
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
11824
     /* test for range errors (not always needed but do it anyway) */
11825
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11826
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11827
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
11828
    }
11829
   /* update xpp and tp */
11830
    if (realign) xp = (int *) *xpp;
11831
    xp += ni;
11832
    tp += ni;
11833
    *xpp = (void*)xp;
11834
  }
11835
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11836
11837
#else   /* not SX */
11838
0
  const char *xp = (const char *) *xpp;
11839
0
  int status = NC_NOERR;
11840
11841
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11842
0
  {
11843
0
    const int lstatus = ncx_get_int_short(xp, tp);
11844
0
    if (status == NC_NOERR) /* report the first encountered error */
11845
0
      status = lstatus;
11846
0
  }
11847
11848
0
  *xpp = (const void *)xp;
11849
0
  return status;
11850
0
#endif
11851
0
}
11852
11853
int
11854
ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
11855
0
{
11856
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11857
11858
 /* basic algorithm is:
11859
  *   - ensure sane alignment of input data
11860
  *   - copy (conversion happens automatically) input data
11861
  *     to output
11862
  *   - update xpp to point at next unconverted input, and tp to point
11863
  *     at next location for converted output
11864
  */
11865
  long i, j, ni;
11866
  int tmp[LOOPCNT];        /* in case input is misaligned */
11867
  int *xp;
11868
  int nrange = 0;         /* number of range errors */
11869
  int realign = 0;        /* "do we need to fix input data alignment?" */
11870
  long cxp = (long) *((char**)xpp);
11871
11872
  realign = (cxp & 7) % SIZEOF_INT;
11873
  /* sjl: manually stripmine so we can limit amount of
11874
   * vector work space reserved to LOOPCNT elements. Also
11875
   * makes vectorisation easy */
11876
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11877
    ni=Min(nelems-j,LOOPCNT);
11878
    if (realign) {
11879
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11880
      xp = tmp;
11881
    } else {
11882
      xp = (int *) *xpp;
11883
    }
11884
   /* copy the next block */
11885
#pragma cdir loopcnt=LOOPCNT
11886
#pragma cdir shortloop
11887
    for (i=0; i<ni; i++) {
11888
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
11889
     /* test for range errors (not always needed but do it anyway) */
11890
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11891
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11892
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
11893
    }
11894
   /* update xpp and tp */
11895
    if (realign) xp = (int *) *xpp;
11896
    xp += ni;
11897
    tp += ni;
11898
    *xpp = (void*)xp;
11899
  }
11900
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11901
11902
#else   /* not SX */
11903
0
  const char *xp = (const char *) *xpp;
11904
0
  int status = NC_NOERR;
11905
11906
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11907
0
  {
11908
0
    const int lstatus = ncx_get_int_long(xp, tp);
11909
0
    if (status == NC_NOERR) /* report the first encountered error */
11910
0
      status = lstatus;
11911
0
  }
11912
11913
0
  *xpp = (const void *)xp;
11914
0
  return status;
11915
0
#endif
11916
0
}
11917
11918
int
11919
ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
11920
0
{
11921
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11922
11923
 /* basic algorithm is:
11924
  *   - ensure sane alignment of input data
11925
  *   - copy (conversion happens automatically) input data
11926
  *     to output
11927
  *   - update xpp to point at next unconverted input, and tp to point
11928
  *     at next location for converted output
11929
  */
11930
  long i, j, ni;
11931
  int tmp[LOOPCNT];        /* in case input is misaligned */
11932
  int *xp;
11933
  int nrange = 0;         /* number of range errors */
11934
  int realign = 0;        /* "do we need to fix input data alignment?" */
11935
  long cxp = (long) *((char**)xpp);
11936
11937
  realign = (cxp & 7) % SIZEOF_INT;
11938
  /* sjl: manually stripmine so we can limit amount of
11939
   * vector work space reserved to LOOPCNT elements. Also
11940
   * makes vectorisation easy */
11941
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11942
    ni=Min(nelems-j,LOOPCNT);
11943
    if (realign) {
11944
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11945
      xp = tmp;
11946
    } else {
11947
      xp = (int *) *xpp;
11948
    }
11949
   /* copy the next block */
11950
#pragma cdir loopcnt=LOOPCNT
11951
#pragma cdir shortloop
11952
    for (i=0; i<ni; i++) {
11953
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
11954
     /* test for range errors (not always needed but do it anyway) */
11955
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11956
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11957
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
11958
    }
11959
   /* update xpp and tp */
11960
    if (realign) xp = (int *) *xpp;
11961
    xp += ni;
11962
    tp += ni;
11963
    *xpp = (void*)xp;
11964
  }
11965
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11966
11967
#else   /* not SX */
11968
0
  const char *xp = (const char *) *xpp;
11969
0
  int status = NC_NOERR;
11970
11971
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11972
0
  {
11973
0
    const int lstatus = ncx_get_int_float(xp, tp);
11974
0
    if (status == NC_NOERR) /* report the first encountered error */
11975
0
      status = lstatus;
11976
0
  }
11977
11978
0
  *xpp = (const void *)xp;
11979
0
  return status;
11980
0
#endif
11981
0
}
11982
11983
int
11984
ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
11985
0
{
11986
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11987
11988
 /* basic algorithm is:
11989
  *   - ensure sane alignment of input data
11990
  *   - copy (conversion happens automatically) input data
11991
  *     to output
11992
  *   - update xpp to point at next unconverted input, and tp to point
11993
  *     at next location for converted output
11994
  */
11995
  long i, j, ni;
11996
  int tmp[LOOPCNT];        /* in case input is misaligned */
11997
  int *xp;
11998
  int nrange = 0;         /* number of range errors */
11999
  int realign = 0;        /* "do we need to fix input data alignment?" */
12000
  long cxp = (long) *((char**)xpp);
12001
12002
  realign = (cxp & 7) % SIZEOF_INT;
12003
  /* sjl: manually stripmine so we can limit amount of
12004
   * vector work space reserved to LOOPCNT elements. Also
12005
   * makes vectorisation easy */
12006
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12007
    ni=Min(nelems-j,LOOPCNT);
12008
    if (realign) {
12009
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12010
      xp = tmp;
12011
    } else {
12012
      xp = (int *) *xpp;
12013
    }
12014
   /* copy the next block */
12015
#pragma cdir loopcnt=LOOPCNT
12016
#pragma cdir shortloop
12017
    for (i=0; i<ni; i++) {
12018
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
12019
     /* test for range errors (not always needed but do it anyway) */
12020
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12021
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12022
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
12023
    }
12024
   /* update xpp and tp */
12025
    if (realign) xp = (int *) *xpp;
12026
    xp += ni;
12027
    tp += ni;
12028
    *xpp = (void*)xp;
12029
  }
12030
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12031
12032
#else   /* not SX */
12033
0
  const char *xp = (const char *) *xpp;
12034
0
  int status = NC_NOERR;
12035
12036
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12037
0
  {
12038
0
    const int lstatus = ncx_get_int_double(xp, tp);
12039
0
    if (status == NC_NOERR) /* report the first encountered error */
12040
0
      status = lstatus;
12041
0
  }
12042
12043
0
  *xpp = (const void *)xp;
12044
0
  return status;
12045
0
#endif
12046
0
}
12047
12048
int
12049
ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp)
12050
0
{
12051
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12052
12053
 /* basic algorithm is:
12054
  *   - ensure sane alignment of input data
12055
  *   - copy (conversion happens automatically) input data
12056
  *     to output
12057
  *   - update xpp to point at next unconverted input, and tp to point
12058
  *     at next location for converted output
12059
  */
12060
  long i, j, ni;
12061
  int tmp[LOOPCNT];        /* in case input is misaligned */
12062
  int *xp;
12063
  int nrange = 0;         /* number of range errors */
12064
  int realign = 0;        /* "do we need to fix input data alignment?" */
12065
  long cxp = (long) *((char**)xpp);
12066
12067
  realign = (cxp & 7) % SIZEOF_INT;
12068
  /* sjl: manually stripmine so we can limit amount of
12069
   * vector work space reserved to LOOPCNT elements. Also
12070
   * makes vectorisation easy */
12071
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12072
    ni=Min(nelems-j,LOOPCNT);
12073
    if (realign) {
12074
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12075
      xp = tmp;
12076
    } else {
12077
      xp = (int *) *xpp;
12078
    }
12079
   /* copy the next block */
12080
#pragma cdir loopcnt=LOOPCNT
12081
#pragma cdir shortloop
12082
    for (i=0; i<ni; i++) {
12083
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
12084
     /* test for range errors (not always needed but do it anyway) */
12085
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12086
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12087
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
12088
    }
12089
   /* update xpp and tp */
12090
    if (realign) xp = (int *) *xpp;
12091
    xp += ni;
12092
    tp += ni;
12093
    *xpp = (void*)xp;
12094
  }
12095
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12096
12097
#else   /* not SX */
12098
0
  const char *xp = (const char *) *xpp;
12099
0
  int status = NC_NOERR;
12100
12101
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12102
0
  {
12103
0
    const int lstatus = ncx_get_int_longlong(xp, tp);
12104
0
    if (status == NC_NOERR) /* report the first encountered error */
12105
0
      status = lstatus;
12106
0
  }
12107
12108
0
  *xpp = (const void *)xp;
12109
0
  return status;
12110
0
#endif
12111
0
}
12112
12113
int
12114
ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
12115
0
{
12116
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12117
12118
 /* basic algorithm is:
12119
  *   - ensure sane alignment of input data
12120
  *   - copy (conversion happens automatically) input data
12121
  *     to output
12122
  *   - update xpp to point at next unconverted input, and tp to point
12123
  *     at next location for converted output
12124
  */
12125
  long i, j, ni;
12126
  int tmp[LOOPCNT];        /* in case input is misaligned */
12127
  int *xp;
12128
  int nrange = 0;         /* number of range errors */
12129
  int realign = 0;        /* "do we need to fix input data alignment?" */
12130
  long cxp = (long) *((char**)xpp);
12131
12132
  realign = (cxp & 7) % SIZEOF_INT;
12133
  /* sjl: manually stripmine so we can limit amount of
12134
   * vector work space reserved to LOOPCNT elements. Also
12135
   * makes vectorisation easy */
12136
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12137
    ni=Min(nelems-j,LOOPCNT);
12138
    if (realign) {
12139
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12140
      xp = tmp;
12141
    } else {
12142
      xp = (int *) *xpp;
12143
    }
12144
   /* copy the next block */
12145
#pragma cdir loopcnt=LOOPCNT
12146
#pragma cdir shortloop
12147
    for (i=0; i<ni; i++) {
12148
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
12149
     /* test for range errors (not always needed but do it anyway) */
12150
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12151
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12152
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
12153
    }
12154
   /* update xpp and tp */
12155
    if (realign) xp = (int *) *xpp;
12156
    xp += ni;
12157
    tp += ni;
12158
    *xpp = (void*)xp;
12159
  }
12160
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12161
12162
#else   /* not SX */
12163
0
  const char *xp = (const char *) *xpp;
12164
0
  int status = NC_NOERR;
12165
12166
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12167
0
  {
12168
0
    const int lstatus = ncx_get_int_uchar(xp, tp);
12169
0
    if (status == NC_NOERR) /* report the first encountered error */
12170
0
      status = lstatus;
12171
0
  }
12172
12173
0
  *xpp = (const void *)xp;
12174
0
  return status;
12175
0
#endif
12176
0
}
12177
12178
int
12179
ncx_getn_int_ushort(const void **xpp, size_t nelems, ushort *tp)
12180
0
{
12181
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12182
12183
 /* basic algorithm is:
12184
  *   - ensure sane alignment of input data
12185
  *   - copy (conversion happens automatically) input data
12186
  *     to output
12187
  *   - update xpp to point at next unconverted input, and tp to point
12188
  *     at next location for converted output
12189
  */
12190
  long i, j, ni;
12191
  int tmp[LOOPCNT];        /* in case input is misaligned */
12192
  int *xp;
12193
  int nrange = 0;         /* number of range errors */
12194
  int realign = 0;        /* "do we need to fix input data alignment?" */
12195
  long cxp = (long) *((char**)xpp);
12196
12197
  realign = (cxp & 7) % SIZEOF_INT;
12198
  /* sjl: manually stripmine so we can limit amount of
12199
   * vector work space reserved to LOOPCNT elements. Also
12200
   * makes vectorisation easy */
12201
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12202
    ni=Min(nelems-j,LOOPCNT);
12203
    if (realign) {
12204
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12205
      xp = tmp;
12206
    } else {
12207
      xp = (int *) *xpp;
12208
    }
12209
   /* copy the next block */
12210
#pragma cdir loopcnt=LOOPCNT
12211
#pragma cdir shortloop
12212
    for (i=0; i<ni; i++) {
12213
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
12214
     /* test for range errors (not always needed but do it anyway) */
12215
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12216
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12217
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
12218
    }
12219
   /* update xpp and tp */
12220
    if (realign) xp = (int *) *xpp;
12221
    xp += ni;
12222
    tp += ni;
12223
    *xpp = (void*)xp;
12224
  }
12225
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12226
12227
#else   /* not SX */
12228
0
  const char *xp = (const char *) *xpp;
12229
0
  int status = NC_NOERR;
12230
12231
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12232
0
  {
12233
0
    const int lstatus = ncx_get_int_ushort(xp, tp);
12234
0
    if (status == NC_NOERR) /* report the first encountered error */
12235
0
      status = lstatus;
12236
0
  }
12237
12238
0
  *xpp = (const void *)xp;
12239
0
  return status;
12240
0
#endif
12241
0
}
12242
12243
int
12244
ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp)
12245
0
{
12246
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12247
12248
 /* basic algorithm is:
12249
  *   - ensure sane alignment of input data
12250
  *   - copy (conversion happens automatically) input data
12251
  *     to output
12252
  *   - update xpp to point at next unconverted input, and tp to point
12253
  *     at next location for converted output
12254
  */
12255
  long i, j, ni;
12256
  int tmp[LOOPCNT];        /* in case input is misaligned */
12257
  int *xp;
12258
  int nrange = 0;         /* number of range errors */
12259
  int realign = 0;        /* "do we need to fix input data alignment?" */
12260
  long cxp = (long) *((char**)xpp);
12261
12262
  realign = (cxp & 7) % SIZEOF_INT;
12263
  /* sjl: manually stripmine so we can limit amount of
12264
   * vector work space reserved to LOOPCNT elements. Also
12265
   * makes vectorisation easy */
12266
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12267
    ni=Min(nelems-j,LOOPCNT);
12268
    if (realign) {
12269
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12270
      xp = tmp;
12271
    } else {
12272
      xp = (int *) *xpp;
12273
    }
12274
   /* copy the next block */
12275
#pragma cdir loopcnt=LOOPCNT
12276
#pragma cdir shortloop
12277
    for (i=0; i<ni; i++) {
12278
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
12279
     /* test for range errors (not always needed but do it anyway) */
12280
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12281
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12282
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
12283
    }
12284
   /* update xpp and tp */
12285
    if (realign) xp = (int *) *xpp;
12286
    xp += ni;
12287
    tp += ni;
12288
    *xpp = (void*)xp;
12289
  }
12290
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12291
12292
#else   /* not SX */
12293
0
  const char *xp = (const char *) *xpp;
12294
0
  int status = NC_NOERR;
12295
12296
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12297
0
  {
12298
0
    const int lstatus = ncx_get_int_uint(xp, tp);
12299
0
    if (status == NC_NOERR) /* report the first encountered error */
12300
0
      status = lstatus;
12301
0
  }
12302
12303
0
  *xpp = (const void *)xp;
12304
0
  return status;
12305
0
#endif
12306
0
}
12307
12308
int
12309
ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
12310
0
{
12311
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12312
12313
 /* basic algorithm is:
12314
  *   - ensure sane alignment of input data
12315
  *   - copy (conversion happens automatically) input data
12316
  *     to output
12317
  *   - update xpp to point at next unconverted input, and tp to point
12318
  *     at next location for converted output
12319
  */
12320
  long i, j, ni;
12321
  int tmp[LOOPCNT];        /* in case input is misaligned */
12322
  int *xp;
12323
  int nrange = 0;         /* number of range errors */
12324
  int realign = 0;        /* "do we need to fix input data alignment?" */
12325
  long cxp = (long) *((char**)xpp);
12326
12327
  realign = (cxp & 7) % SIZEOF_INT;
12328
  /* sjl: manually stripmine so we can limit amount of
12329
   * vector work space reserved to LOOPCNT elements. Also
12330
   * makes vectorisation easy */
12331
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12332
    ni=Min(nelems-j,LOOPCNT);
12333
    if (realign) {
12334
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12335
      xp = tmp;
12336
    } else {
12337
      xp = (int *) *xpp;
12338
    }
12339
   /* copy the next block */
12340
#pragma cdir loopcnt=LOOPCNT
12341
#pragma cdir shortloop
12342
    for (i=0; i<ni; i++) {
12343
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
12344
     /* test for range errors (not always needed but do it anyway) */
12345
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12346
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12347
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
12348
    }
12349
   /* update xpp and tp */
12350
    if (realign) xp = (int *) *xpp;
12351
    xp += ni;
12352
    tp += ni;
12353
    *xpp = (void*)xp;
12354
  }
12355
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12356
12357
#else   /* not SX */
12358
0
  const char *xp = (const char *) *xpp;
12359
0
  int status = NC_NOERR;
12360
12361
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12362
0
  {
12363
0
    const int lstatus = ncx_get_int_ulonglong(xp, tp);
12364
0
    if (status == NC_NOERR) /* report the first encountered error */
12365
0
      status = lstatus;
12366
0
  }
12367
12368
0
  *xpp = (const void *)xp;
12369
0
  return status;
12370
0
#endif
12371
0
}
12372
12373
12374
#if X_SIZEOF_INT == SIZEOF_INT
12375
/* optimized version */
12376
int
12377
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12378
0
{
12379
#ifdef WORDS_BIGENDIAN
12380
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
12381
# else
12382
0
  swapn4b(*xpp, tp, nelems);
12383
0
# endif
12384
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
12385
0
  return NC_NOERR;
12386
0
}
12387
#else
12388
int
12389
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12390
{
12391
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12392
12393
 /* basic algorithm is:
12394
  *   - ensure sane alignment of output data
12395
  *   - copy (conversion happens automatically) input data
12396
  *     to output
12397
  *   - update tp to point at next unconverted input, and xpp to point
12398
  *     at next location for converted output
12399
  */
12400
  long i, j, ni;
12401
  int tmp[LOOPCNT];        /* in case input is misaligned */
12402
  int *xp;
12403
  int nrange = 0;         /* number of range errors */
12404
  int realign = 0;        /* "do we need to fix input data alignment?" */
12405
  long cxp = (long) *((char**)xpp);
12406
12407
  realign = (cxp & 7) % SIZEOF_INT;
12408
  /* sjl: manually stripmine so we can limit amount of
12409
   * vector work space reserved to LOOPCNT elements. Also
12410
   * makes vectorisation easy */
12411
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12412
    ni=Min(nelems-j,LOOPCNT);
12413
    if (realign) {
12414
      xp = tmp;
12415
    } else {
12416
      xp = (int *) *xpp;
12417
    }
12418
   /* copy the next block */
12419
#pragma cdir loopcnt=LOOPCNT
12420
#pragma cdir shortloop
12421
    for (i=0; i<ni; i++) {
12422
      /* the normal case: */
12423
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12424
     /* test for range errors (not always needed but do it anyway) */
12425
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12426
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12427
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12428
    }
12429
   /* copy workspace back if necessary */
12430
    if (realign) {
12431
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12432
      xp = (int *) *xpp;
12433
    }
12434
   /* update xpp and tp */
12435
    xp += ni;
12436
    tp += ni;
12437
    *xpp = (void*)xp;
12438
  }
12439
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12440
12441
#else   /* not SX */
12442
12443
  char *xp = (char *) *xpp;
12444
  int status = NC_NOERR;
12445
12446
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12447
  {
12448
    int lstatus = ncx_put_int_int(xp, tp, fillp);
12449
    if (status == NC_NOERR) /* report the first encountered error */
12450
      status = lstatus;
12451
  }
12452
12453
  *xpp = (void *)xp;
12454
  return status;
12455
#endif
12456
}
12457
12458
#endif
12459
int
12460
ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
12461
0
{
12462
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12463
12464
 /* basic algorithm is:
12465
  *   - ensure sane alignment of output data
12466
  *   - copy (conversion happens automatically) input data
12467
  *     to output
12468
  *   - update tp to point at next unconverted input, and xpp to point
12469
  *     at next location for converted output
12470
  */
12471
  long i, j, ni;
12472
  int tmp[LOOPCNT];        /* in case input is misaligned */
12473
  int *xp;
12474
  int nrange = 0;         /* number of range errors */
12475
  int realign = 0;        /* "do we need to fix input data alignment?" */
12476
  long cxp = (long) *((char**)xpp);
12477
12478
  realign = (cxp & 7) % SIZEOF_INT;
12479
  /* sjl: manually stripmine so we can limit amount of
12480
   * vector work space reserved to LOOPCNT elements. Also
12481
   * makes vectorisation easy */
12482
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12483
    ni=Min(nelems-j,LOOPCNT);
12484
    if (realign) {
12485
      xp = tmp;
12486
    } else {
12487
      xp = (int *) *xpp;
12488
    }
12489
   /* copy the next block */
12490
#pragma cdir loopcnt=LOOPCNT
12491
#pragma cdir shortloop
12492
    for (i=0; i<ni; i++) {
12493
      /* the normal case: */
12494
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12495
     /* test for range errors (not always needed but do it anyway) */
12496
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12497
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12498
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12499
    }
12500
   /* copy workspace back if necessary */
12501
    if (realign) {
12502
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12503
      xp = (int *) *xpp;
12504
    }
12505
   /* update xpp and tp */
12506
    xp += ni;
12507
    tp += ni;
12508
    *xpp = (void*)xp;
12509
  }
12510
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12511
12512
#else   /* not SX */
12513
12514
0
  char *xp = (char *) *xpp;
12515
0
  int status = NC_NOERR;
12516
12517
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12518
0
  {
12519
0
    int lstatus = ncx_put_int_schar(xp, tp, fillp);
12520
0
    if (status == NC_NOERR) /* report the first encountered error */
12521
0
      status = lstatus;
12522
0
  }
12523
12524
0
  *xpp = (void *)xp;
12525
0
  return status;
12526
0
#endif
12527
0
}
12528
12529
int
12530
ncx_putn_int_short(void **xpp, size_t nelems, const short *tp, void *fillp)
12531
0
{
12532
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12533
12534
 /* basic algorithm is:
12535
  *   - ensure sane alignment of output data
12536
  *   - copy (conversion happens automatically) input data
12537
  *     to output
12538
  *   - update tp to point at next unconverted input, and xpp to point
12539
  *     at next location for converted output
12540
  */
12541
  long i, j, ni;
12542
  int tmp[LOOPCNT];        /* in case input is misaligned */
12543
  int *xp;
12544
  int nrange = 0;         /* number of range errors */
12545
  int realign = 0;        /* "do we need to fix input data alignment?" */
12546
  long cxp = (long) *((char**)xpp);
12547
12548
  realign = (cxp & 7) % SIZEOF_INT;
12549
  /* sjl: manually stripmine so we can limit amount of
12550
   * vector work space reserved to LOOPCNT elements. Also
12551
   * makes vectorisation easy */
12552
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12553
    ni=Min(nelems-j,LOOPCNT);
12554
    if (realign) {
12555
      xp = tmp;
12556
    } else {
12557
      xp = (int *) *xpp;
12558
    }
12559
   /* copy the next block */
12560
#pragma cdir loopcnt=LOOPCNT
12561
#pragma cdir shortloop
12562
    for (i=0; i<ni; i++) {
12563
      /* the normal case: */
12564
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12565
     /* test for range errors (not always needed but do it anyway) */
12566
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12567
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12568
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12569
    }
12570
   /* copy workspace back if necessary */
12571
    if (realign) {
12572
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12573
      xp = (int *) *xpp;
12574
    }
12575
   /* update xpp and tp */
12576
    xp += ni;
12577
    tp += ni;
12578
    *xpp = (void*)xp;
12579
  }
12580
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12581
12582
#else   /* not SX */
12583
12584
0
  char *xp = (char *) *xpp;
12585
0
  int status = NC_NOERR;
12586
12587
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12588
0
  {
12589
0
    int lstatus = ncx_put_int_short(xp, tp, fillp);
12590
0
    if (status == NC_NOERR) /* report the first encountered error */
12591
0
      status = lstatus;
12592
0
  }
12593
12594
0
  *xpp = (void *)xp;
12595
0
  return status;
12596
0
#endif
12597
0
}
12598
12599
int
12600
ncx_putn_int_long(void **xpp, size_t nelems, const long *tp, void *fillp)
12601
0
{
12602
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12603
12604
 /* basic algorithm is:
12605
  *   - ensure sane alignment of output data
12606
  *   - copy (conversion happens automatically) input data
12607
  *     to output
12608
  *   - update tp to point at next unconverted input, and xpp to point
12609
  *     at next location for converted output
12610
  */
12611
  long i, j, ni;
12612
  int tmp[LOOPCNT];        /* in case input is misaligned */
12613
  int *xp;
12614
  int nrange = 0;         /* number of range errors */
12615
  int realign = 0;        /* "do we need to fix input data alignment?" */
12616
  long cxp = (long) *((char**)xpp);
12617
12618
  realign = (cxp & 7) % SIZEOF_INT;
12619
  /* sjl: manually stripmine so we can limit amount of
12620
   * vector work space reserved to LOOPCNT elements. Also
12621
   * makes vectorisation easy */
12622
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12623
    ni=Min(nelems-j,LOOPCNT);
12624
    if (realign) {
12625
      xp = tmp;
12626
    } else {
12627
      xp = (int *) *xpp;
12628
    }
12629
   /* copy the next block */
12630
#pragma cdir loopcnt=LOOPCNT
12631
#pragma cdir shortloop
12632
    for (i=0; i<ni; i++) {
12633
      /* the normal case: */
12634
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12635
     /* test for range errors (not always needed but do it anyway) */
12636
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12637
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12638
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12639
    }
12640
   /* copy workspace back if necessary */
12641
    if (realign) {
12642
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12643
      xp = (int *) *xpp;
12644
    }
12645
   /* update xpp and tp */
12646
    xp += ni;
12647
    tp += ni;
12648
    *xpp = (void*)xp;
12649
  }
12650
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12651
12652
#else   /* not SX */
12653
12654
0
  char *xp = (char *) *xpp;
12655
0
  int status = NC_NOERR;
12656
12657
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12658
0
  {
12659
0
    int lstatus = ncx_put_int_long(xp, tp, fillp);
12660
0
    if (status == NC_NOERR) /* report the first encountered error */
12661
0
      status = lstatus;
12662
0
  }
12663
12664
0
  *xpp = (void *)xp;
12665
0
  return status;
12666
0
#endif
12667
0
}
12668
12669
int
12670
ncx_putn_int_float(void **xpp, size_t nelems, const float *tp, void *fillp)
12671
0
{
12672
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12673
12674
 /* basic algorithm is:
12675
  *   - ensure sane alignment of output data
12676
  *   - copy (conversion happens automatically) input data
12677
  *     to output
12678
  *   - update tp to point at next unconverted input, and xpp to point
12679
  *     at next location for converted output
12680
  */
12681
  long i, j, ni;
12682
  int tmp[LOOPCNT];        /* in case input is misaligned */
12683
  int *xp;
12684
  double d;               /* special case for ncx_putn_int_float */
12685
  int nrange = 0;         /* number of range errors */
12686
  int realign = 0;        /* "do we need to fix input data alignment?" */
12687
  long cxp = (long) *((char**)xpp);
12688
12689
  realign = (cxp & 7) % SIZEOF_INT;
12690
  /* sjl: manually stripmine so we can limit amount of
12691
   * vector work space reserved to LOOPCNT elements. Also
12692
   * makes vectorisation easy */
12693
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12694
    ni=Min(nelems-j,LOOPCNT);
12695
    if (realign) {
12696
      xp = tmp;
12697
    } else {
12698
      xp = (int *) *xpp;
12699
    }
12700
   /* copy the next block */
12701
#pragma cdir loopcnt=LOOPCNT
12702
#pragma cdir shortloop
12703
    for (i=0; i<ni; i++) {
12704
      /* for some reason int to float, for putn, requires a special case */
12705
      d = tp[i];
12706
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
12707
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12708
    }
12709
   /* copy workspace back if necessary */
12710
    if (realign) {
12711
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12712
      xp = (int *) *xpp;
12713
    }
12714
   /* update xpp and tp */
12715
    xp += ni;
12716
    tp += ni;
12717
    *xpp = (void*)xp;
12718
  }
12719
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12720
12721
#else   /* not SX */
12722
12723
0
  char *xp = (char *) *xpp;
12724
0
  int status = NC_NOERR;
12725
12726
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12727
0
  {
12728
0
    int lstatus = ncx_put_int_float(xp, tp, fillp);
12729
0
    if (status == NC_NOERR) /* report the first encountered error */
12730
0
      status = lstatus;
12731
0
  }
12732
12733
0
  *xpp = (void *)xp;
12734
0
  return status;
12735
0
#endif
12736
0
}
12737
12738
int
12739
ncx_putn_int_double(void **xpp, size_t nelems, const double *tp, void *fillp)
12740
0
{
12741
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12742
12743
 /* basic algorithm is:
12744
  *   - ensure sane alignment of output data
12745
  *   - copy (conversion happens automatically) input data
12746
  *     to output
12747
  *   - update tp to point at next unconverted input, and xpp to point
12748
  *     at next location for converted output
12749
  */
12750
  long i, j, ni;
12751
  int tmp[LOOPCNT];        /* in case input is misaligned */
12752
  int *xp;
12753
  int nrange = 0;         /* number of range errors */
12754
  int realign = 0;        /* "do we need to fix input data alignment?" */
12755
  long cxp = (long) *((char**)xpp);
12756
12757
  realign = (cxp & 7) % SIZEOF_INT;
12758
  /* sjl: manually stripmine so we can limit amount of
12759
   * vector work space reserved to LOOPCNT elements. Also
12760
   * makes vectorisation easy */
12761
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12762
    ni=Min(nelems-j,LOOPCNT);
12763
    if (realign) {
12764
      xp = tmp;
12765
    } else {
12766
      xp = (int *) *xpp;
12767
    }
12768
   /* copy the next block */
12769
#pragma cdir loopcnt=LOOPCNT
12770
#pragma cdir shortloop
12771
    for (i=0; i<ni; i++) {
12772
      /* the normal case: */
12773
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12774
     /* test for range errors (not always needed but do it anyway) */
12775
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12776
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12777
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12778
    }
12779
   /* copy workspace back if necessary */
12780
    if (realign) {
12781
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12782
      xp = (int *) *xpp;
12783
    }
12784
   /* update xpp and tp */
12785
    xp += ni;
12786
    tp += ni;
12787
    *xpp = (void*)xp;
12788
  }
12789
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12790
12791
#else   /* not SX */
12792
12793
0
  char *xp = (char *) *xpp;
12794
0
  int status = NC_NOERR;
12795
12796
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12797
0
  {
12798
0
    int lstatus = ncx_put_int_double(xp, tp, fillp);
12799
0
    if (status == NC_NOERR) /* report the first encountered error */
12800
0
      status = lstatus;
12801
0
  }
12802
12803
0
  *xpp = (void *)xp;
12804
0
  return status;
12805
0
#endif
12806
0
}
12807
12808
int
12809
ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
12810
0
{
12811
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12812
12813
 /* basic algorithm is:
12814
  *   - ensure sane alignment of output data
12815
  *   - copy (conversion happens automatically) input data
12816
  *     to output
12817
  *   - update tp to point at next unconverted input, and xpp to point
12818
  *     at next location for converted output
12819
  */
12820
  long i, j, ni;
12821
  int tmp[LOOPCNT];        /* in case input is misaligned */
12822
  int *xp;
12823
  int nrange = 0;         /* number of range errors */
12824
  int realign = 0;        /* "do we need to fix input data alignment?" */
12825
  long cxp = (long) *((char**)xpp);
12826
12827
  realign = (cxp & 7) % SIZEOF_INT;
12828
  /* sjl: manually stripmine so we can limit amount of
12829
   * vector work space reserved to LOOPCNT elements. Also
12830
   * makes vectorisation easy */
12831
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12832
    ni=Min(nelems-j,LOOPCNT);
12833
    if (realign) {
12834
      xp = tmp;
12835
    } else {
12836
      xp = (int *) *xpp;
12837
    }
12838
   /* copy the next block */
12839
#pragma cdir loopcnt=LOOPCNT
12840
#pragma cdir shortloop
12841
    for (i=0; i<ni; i++) {
12842
      /* the normal case: */
12843
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12844
     /* test for range errors (not always needed but do it anyway) */
12845
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12846
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12847
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12848
    }
12849
   /* copy workspace back if necessary */
12850
    if (realign) {
12851
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12852
      xp = (int *) *xpp;
12853
    }
12854
   /* update xpp and tp */
12855
    xp += ni;
12856
    tp += ni;
12857
    *xpp = (void*)xp;
12858
  }
12859
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12860
12861
#else   /* not SX */
12862
12863
0
  char *xp = (char *) *xpp;
12864
0
  int status = NC_NOERR;
12865
12866
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12867
0
  {
12868
0
    int lstatus = ncx_put_int_longlong(xp, tp, fillp);
12869
0
    if (status == NC_NOERR) /* report the first encountered error */
12870
0
      status = lstatus;
12871
0
  }
12872
12873
0
  *xpp = (void *)xp;
12874
0
  return status;
12875
0
#endif
12876
0
}
12877
12878
int
12879
ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
12880
0
{
12881
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12882
12883
 /* basic algorithm is:
12884
  *   - ensure sane alignment of output data
12885
  *   - copy (conversion happens automatically) input data
12886
  *     to output
12887
  *   - update tp to point at next unconverted input, and xpp to point
12888
  *     at next location for converted output
12889
  */
12890
  long i, j, ni;
12891
  int tmp[LOOPCNT];        /* in case input is misaligned */
12892
  int *xp;
12893
  int nrange = 0;         /* number of range errors */
12894
  int realign = 0;        /* "do we need to fix input data alignment?" */
12895
  long cxp = (long) *((char**)xpp);
12896
12897
  realign = (cxp & 7) % SIZEOF_INT;
12898
  /* sjl: manually stripmine so we can limit amount of
12899
   * vector work space reserved to LOOPCNT elements. Also
12900
   * makes vectorisation easy */
12901
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12902
    ni=Min(nelems-j,LOOPCNT);
12903
    if (realign) {
12904
      xp = tmp;
12905
    } else {
12906
      xp = (int *) *xpp;
12907
    }
12908
   /* copy the next block */
12909
#pragma cdir loopcnt=LOOPCNT
12910
#pragma cdir shortloop
12911
    for (i=0; i<ni; i++) {
12912
      /* the normal case: */
12913
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12914
     /* test for range errors (not always needed but do it anyway) */
12915
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12916
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12917
      nrange += tp[i] > X_INT_MAX ;
12918
    }
12919
   /* copy workspace back if necessary */
12920
    if (realign) {
12921
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12922
      xp = (int *) *xpp;
12923
    }
12924
   /* update xpp and tp */
12925
    xp += ni;
12926
    tp += ni;
12927
    *xpp = (void*)xp;
12928
  }
12929
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12930
12931
#else   /* not SX */
12932
12933
0
  char *xp = (char *) *xpp;
12934
0
  int status = NC_NOERR;
12935
12936
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12937
0
  {
12938
0
    int lstatus = ncx_put_int_uchar(xp, tp, fillp);
12939
0
    if (status == NC_NOERR) /* report the first encountered error */
12940
0
      status = lstatus;
12941
0
  }
12942
12943
0
  *xpp = (void *)xp;
12944
0
  return status;
12945
0
#endif
12946
0
}
12947
12948
int
12949
ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
12950
0
{
12951
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12952
12953
 /* basic algorithm is:
12954
  *   - ensure sane alignment of output data
12955
  *   - copy (conversion happens automatically) input data
12956
  *     to output
12957
  *   - update tp to point at next unconverted input, and xpp to point
12958
  *     at next location for converted output
12959
  */
12960
  long i, j, ni;
12961
  int tmp[LOOPCNT];        /* in case input is misaligned */
12962
  int *xp;
12963
  int nrange = 0;         /* number of range errors */
12964
  int realign = 0;        /* "do we need to fix input data alignment?" */
12965
  long cxp = (long) *((char**)xpp);
12966
12967
  realign = (cxp & 7) % SIZEOF_INT;
12968
  /* sjl: manually stripmine so we can limit amount of
12969
   * vector work space reserved to LOOPCNT elements. Also
12970
   * makes vectorisation easy */
12971
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12972
    ni=Min(nelems-j,LOOPCNT);
12973
    if (realign) {
12974
      xp = tmp;
12975
    } else {
12976
      xp = (int *) *xpp;
12977
    }
12978
   /* copy the next block */
12979
#pragma cdir loopcnt=LOOPCNT
12980
#pragma cdir shortloop
12981
    for (i=0; i<ni; i++) {
12982
      /* the normal case: */
12983
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12984
     /* test for range errors (not always needed but do it anyway) */
12985
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12986
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12987
      nrange += tp[i] > X_INT_MAX ;
12988
    }
12989
   /* copy workspace back if necessary */
12990
    if (realign) {
12991
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12992
      xp = (int *) *xpp;
12993
    }
12994
   /* update xpp and tp */
12995
    xp += ni;
12996
    tp += ni;
12997
    *xpp = (void*)xp;
12998
  }
12999
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13000
13001
#else   /* not SX */
13002
13003
0
  char *xp = (char *) *xpp;
13004
0
  int status = NC_NOERR;
13005
13006
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13007
0
  {
13008
0
    int lstatus = ncx_put_int_ushort(xp, tp, fillp);
13009
0
    if (status == NC_NOERR) /* report the first encountered error */
13010
0
      status = lstatus;
13011
0
  }
13012
13013
0
  *xpp = (void *)xp;
13014
0
  return status;
13015
0
#endif
13016
0
}
13017
13018
int
13019
ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13020
0
{
13021
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13022
13023
 /* basic algorithm is:
13024
  *   - ensure sane alignment of output data
13025
  *   - copy (conversion happens automatically) input data
13026
  *     to output
13027
  *   - update tp to point at next unconverted input, and xpp to point
13028
  *     at next location for converted output
13029
  */
13030
  long i, j, ni;
13031
  int tmp[LOOPCNT];        /* in case input is misaligned */
13032
  int *xp;
13033
  int nrange = 0;         /* number of range errors */
13034
  int realign = 0;        /* "do we need to fix input data alignment?" */
13035
  long cxp = (long) *((char**)xpp);
13036
13037
  realign = (cxp & 7) % SIZEOF_INT;
13038
  /* sjl: manually stripmine so we can limit amount of
13039
   * vector work space reserved to LOOPCNT elements. Also
13040
   * makes vectorisation easy */
13041
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13042
    ni=Min(nelems-j,LOOPCNT);
13043
    if (realign) {
13044
      xp = tmp;
13045
    } else {
13046
      xp = (int *) *xpp;
13047
    }
13048
   /* copy the next block */
13049
#pragma cdir loopcnt=LOOPCNT
13050
#pragma cdir shortloop
13051
    for (i=0; i<ni; i++) {
13052
      /* the normal case: */
13053
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13054
     /* test for range errors (not always needed but do it anyway) */
13055
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13056
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13057
      nrange += tp[i] > X_INT_MAX ;
13058
    }
13059
   /* copy workspace back if necessary */
13060
    if (realign) {
13061
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13062
      xp = (int *) *xpp;
13063
    }
13064
   /* update xpp and tp */
13065
    xp += ni;
13066
    tp += ni;
13067
    *xpp = (void*)xp;
13068
  }
13069
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13070
13071
#else   /* not SX */
13072
13073
0
  char *xp = (char *) *xpp;
13074
0
  int status = NC_NOERR;
13075
13076
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13077
0
  {
13078
0
    int lstatus = ncx_put_int_uint(xp, tp, fillp);
13079
0
    if (status == NC_NOERR) /* report the first encountered error */
13080
0
      status = lstatus;
13081
0
  }
13082
13083
0
  *xpp = (void *)xp;
13084
0
  return status;
13085
0
#endif
13086
0
}
13087
13088
int
13089
ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
13090
0
{
13091
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13092
13093
 /* basic algorithm is:
13094
  *   - ensure sane alignment of output data
13095
  *   - copy (conversion happens automatically) input data
13096
  *     to output
13097
  *   - update tp to point at next unconverted input, and xpp to point
13098
  *     at next location for converted output
13099
  */
13100
  long i, j, ni;
13101
  int tmp[LOOPCNT];        /* in case input is misaligned */
13102
  int *xp;
13103
  int nrange = 0;         /* number of range errors */
13104
  int realign = 0;        /* "do we need to fix input data alignment?" */
13105
  long cxp = (long) *((char**)xpp);
13106
13107
  realign = (cxp & 7) % SIZEOF_INT;
13108
  /* sjl: manually stripmine so we can limit amount of
13109
   * vector work space reserved to LOOPCNT elements. Also
13110
   * makes vectorisation easy */
13111
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13112
    ni=Min(nelems-j,LOOPCNT);
13113
    if (realign) {
13114
      xp = tmp;
13115
    } else {
13116
      xp = (int *) *xpp;
13117
    }
13118
   /* copy the next block */
13119
#pragma cdir loopcnt=LOOPCNT
13120
#pragma cdir shortloop
13121
    for (i=0; i<ni; i++) {
13122
      /* the normal case: */
13123
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13124
     /* test for range errors (not always needed but do it anyway) */
13125
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13126
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13127
      nrange += tp[i] > X_INT_MAX ;
13128
    }
13129
   /* copy workspace back if necessary */
13130
    if (realign) {
13131
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13132
      xp = (int *) *xpp;
13133
    }
13134
   /* update xpp and tp */
13135
    xp += ni;
13136
    tp += ni;
13137
    *xpp = (void*)xp;
13138
  }
13139
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13140
13141
#else   /* not SX */
13142
13143
0
  char *xp = (char *) *xpp;
13144
0
  int status = NC_NOERR;
13145
13146
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13147
0
  {
13148
0
    int lstatus = ncx_put_int_ulonglong(xp, tp, fillp);
13149
0
    if (status == NC_NOERR) /* report the first encountered error */
13150
0
      status = lstatus;
13151
0
  }
13152
13153
0
  *xpp = (void *)xp;
13154
0
  return status;
13155
0
#endif
13156
0
}
13157
13158
13159
/* uint ----------------------------------------------------------------------*/
13160
13161
#if X_SIZEOF_UINT == SIZEOF_UINT
13162
/* optimized version */
13163
int
13164
ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
13165
0
{
13166
#ifdef WORDS_BIGENDIAN
13167
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
13168
# else
13169
0
  swapn4b(tp, *xpp, nelems);
13170
0
# endif
13171
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
13172
0
  return NC_NOERR;
13173
0
}
13174
#else
13175
int
13176
ncx_getn_uint_uint(const void **xpp, size_t nelems, uint *tp)
13177
{
13178
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13179
13180
 /* basic algorithm is:
13181
  *   - ensure sane alignment of input data
13182
  *   - copy (conversion happens automatically) input data
13183
  *     to output
13184
  *   - update xpp to point at next unconverted input, and tp to point
13185
  *     at next location for converted output
13186
  */
13187
  long i, j, ni;
13188
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13189
  uint *xp;
13190
  int nrange = 0;         /* number of range errors */
13191
  int realign = 0;        /* "do we need to fix input data alignment?" */
13192
  long cxp = (long) *((char**)xpp);
13193
13194
  realign = (cxp & 7) % SIZEOF_UINT;
13195
  /* sjl: manually stripmine so we can limit amount of
13196
   * vector work space reserved to LOOPCNT elements. Also
13197
   * makes vectorisation easy */
13198
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13199
    ni=Min(nelems-j,LOOPCNT);
13200
    if (realign) {
13201
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13202
      xp = tmp;
13203
    } else {
13204
      xp = (uint *) *xpp;
13205
    }
13206
   /* copy the next block */
13207
#pragma cdir loopcnt=LOOPCNT
13208
#pragma cdir shortloop
13209
    for (i=0; i<ni; i++) {
13210
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
13211
     /* test for range errors (not always needed but do it anyway) */
13212
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13213
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13214
      nrange += xp[i] > UINT_MAX ;
13215
    }
13216
   /* update xpp and tp */
13217
    if (realign) xp = (uint *) *xpp;
13218
    xp += ni;
13219
    tp += ni;
13220
    *xpp = (void*)xp;
13221
  }
13222
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13223
13224
#else   /* not SX */
13225
  const char *xp = (const char *) *xpp;
13226
  int status = NC_NOERR;
13227
13228
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13229
  {
13230
    const int lstatus = ncx_get_uint_uint(xp, tp);
13231
    if (status == NC_NOERR) /* report the first encountered error */
13232
      status = lstatus;
13233
  }
13234
13235
  *xpp = (const void *)xp;
13236
  return status;
13237
#endif
13238
}
13239
13240
#endif
13241
int
13242
ncx_getn_uint_schar(const void **xpp, size_t nelems, schar *tp)
13243
0
{
13244
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13245
13246
 /* basic algorithm is:
13247
  *   - ensure sane alignment of input data
13248
  *   - copy (conversion happens automatically) input data
13249
  *     to output
13250
  *   - update xpp to point at next unconverted input, and tp to point
13251
  *     at next location for converted output
13252
  */
13253
  long i, j, ni;
13254
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13255
  uint *xp;
13256
  int nrange = 0;         /* number of range errors */
13257
  int realign = 0;        /* "do we need to fix input data alignment?" */
13258
  long cxp = (long) *((char**)xpp);
13259
13260
  realign = (cxp & 7) % SIZEOF_UINT;
13261
  /* sjl: manually stripmine so we can limit amount of
13262
   * vector work space reserved to LOOPCNT elements. Also
13263
   * makes vectorisation easy */
13264
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13265
    ni=Min(nelems-j,LOOPCNT);
13266
    if (realign) {
13267
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13268
      xp = tmp;
13269
    } else {
13270
      xp = (uint *) *xpp;
13271
    }
13272
   /* copy the next block */
13273
#pragma cdir loopcnt=LOOPCNT
13274
#pragma cdir shortloop
13275
    for (i=0; i<ni; i++) {
13276
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
13277
     /* test for range errors (not always needed but do it anyway) */
13278
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13279
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13280
      nrange += xp[i] > SCHAR_MAX ;
13281
    }
13282
   /* update xpp and tp */
13283
    if (realign) xp = (uint *) *xpp;
13284
    xp += ni;
13285
    tp += ni;
13286
    *xpp = (void*)xp;
13287
  }
13288
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13289
13290
#else   /* not SX */
13291
0
  const char *xp = (const char *) *xpp;
13292
0
  int status = NC_NOERR;
13293
13294
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13295
0
  {
13296
0
    const int lstatus = ncx_get_uint_schar(xp, tp);
13297
0
    if (status == NC_NOERR) /* report the first encountered error */
13298
0
      status = lstatus;
13299
0
  }
13300
13301
0
  *xpp = (const void *)xp;
13302
0
  return status;
13303
0
#endif
13304
0
}
13305
13306
int
13307
ncx_getn_uint_short(const void **xpp, size_t nelems, short *tp)
13308
0
{
13309
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13310
13311
 /* basic algorithm is:
13312
  *   - ensure sane alignment of input data
13313
  *   - copy (conversion happens automatically) input data
13314
  *     to output
13315
  *   - update xpp to point at next unconverted input, and tp to point
13316
  *     at next location for converted output
13317
  */
13318
  long i, j, ni;
13319
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13320
  uint *xp;
13321
  int nrange = 0;         /* number of range errors */
13322
  int realign = 0;        /* "do we need to fix input data alignment?" */
13323
  long cxp = (long) *((char**)xpp);
13324
13325
  realign = (cxp & 7) % SIZEOF_UINT;
13326
  /* sjl: manually stripmine so we can limit amount of
13327
   * vector work space reserved to LOOPCNT elements. Also
13328
   * makes vectorisation easy */
13329
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13330
    ni=Min(nelems-j,LOOPCNT);
13331
    if (realign) {
13332
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13333
      xp = tmp;
13334
    } else {
13335
      xp = (uint *) *xpp;
13336
    }
13337
   /* copy the next block */
13338
#pragma cdir loopcnt=LOOPCNT
13339
#pragma cdir shortloop
13340
    for (i=0; i<ni; i++) {
13341
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
13342
     /* test for range errors (not always needed but do it anyway) */
13343
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13344
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13345
      nrange += xp[i] > SHORT_MAX ;
13346
    }
13347
   /* update xpp and tp */
13348
    if (realign) xp = (uint *) *xpp;
13349
    xp += ni;
13350
    tp += ni;
13351
    *xpp = (void*)xp;
13352
  }
13353
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13354
13355
#else   /* not SX */
13356
0
  const char *xp = (const char *) *xpp;
13357
0
  int status = NC_NOERR;
13358
13359
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13360
0
  {
13361
0
    const int lstatus = ncx_get_uint_short(xp, tp);
13362
0
    if (status == NC_NOERR) /* report the first encountered error */
13363
0
      status = lstatus;
13364
0
  }
13365
13366
0
  *xpp = (const void *)xp;
13367
0
  return status;
13368
0
#endif
13369
0
}
13370
13371
int
13372
ncx_getn_uint_int(const void **xpp, size_t nelems, int *tp)
13373
0
{
13374
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13375
13376
 /* basic algorithm is:
13377
  *   - ensure sane alignment of input data
13378
  *   - copy (conversion happens automatically) input data
13379
  *     to output
13380
  *   - update xpp to point at next unconverted input, and tp to point
13381
  *     at next location for converted output
13382
  */
13383
  long i, j, ni;
13384
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13385
  uint *xp;
13386
  int nrange = 0;         /* number of range errors */
13387
  int realign = 0;        /* "do we need to fix input data alignment?" */
13388
  long cxp = (long) *((char**)xpp);
13389
13390
  realign = (cxp & 7) % SIZEOF_UINT;
13391
  /* sjl: manually stripmine so we can limit amount of
13392
   * vector work space reserved to LOOPCNT elements. Also
13393
   * makes vectorisation easy */
13394
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13395
    ni=Min(nelems-j,LOOPCNT);
13396
    if (realign) {
13397
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13398
      xp = tmp;
13399
    } else {
13400
      xp = (uint *) *xpp;
13401
    }
13402
   /* copy the next block */
13403
#pragma cdir loopcnt=LOOPCNT
13404
#pragma cdir shortloop
13405
    for (i=0; i<ni; i++) {
13406
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
13407
     /* test for range errors (not always needed but do it anyway) */
13408
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13409
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13410
      nrange += xp[i] > INT_MAX ;
13411
    }
13412
   /* update xpp and tp */
13413
    if (realign) xp = (uint *) *xpp;
13414
    xp += ni;
13415
    tp += ni;
13416
    *xpp = (void*)xp;
13417
  }
13418
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13419
13420
#else   /* not SX */
13421
0
  const char *xp = (const char *) *xpp;
13422
0
  int status = NC_NOERR;
13423
13424
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13425
0
  {
13426
0
    const int lstatus = ncx_get_uint_int(xp, tp);
13427
0
    if (status == NC_NOERR) /* report the first encountered error */
13428
0
      status = lstatus;
13429
0
  }
13430
13431
0
  *xpp = (const void *)xp;
13432
0
  return status;
13433
0
#endif
13434
0
}
13435
13436
int
13437
ncx_getn_uint_long(const void **xpp, size_t nelems, long *tp)
13438
0
{
13439
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13440
13441
 /* basic algorithm is:
13442
  *   - ensure sane alignment of input data
13443
  *   - copy (conversion happens automatically) input data
13444
  *     to output
13445
  *   - update xpp to point at next unconverted input, and tp to point
13446
  *     at next location for converted output
13447
  */
13448
  long i, j, ni;
13449
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13450
  uint *xp;
13451
  int nrange = 0;         /* number of range errors */
13452
  int realign = 0;        /* "do we need to fix input data alignment?" */
13453
  long cxp = (long) *((char**)xpp);
13454
13455
  realign = (cxp & 7) % SIZEOF_UINT;
13456
  /* sjl: manually stripmine so we can limit amount of
13457
   * vector work space reserved to LOOPCNT elements. Also
13458
   * makes vectorisation easy */
13459
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13460
    ni=Min(nelems-j,LOOPCNT);
13461
    if (realign) {
13462
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13463
      xp = tmp;
13464
    } else {
13465
      xp = (uint *) *xpp;
13466
    }
13467
   /* copy the next block */
13468
#pragma cdir loopcnt=LOOPCNT
13469
#pragma cdir shortloop
13470
    for (i=0; i<ni; i++) {
13471
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
13472
     /* test for range errors (not always needed but do it anyway) */
13473
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13474
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13475
      nrange += xp[i] > LONG_MAX ;
13476
    }
13477
   /* update xpp and tp */
13478
    if (realign) xp = (uint *) *xpp;
13479
    xp += ni;
13480
    tp += ni;
13481
    *xpp = (void*)xp;
13482
  }
13483
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13484
13485
#else   /* not SX */
13486
0
  const char *xp = (const char *) *xpp;
13487
0
  int status = NC_NOERR;
13488
13489
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13490
0
  {
13491
0
    const int lstatus = ncx_get_uint_long(xp, tp);
13492
0
    if (status == NC_NOERR) /* report the first encountered error */
13493
0
      status = lstatus;
13494
0
  }
13495
13496
0
  *xpp = (const void *)xp;
13497
0
  return status;
13498
0
#endif
13499
0
}
13500
13501
int
13502
ncx_getn_uint_float(const void **xpp, size_t nelems, float *tp)
13503
0
{
13504
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13505
13506
 /* basic algorithm is:
13507
  *   - ensure sane alignment of input data
13508
  *   - copy (conversion happens automatically) input data
13509
  *     to output
13510
  *   - update xpp to point at next unconverted input, and tp to point
13511
  *     at next location for converted output
13512
  */
13513
  long i, j, ni;
13514
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13515
  uint *xp;
13516
  int nrange = 0;         /* number of range errors */
13517
  int realign = 0;        /* "do we need to fix input data alignment?" */
13518
  long cxp = (long) *((char**)xpp);
13519
13520
  realign = (cxp & 7) % SIZEOF_UINT;
13521
  /* sjl: manually stripmine so we can limit amount of
13522
   * vector work space reserved to LOOPCNT elements. Also
13523
   * makes vectorisation easy */
13524
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13525
    ni=Min(nelems-j,LOOPCNT);
13526
    if (realign) {
13527
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13528
      xp = tmp;
13529
    } else {
13530
      xp = (uint *) *xpp;
13531
    }
13532
   /* copy the next block */
13533
#pragma cdir loopcnt=LOOPCNT
13534
#pragma cdir shortloop
13535
    for (i=0; i<ni; i++) {
13536
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
13537
     /* test for range errors (not always needed but do it anyway) */
13538
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13539
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13540
      nrange += xp[i] > FLOAT_MAX ;
13541
    }
13542
   /* update xpp and tp */
13543
    if (realign) xp = (uint *) *xpp;
13544
    xp += ni;
13545
    tp += ni;
13546
    *xpp = (void*)xp;
13547
  }
13548
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13549
13550
#else   /* not SX */
13551
0
  const char *xp = (const char *) *xpp;
13552
0
  int status = NC_NOERR;
13553
13554
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13555
0
  {
13556
0
    const int lstatus = ncx_get_uint_float(xp, tp);
13557
0
    if (status == NC_NOERR) /* report the first encountered error */
13558
0
      status = lstatus;
13559
0
  }
13560
13561
0
  *xpp = (const void *)xp;
13562
0
  return status;
13563
0
#endif
13564
0
}
13565
13566
int
13567
ncx_getn_uint_double(const void **xpp, size_t nelems, double *tp)
13568
0
{
13569
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13570
13571
 /* basic algorithm is:
13572
  *   - ensure sane alignment of input data
13573
  *   - copy (conversion happens automatically) input data
13574
  *     to output
13575
  *   - update xpp to point at next unconverted input, and tp to point
13576
  *     at next location for converted output
13577
  */
13578
  long i, j, ni;
13579
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13580
  uint *xp;
13581
  int nrange = 0;         /* number of range errors */
13582
  int realign = 0;        /* "do we need to fix input data alignment?" */
13583
  long cxp = (long) *((char**)xpp);
13584
13585
  realign = (cxp & 7) % SIZEOF_UINT;
13586
  /* sjl: manually stripmine so we can limit amount of
13587
   * vector work space reserved to LOOPCNT elements. Also
13588
   * makes vectorisation easy */
13589
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13590
    ni=Min(nelems-j,LOOPCNT);
13591
    if (realign) {
13592
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13593
      xp = tmp;
13594
    } else {
13595
      xp = (uint *) *xpp;
13596
    }
13597
   /* copy the next block */
13598
#pragma cdir loopcnt=LOOPCNT
13599
#pragma cdir shortloop
13600
    for (i=0; i<ni; i++) {
13601
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
13602
     /* test for range errors (not always needed but do it anyway) */
13603
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13604
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13605
      nrange += xp[i] > DOUBLE_MAX ;
13606
    }
13607
   /* update xpp and tp */
13608
    if (realign) xp = (uint *) *xpp;
13609
    xp += ni;
13610
    tp += ni;
13611
    *xpp = (void*)xp;
13612
  }
13613
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13614
13615
#else   /* not SX */
13616
0
  const char *xp = (const char *) *xpp;
13617
0
  int status = NC_NOERR;
13618
13619
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13620
0
  {
13621
0
    const int lstatus = ncx_get_uint_double(xp, tp);
13622
0
    if (status == NC_NOERR) /* report the first encountered error */
13623
0
      status = lstatus;
13624
0
  }
13625
13626
0
  *xpp = (const void *)xp;
13627
0
  return status;
13628
0
#endif
13629
0
}
13630
13631
int
13632
ncx_getn_uint_longlong(const void **xpp, size_t nelems, longlong *tp)
13633
0
{
13634
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13635
13636
 /* basic algorithm is:
13637
  *   - ensure sane alignment of input data
13638
  *   - copy (conversion happens automatically) input data
13639
  *     to output
13640
  *   - update xpp to point at next unconverted input, and tp to point
13641
  *     at next location for converted output
13642
  */
13643
  long i, j, ni;
13644
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13645
  uint *xp;
13646
  int nrange = 0;         /* number of range errors */
13647
  int realign = 0;        /* "do we need to fix input data alignment?" */
13648
  long cxp = (long) *((char**)xpp);
13649
13650
  realign = (cxp & 7) % SIZEOF_UINT;
13651
  /* sjl: manually stripmine so we can limit amount of
13652
   * vector work space reserved to LOOPCNT elements. Also
13653
   * makes vectorisation easy */
13654
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13655
    ni=Min(nelems-j,LOOPCNT);
13656
    if (realign) {
13657
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13658
      xp = tmp;
13659
    } else {
13660
      xp = (uint *) *xpp;
13661
    }
13662
   /* copy the next block */
13663
#pragma cdir loopcnt=LOOPCNT
13664
#pragma cdir shortloop
13665
    for (i=0; i<ni; i++) {
13666
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
13667
     /* test for range errors (not always needed but do it anyway) */
13668
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13669
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13670
      nrange += xp[i] > LONGLONG_MAX ;
13671
    }
13672
   /* update xpp and tp */
13673
    if (realign) xp = (uint *) *xpp;
13674
    xp += ni;
13675
    tp += ni;
13676
    *xpp = (void*)xp;
13677
  }
13678
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13679
13680
#else   /* not SX */
13681
0
  const char *xp = (const char *) *xpp;
13682
0
  int status = NC_NOERR;
13683
13684
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13685
0
  {
13686
0
    const int lstatus = ncx_get_uint_longlong(xp, tp);
13687
0
    if (status == NC_NOERR) /* report the first encountered error */
13688
0
      status = lstatus;
13689
0
  }
13690
13691
0
  *xpp = (const void *)xp;
13692
0
  return status;
13693
0
#endif
13694
0
}
13695
13696
int
13697
ncx_getn_uint_uchar(const void **xpp, size_t nelems, uchar *tp)
13698
0
{
13699
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13700
13701
 /* basic algorithm is:
13702
  *   - ensure sane alignment of input data
13703
  *   - copy (conversion happens automatically) input data
13704
  *     to output
13705
  *   - update xpp to point at next unconverted input, and tp to point
13706
  *     at next location for converted output
13707
  */
13708
  long i, j, ni;
13709
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13710
  uint *xp;
13711
  int nrange = 0;         /* number of range errors */
13712
  int realign = 0;        /* "do we need to fix input data alignment?" */
13713
  long cxp = (long) *((char**)xpp);
13714
13715
  realign = (cxp & 7) % SIZEOF_UINT;
13716
  /* sjl: manually stripmine so we can limit amount of
13717
   * vector work space reserved to LOOPCNT elements. Also
13718
   * makes vectorisation easy */
13719
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13720
    ni=Min(nelems-j,LOOPCNT);
13721
    if (realign) {
13722
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13723
      xp = tmp;
13724
    } else {
13725
      xp = (uint *) *xpp;
13726
    }
13727
   /* copy the next block */
13728
#pragma cdir loopcnt=LOOPCNT
13729
#pragma cdir shortloop
13730
    for (i=0; i<ni; i++) {
13731
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
13732
     /* test for range errors (not always needed but do it anyway) */
13733
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13734
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13735
      nrange += xp[i] > UCHAR_MAX ;
13736
    }
13737
   /* update xpp and tp */
13738
    if (realign) xp = (uint *) *xpp;
13739
    xp += ni;
13740
    tp += ni;
13741
    *xpp = (void*)xp;
13742
  }
13743
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13744
13745
#else   /* not SX */
13746
0
  const char *xp = (const char *) *xpp;
13747
0
  int status = NC_NOERR;
13748
13749
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13750
0
  {
13751
0
    const int lstatus = ncx_get_uint_uchar(xp, tp);
13752
0
    if (status == NC_NOERR) /* report the first encountered error */
13753
0
      status = lstatus;
13754
0
  }
13755
13756
0
  *xpp = (const void *)xp;
13757
0
  return status;
13758
0
#endif
13759
0
}
13760
13761
int
13762
ncx_getn_uint_ushort(const void **xpp, size_t nelems, ushort *tp)
13763
0
{
13764
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13765
13766
 /* basic algorithm is:
13767
  *   - ensure sane alignment of input data
13768
  *   - copy (conversion happens automatically) input data
13769
  *     to output
13770
  *   - update xpp to point at next unconverted input, and tp to point
13771
  *     at next location for converted output
13772
  */
13773
  long i, j, ni;
13774
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13775
  uint *xp;
13776
  int nrange = 0;         /* number of range errors */
13777
  int realign = 0;        /* "do we need to fix input data alignment?" */
13778
  long cxp = (long) *((char**)xpp);
13779
13780
  realign = (cxp & 7) % SIZEOF_UINT;
13781
  /* sjl: manually stripmine so we can limit amount of
13782
   * vector work space reserved to LOOPCNT elements. Also
13783
   * makes vectorisation easy */
13784
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13785
    ni=Min(nelems-j,LOOPCNT);
13786
    if (realign) {
13787
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13788
      xp = tmp;
13789
    } else {
13790
      xp = (uint *) *xpp;
13791
    }
13792
   /* copy the next block */
13793
#pragma cdir loopcnt=LOOPCNT
13794
#pragma cdir shortloop
13795
    for (i=0; i<ni; i++) {
13796
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
13797
     /* test for range errors (not always needed but do it anyway) */
13798
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13799
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13800
      nrange += xp[i] > USHORT_MAX ;
13801
    }
13802
   /* update xpp and tp */
13803
    if (realign) xp = (uint *) *xpp;
13804
    xp += ni;
13805
    tp += ni;
13806
    *xpp = (void*)xp;
13807
  }
13808
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13809
13810
#else   /* not SX */
13811
0
  const char *xp = (const char *) *xpp;
13812
0
  int status = NC_NOERR;
13813
13814
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13815
0
  {
13816
0
    const int lstatus = ncx_get_uint_ushort(xp, tp);
13817
0
    if (status == NC_NOERR) /* report the first encountered error */
13818
0
      status = lstatus;
13819
0
  }
13820
13821
0
  *xpp = (const void *)xp;
13822
0
  return status;
13823
0
#endif
13824
0
}
13825
13826
int
13827
ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
13828
0
{
13829
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13830
13831
 /* basic algorithm is:
13832
  *   - ensure sane alignment of input data
13833
  *   - copy (conversion happens automatically) input data
13834
  *     to output
13835
  *   - update xpp to point at next unconverted input, and tp to point
13836
  *     at next location for converted output
13837
  */
13838
  long i, j, ni;
13839
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13840
  uint *xp;
13841
  int nrange = 0;         /* number of range errors */
13842
  int realign = 0;        /* "do we need to fix input data alignment?" */
13843
  long cxp = (long) *((char**)xpp);
13844
13845
  realign = (cxp & 7) % SIZEOF_UINT;
13846
  /* sjl: manually stripmine so we can limit amount of
13847
   * vector work space reserved to LOOPCNT elements. Also
13848
   * makes vectorisation easy */
13849
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13850
    ni=Min(nelems-j,LOOPCNT);
13851
    if (realign) {
13852
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13853
      xp = tmp;
13854
    } else {
13855
      xp = (uint *) *xpp;
13856
    }
13857
   /* copy the next block */
13858
#pragma cdir loopcnt=LOOPCNT
13859
#pragma cdir shortloop
13860
    for (i=0; i<ni; i++) {
13861
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
13862
     /* test for range errors (not always needed but do it anyway) */
13863
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13864
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13865
      nrange += xp[i] > ULONGLONG_MAX ;
13866
    }
13867
   /* update xpp and tp */
13868
    if (realign) xp = (uint *) *xpp;
13869
    xp += ni;
13870
    tp += ni;
13871
    *xpp = (void*)xp;
13872
  }
13873
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13874
13875
#else   /* not SX */
13876
0
  const char *xp = (const char *) *xpp;
13877
0
  int status = NC_NOERR;
13878
13879
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13880
0
  {
13881
0
    const int lstatus = ncx_get_uint_ulonglong(xp, tp);
13882
0
    if (status == NC_NOERR) /* report the first encountered error */
13883
0
      status = lstatus;
13884
0
  }
13885
13886
0
  *xpp = (const void *)xp;
13887
0
  return status;
13888
0
#endif
13889
0
}
13890
13891
13892
#if X_SIZEOF_UINT == SIZEOF_UINT
13893
/* optimized version */
13894
int
13895
ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp, void *fillp)
13896
0
{
13897
#ifdef WORDS_BIGENDIAN
13898
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
13899
# else
13900
0
  swapn4b(*xpp, tp, nelems);
13901
0
# endif
13902
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
13903
0
  return NC_NOERR;
13904
0
}
13905
#else
13906
int
13907
ncx_putn_uint_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13908
{
13909
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13910
13911
 /* basic algorithm is:
13912
  *   - ensure sane alignment of output data
13913
  *   - copy (conversion happens automatically) input data
13914
  *     to output
13915
  *   - update tp to point at next unconverted input, and xpp to point
13916
  *     at next location for converted output
13917
  */
13918
  long i, j, ni;
13919
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13920
  uint *xp;
13921
  int nrange = 0;         /* number of range errors */
13922
  int realign = 0;        /* "do we need to fix input data alignment?" */
13923
  long cxp = (long) *((char**)xpp);
13924
13925
  realign = (cxp & 7) % SIZEOF_UINT;
13926
  /* sjl: manually stripmine so we can limit amount of
13927
   * vector work space reserved to LOOPCNT elements. Also
13928
   * makes vectorisation easy */
13929
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13930
    ni=Min(nelems-j,LOOPCNT);
13931
    if (realign) {
13932
      xp = tmp;
13933
    } else {
13934
      xp = (uint *) *xpp;
13935
    }
13936
   /* copy the next block */
13937
#pragma cdir loopcnt=LOOPCNT
13938
#pragma cdir shortloop
13939
    for (i=0; i<ni; i++) {
13940
      /* the normal case: */
13941
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
13942
     /* test for range errors (not always needed but do it anyway) */
13943
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13944
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13945
      nrange += tp[i] > X_UINT_MAX ;
13946
    }
13947
   /* copy workspace back if necessary */
13948
    if (realign) {
13949
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
13950
      xp = (uint *) *xpp;
13951
    }
13952
   /* update xpp and tp */
13953
    xp += ni;
13954
    tp += ni;
13955
    *xpp = (void*)xp;
13956
  }
13957
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13958
13959
#else   /* not SX */
13960
13961
  char *xp = (char *) *xpp;
13962
  int status = NC_NOERR;
13963
13964
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13965
  {
13966
    int lstatus = ncx_put_uint_uint(xp, tp, fillp);
13967
    if (status == NC_NOERR) /* report the first encountered error */
13968
      status = lstatus;
13969
  }
13970
13971
  *xpp = (void *)xp;
13972
  return status;
13973
#endif
13974
}
13975
13976
#endif
13977
int
13978
ncx_putn_uint_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
13979
0
{
13980
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13981
13982
 /* basic algorithm is:
13983
  *   - ensure sane alignment of output data
13984
  *   - copy (conversion happens automatically) input data
13985
  *     to output
13986
  *   - update tp to point at next unconverted input, and xpp to point
13987
  *     at next location for converted output
13988
  */
13989
  long i, j, ni;
13990
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13991
  uint *xp;
13992
  int nrange = 0;         /* number of range errors */
13993
  int realign = 0;        /* "do we need to fix input data alignment?" */
13994
  long cxp = (long) *((char**)xpp);
13995
13996
  realign = (cxp & 7) % SIZEOF_UINT;
13997
  /* sjl: manually stripmine so we can limit amount of
13998
   * vector work space reserved to LOOPCNT elements. Also
13999
   * makes vectorisation easy */
14000
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14001
    ni=Min(nelems-j,LOOPCNT);
14002
    if (realign) {
14003
      xp = tmp;
14004
    } else {
14005
      xp = (uint *) *xpp;
14006
    }
14007
   /* copy the next block */
14008
#pragma cdir loopcnt=LOOPCNT
14009
#pragma cdir shortloop
14010
    for (i=0; i<ni; i++) {
14011
      /* the normal case: */
14012
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14013
     /* test for range errors (not always needed but do it anyway) */
14014
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14015
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14016
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14017
    }
14018
   /* copy workspace back if necessary */
14019
    if (realign) {
14020
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14021
      xp = (uint *) *xpp;
14022
    }
14023
   /* update xpp and tp */
14024
    xp += ni;
14025
    tp += ni;
14026
    *xpp = (void*)xp;
14027
  }
14028
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14029
14030
#else   /* not SX */
14031
14032
0
  char *xp = (char *) *xpp;
14033
0
  int status = NC_NOERR;
14034
14035
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14036
0
  {
14037
0
    int lstatus = ncx_put_uint_schar(xp, tp, fillp);
14038
0
    if (status == NC_NOERR) /* report the first encountered error */
14039
0
      status = lstatus;
14040
0
  }
14041
14042
0
  *xpp = (void *)xp;
14043
0
  return status;
14044
0
#endif
14045
0
}
14046
14047
int
14048
ncx_putn_uint_short(void **xpp, size_t nelems, const short *tp, void *fillp)
14049
0
{
14050
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14051
14052
 /* basic algorithm is:
14053
  *   - ensure sane alignment of output data
14054
  *   - copy (conversion happens automatically) input data
14055
  *     to output
14056
  *   - update tp to point at next unconverted input, and xpp to point
14057
  *     at next location for converted output
14058
  */
14059
  long i, j, ni;
14060
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14061
  uint *xp;
14062
  int nrange = 0;         /* number of range errors */
14063
  int realign = 0;        /* "do we need to fix input data alignment?" */
14064
  long cxp = (long) *((char**)xpp);
14065
14066
  realign = (cxp & 7) % SIZEOF_UINT;
14067
  /* sjl: manually stripmine so we can limit amount of
14068
   * vector work space reserved to LOOPCNT elements. Also
14069
   * makes vectorisation easy */
14070
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14071
    ni=Min(nelems-j,LOOPCNT);
14072
    if (realign) {
14073
      xp = tmp;
14074
    } else {
14075
      xp = (uint *) *xpp;
14076
    }
14077
   /* copy the next block */
14078
#pragma cdir loopcnt=LOOPCNT
14079
#pragma cdir shortloop
14080
    for (i=0; i<ni; i++) {
14081
      /* the normal case: */
14082
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14083
     /* test for range errors (not always needed but do it anyway) */
14084
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14085
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14086
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14087
    }
14088
   /* copy workspace back if necessary */
14089
    if (realign) {
14090
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14091
      xp = (uint *) *xpp;
14092
    }
14093
   /* update xpp and tp */
14094
    xp += ni;
14095
    tp += ni;
14096
    *xpp = (void*)xp;
14097
  }
14098
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14099
14100
#else   /* not SX */
14101
14102
0
  char *xp = (char *) *xpp;
14103
0
  int status = NC_NOERR;
14104
14105
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14106
0
  {
14107
0
    int lstatus = ncx_put_uint_short(xp, tp, fillp);
14108
0
    if (status == NC_NOERR) /* report the first encountered error */
14109
0
      status = lstatus;
14110
0
  }
14111
14112
0
  *xpp = (void *)xp;
14113
0
  return status;
14114
0
#endif
14115
0
}
14116
14117
int
14118
ncx_putn_uint_int(void **xpp, size_t nelems, const int *tp, void *fillp)
14119
0
{
14120
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14121
14122
 /* basic algorithm is:
14123
  *   - ensure sane alignment of output data
14124
  *   - copy (conversion happens automatically) input data
14125
  *     to output
14126
  *   - update tp to point at next unconverted input, and xpp to point
14127
  *     at next location for converted output
14128
  */
14129
  long i, j, ni;
14130
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14131
  uint *xp;
14132
  int nrange = 0;         /* number of range errors */
14133
  int realign = 0;        /* "do we need to fix input data alignment?" */
14134
  long cxp = (long) *((char**)xpp);
14135
14136
  realign = (cxp & 7) % SIZEOF_UINT;
14137
  /* sjl: manually stripmine so we can limit amount of
14138
   * vector work space reserved to LOOPCNT elements. Also
14139
   * makes vectorisation easy */
14140
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14141
    ni=Min(nelems-j,LOOPCNT);
14142
    if (realign) {
14143
      xp = tmp;
14144
    } else {
14145
      xp = (uint *) *xpp;
14146
    }
14147
   /* copy the next block */
14148
#pragma cdir loopcnt=LOOPCNT
14149
#pragma cdir shortloop
14150
    for (i=0; i<ni; i++) {
14151
      /* the normal case: */
14152
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14153
     /* test for range errors (not always needed but do it anyway) */
14154
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14155
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14156
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14157
    }
14158
   /* copy workspace back if necessary */
14159
    if (realign) {
14160
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14161
      xp = (uint *) *xpp;
14162
    }
14163
   /* update xpp and tp */
14164
    xp += ni;
14165
    tp += ni;
14166
    *xpp = (void*)xp;
14167
  }
14168
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14169
14170
#else   /* not SX */
14171
14172
0
  char *xp = (char *) *xpp;
14173
0
  int status = NC_NOERR;
14174
14175
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14176
0
  {
14177
0
    int lstatus = ncx_put_uint_int(xp, tp, fillp);
14178
0
    if (status == NC_NOERR) /* report the first encountered error */
14179
0
      status = lstatus;
14180
0
  }
14181
14182
0
  *xpp = (void *)xp;
14183
0
  return status;
14184
0
#endif
14185
0
}
14186
14187
int
14188
ncx_putn_uint_long(void **xpp, size_t nelems, const long *tp, void *fillp)
14189
0
{
14190
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14191
14192
 /* basic algorithm is:
14193
  *   - ensure sane alignment of output data
14194
  *   - copy (conversion happens automatically) input data
14195
  *     to output
14196
  *   - update tp to point at next unconverted input, and xpp to point
14197
  *     at next location for converted output
14198
  */
14199
  long i, j, ni;
14200
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14201
  uint *xp;
14202
  int nrange = 0;         /* number of range errors */
14203
  int realign = 0;        /* "do we need to fix input data alignment?" */
14204
  long cxp = (long) *((char**)xpp);
14205
14206
  realign = (cxp & 7) % SIZEOF_UINT;
14207
  /* sjl: manually stripmine so we can limit amount of
14208
   * vector work space reserved to LOOPCNT elements. Also
14209
   * makes vectorisation easy */
14210
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14211
    ni=Min(nelems-j,LOOPCNT);
14212
    if (realign) {
14213
      xp = tmp;
14214
    } else {
14215
      xp = (uint *) *xpp;
14216
    }
14217
   /* copy the next block */
14218
#pragma cdir loopcnt=LOOPCNT
14219
#pragma cdir shortloop
14220
    for (i=0; i<ni; i++) {
14221
      /* the normal case: */
14222
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14223
     /* test for range errors (not always needed but do it anyway) */
14224
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14225
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14226
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14227
    }
14228
   /* copy workspace back if necessary */
14229
    if (realign) {
14230
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14231
      xp = (uint *) *xpp;
14232
    }
14233
   /* update xpp and tp */
14234
    xp += ni;
14235
    tp += ni;
14236
    *xpp = (void*)xp;
14237
  }
14238
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14239
14240
#else   /* not SX */
14241
14242
0
  char *xp = (char *) *xpp;
14243
0
  int status = NC_NOERR;
14244
14245
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14246
0
  {
14247
0
    int lstatus = ncx_put_uint_long(xp, tp, fillp);
14248
0
    if (status == NC_NOERR) /* report the first encountered error */
14249
0
      status = lstatus;
14250
0
  }
14251
14252
0
  *xpp = (void *)xp;
14253
0
  return status;
14254
0
#endif
14255
0
}
14256
14257
int
14258
ncx_putn_uint_float(void **xpp, size_t nelems, const float *tp, void *fillp)
14259
0
{
14260
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14261
14262
 /* basic algorithm is:
14263
  *   - ensure sane alignment of output data
14264
  *   - copy (conversion happens automatically) input data
14265
  *     to output
14266
  *   - update tp to point at next unconverted input, and xpp to point
14267
  *     at next location for converted output
14268
  */
14269
  long i, j, ni;
14270
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14271
  uint *xp;
14272
  int nrange = 0;         /* number of range errors */
14273
  int realign = 0;        /* "do we need to fix input data alignment?" */
14274
  long cxp = (long) *((char**)xpp);
14275
14276
  realign = (cxp & 7) % SIZEOF_UINT;
14277
  /* sjl: manually stripmine so we can limit amount of
14278
   * vector work space reserved to LOOPCNT elements. Also
14279
   * makes vectorisation easy */
14280
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14281
    ni=Min(nelems-j,LOOPCNT);
14282
    if (realign) {
14283
      xp = tmp;
14284
    } else {
14285
      xp = (uint *) *xpp;
14286
    }
14287
   /* copy the next block */
14288
#pragma cdir loopcnt=LOOPCNT
14289
#pragma cdir shortloop
14290
    for (i=0; i<ni; i++) {
14291
      /* the normal case: */
14292
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14293
     /* test for range errors (not always needed but do it anyway) */
14294
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14295
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14296
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14297
    }
14298
   /* copy workspace back if necessary */
14299
    if (realign) {
14300
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14301
      xp = (uint *) *xpp;
14302
    }
14303
   /* update xpp and tp */
14304
    xp += ni;
14305
    tp += ni;
14306
    *xpp = (void*)xp;
14307
  }
14308
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14309
14310
#else   /* not SX */
14311
14312
0
  char *xp = (char *) *xpp;
14313
0
  int status = NC_NOERR;
14314
14315
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14316
0
  {
14317
0
    int lstatus = ncx_put_uint_float(xp, tp, fillp);
14318
0
    if (status == NC_NOERR) /* report the first encountered error */
14319
0
      status = lstatus;
14320
0
  }
14321
14322
0
  *xpp = (void *)xp;
14323
0
  return status;
14324
0
#endif
14325
0
}
14326
14327
int
14328
ncx_putn_uint_double(void **xpp, size_t nelems, const double *tp, void *fillp)
14329
0
{
14330
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14331
14332
 /* basic algorithm is:
14333
  *   - ensure sane alignment of output data
14334
  *   - copy (conversion happens automatically) input data
14335
  *     to output
14336
  *   - update tp to point at next unconverted input, and xpp to point
14337
  *     at next location for converted output
14338
  */
14339
  long i, j, ni;
14340
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14341
  uint *xp;
14342
  int nrange = 0;         /* number of range errors */
14343
  int realign = 0;        /* "do we need to fix input data alignment?" */
14344
  long cxp = (long) *((char**)xpp);
14345
14346
  realign = (cxp & 7) % SIZEOF_UINT;
14347
  /* sjl: manually stripmine so we can limit amount of
14348
   * vector work space reserved to LOOPCNT elements. Also
14349
   * makes vectorisation easy */
14350
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14351
    ni=Min(nelems-j,LOOPCNT);
14352
    if (realign) {
14353
      xp = tmp;
14354
    } else {
14355
      xp = (uint *) *xpp;
14356
    }
14357
   /* copy the next block */
14358
#pragma cdir loopcnt=LOOPCNT
14359
#pragma cdir shortloop
14360
    for (i=0; i<ni; i++) {
14361
      /* the normal case: */
14362
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14363
     /* test for range errors (not always needed but do it anyway) */
14364
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14365
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14366
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14367
    }
14368
   /* copy workspace back if necessary */
14369
    if (realign) {
14370
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14371
      xp = (uint *) *xpp;
14372
    }
14373
   /* update xpp and tp */
14374
    xp += ni;
14375
    tp += ni;
14376
    *xpp = (void*)xp;
14377
  }
14378
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14379
14380
#else   /* not SX */
14381
14382
0
  char *xp = (char *) *xpp;
14383
0
  int status = NC_NOERR;
14384
14385
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14386
0
  {
14387
0
    int lstatus = ncx_put_uint_double(xp, tp, fillp);
14388
0
    if (status == NC_NOERR) /* report the first encountered error */
14389
0
      status = lstatus;
14390
0
  }
14391
14392
0
  *xpp = (void *)xp;
14393
0
  return status;
14394
0
#endif
14395
0
}
14396
14397
int
14398
ncx_putn_uint_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
14399
0
{
14400
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14401
14402
 /* basic algorithm is:
14403
  *   - ensure sane alignment of output data
14404
  *   - copy (conversion happens automatically) input data
14405
  *     to output
14406
  *   - update tp to point at next unconverted input, and xpp to point
14407
  *     at next location for converted output
14408
  */
14409
  long i, j, ni;
14410
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14411
  uint *xp;
14412
  int nrange = 0;         /* number of range errors */
14413
  int realign = 0;        /* "do we need to fix input data alignment?" */
14414
  long cxp = (long) *((char**)xpp);
14415
14416
  realign = (cxp & 7) % SIZEOF_UINT;
14417
  /* sjl: manually stripmine so we can limit amount of
14418
   * vector work space reserved to LOOPCNT elements. Also
14419
   * makes vectorisation easy */
14420
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14421
    ni=Min(nelems-j,LOOPCNT);
14422
    if (realign) {
14423
      xp = tmp;
14424
    } else {
14425
      xp = (uint *) *xpp;
14426
    }
14427
   /* copy the next block */
14428
#pragma cdir loopcnt=LOOPCNT
14429
#pragma cdir shortloop
14430
    for (i=0; i<ni; i++) {
14431
      /* the normal case: */
14432
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14433
     /* test for range errors (not always needed but do it anyway) */
14434
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14435
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14436
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14437
    }
14438
   /* copy workspace back if necessary */
14439
    if (realign) {
14440
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14441
      xp = (uint *) *xpp;
14442
    }
14443
   /* update xpp and tp */
14444
    xp += ni;
14445
    tp += ni;
14446
    *xpp = (void*)xp;
14447
  }
14448
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14449
14450
#else   /* not SX */
14451
14452
0
  char *xp = (char *) *xpp;
14453
0
  int status = NC_NOERR;
14454
14455
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14456
0
  {
14457
0
    int lstatus = ncx_put_uint_longlong(xp, tp, fillp);
14458
0
    if (status == NC_NOERR) /* report the first encountered error */
14459
0
      status = lstatus;
14460
0
  }
14461
14462
0
  *xpp = (void *)xp;
14463
0
  return status;
14464
0
#endif
14465
0
}
14466
14467
int
14468
ncx_putn_uint_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
14469
0
{
14470
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14471
14472
 /* basic algorithm is:
14473
  *   - ensure sane alignment of output data
14474
  *   - copy (conversion happens automatically) input data
14475
  *     to output
14476
  *   - update tp to point at next unconverted input, and xpp to point
14477
  *     at next location for converted output
14478
  */
14479
  long i, j, ni;
14480
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14481
  uint *xp;
14482
  int nrange = 0;         /* number of range errors */
14483
  int realign = 0;        /* "do we need to fix input data alignment?" */
14484
  long cxp = (long) *((char**)xpp);
14485
14486
  realign = (cxp & 7) % SIZEOF_UINT;
14487
  /* sjl: manually stripmine so we can limit amount of
14488
   * vector work space reserved to LOOPCNT elements. Also
14489
   * makes vectorisation easy */
14490
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14491
    ni=Min(nelems-j,LOOPCNT);
14492
    if (realign) {
14493
      xp = tmp;
14494
    } else {
14495
      xp = (uint *) *xpp;
14496
    }
14497
   /* copy the next block */
14498
#pragma cdir loopcnt=LOOPCNT
14499
#pragma cdir shortloop
14500
    for (i=0; i<ni; i++) {
14501
      /* the normal case: */
14502
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14503
     /* test for range errors (not always needed but do it anyway) */
14504
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14505
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14506
      nrange += tp[i] > X_UINT_MAX ;
14507
    }
14508
   /* copy workspace back if necessary */
14509
    if (realign) {
14510
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14511
      xp = (uint *) *xpp;
14512
    }
14513
   /* update xpp and tp */
14514
    xp += ni;
14515
    tp += ni;
14516
    *xpp = (void*)xp;
14517
  }
14518
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14519
14520
#else   /* not SX */
14521
14522
0
  char *xp = (char *) *xpp;
14523
0
  int status = NC_NOERR;
14524
14525
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14526
0
  {
14527
0
    int lstatus = ncx_put_uint_uchar(xp, tp, fillp);
14528
0
    if (status == NC_NOERR) /* report the first encountered error */
14529
0
      status = lstatus;
14530
0
  }
14531
14532
0
  *xpp = (void *)xp;
14533
0
  return status;
14534
0
#endif
14535
0
}
14536
14537
int
14538
ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
14539
0
{
14540
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14541
14542
 /* basic algorithm is:
14543
  *   - ensure sane alignment of output data
14544
  *   - copy (conversion happens automatically) input data
14545
  *     to output
14546
  *   - update tp to point at next unconverted input, and xpp to point
14547
  *     at next location for converted output
14548
  */
14549
  long i, j, ni;
14550
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14551
  uint *xp;
14552
  int nrange = 0;         /* number of range errors */
14553
  int realign = 0;        /* "do we need to fix input data alignment?" */
14554
  long cxp = (long) *((char**)xpp);
14555
14556
  realign = (cxp & 7) % SIZEOF_UINT;
14557
  /* sjl: manually stripmine so we can limit amount of
14558
   * vector work space reserved to LOOPCNT elements. Also
14559
   * makes vectorisation easy */
14560
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14561
    ni=Min(nelems-j,LOOPCNT);
14562
    if (realign) {
14563
      xp = tmp;
14564
    } else {
14565
      xp = (uint *) *xpp;
14566
    }
14567
   /* copy the next block */
14568
#pragma cdir loopcnt=LOOPCNT
14569
#pragma cdir shortloop
14570
    for (i=0; i<ni; i++) {
14571
      /* the normal case: */
14572
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14573
     /* test for range errors (not always needed but do it anyway) */
14574
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14575
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14576
      nrange += tp[i] > X_UINT_MAX ;
14577
    }
14578
   /* copy workspace back if necessary */
14579
    if (realign) {
14580
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14581
      xp = (uint *) *xpp;
14582
    }
14583
   /* update xpp and tp */
14584
    xp += ni;
14585
    tp += ni;
14586
    *xpp = (void*)xp;
14587
  }
14588
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14589
14590
#else   /* not SX */
14591
14592
0
  char *xp = (char *) *xpp;
14593
0
  int status = NC_NOERR;
14594
14595
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14596
0
  {
14597
0
    int lstatus = ncx_put_uint_ushort(xp, tp, fillp);
14598
0
    if (status == NC_NOERR) /* report the first encountered error */
14599
0
      status = lstatus;
14600
0
  }
14601
14602
0
  *xpp = (void *)xp;
14603
0
  return status;
14604
0
#endif
14605
0
}
14606
14607
int
14608
ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
14609
0
{
14610
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14611
14612
 /* basic algorithm is:
14613
  *   - ensure sane alignment of output data
14614
  *   - copy (conversion happens automatically) input data
14615
  *     to output
14616
  *   - update tp to point at next unconverted input, and xpp to point
14617
  *     at next location for converted output
14618
  */
14619
  long i, j, ni;
14620
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14621
  uint *xp;
14622
  int nrange = 0;         /* number of range errors */
14623
  int realign = 0;        /* "do we need to fix input data alignment?" */
14624
  long cxp = (long) *((char**)xpp);
14625
14626
  realign = (cxp & 7) % SIZEOF_UINT;
14627
  /* sjl: manually stripmine so we can limit amount of
14628
   * vector work space reserved to LOOPCNT elements. Also
14629
   * makes vectorisation easy */
14630
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14631
    ni=Min(nelems-j,LOOPCNT);
14632
    if (realign) {
14633
      xp = tmp;
14634
    } else {
14635
      xp = (uint *) *xpp;
14636
    }
14637
   /* copy the next block */
14638
#pragma cdir loopcnt=LOOPCNT
14639
#pragma cdir shortloop
14640
    for (i=0; i<ni; i++) {
14641
      /* the normal case: */
14642
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14643
     /* test for range errors (not always needed but do it anyway) */
14644
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14645
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14646
      nrange += tp[i] > X_UINT_MAX ;
14647
    }
14648
   /* copy workspace back if necessary */
14649
    if (realign) {
14650
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14651
      xp = (uint *) *xpp;
14652
    }
14653
   /* update xpp and tp */
14654
    xp += ni;
14655
    tp += ni;
14656
    *xpp = (void*)xp;
14657
  }
14658
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14659
14660
#else   /* not SX */
14661
14662
0
  char *xp = (char *) *xpp;
14663
0
  int status = NC_NOERR;
14664
14665
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14666
0
  {
14667
0
    int lstatus = ncx_put_uint_ulonglong(xp, tp, fillp);
14668
0
    if (status == NC_NOERR) /* report the first encountered error */
14669
0
      status = lstatus;
14670
0
  }
14671
14672
0
  *xpp = (void *)xp;
14673
0
  return status;
14674
0
#endif
14675
0
}
14676
14677
14678
14679
/* float ---------------------------------------------------------------------*/
14680
14681
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
14682
/* optimized version */
14683
int
14684
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14685
0
{
14686
#ifdef WORDS_BIGENDIAN
14687
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
14688
# else
14689
0
  swapn4b(tp, *xpp, nelems);
14690
0
# endif
14691
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
14692
0
  return NC_NOERR;
14693
0
}
14694
#elif defined(vax) && vax != 0
14695
int
14696
ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
14697
{
14698
  float *const end = ip + nfloats;
14699
14700
  while (ip < end)
14701
  {
14702
    struct vax_single *const vsp = (struct vax_single *) ip;
14703
    const struct ieee_single *const isp =
14704
       (const struct ieee_single *) (*xpp);
14705
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
14706
14707
    switch(exp) {
14708
    case 0 :
14709
      /* ieee subnormal */
14710
      if (isp->mant_hi == min.ieee.mant_hi
14711
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
14712
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
14713
      {
14714
        *vsp = min.s;
14715
      }
14716
      else
14717
      {
14718
        unsigned mantissa = (isp->mant_hi << 16)
14719
           | isp->mant_lo_hi << 8
14720
           | isp->mant_lo_lo;
14721
        unsigned tmp = mantissa >> 20;
14722
        if (tmp >= 4) {
14723
          vsp->exp = 2;
14724
        } else if (tmp >= 2) {
14725
          vsp->exp = 1;
14726
        } else {
14727
          *vsp = min.s;
14728
          break;
14729
        } /* else */
14730
        tmp = mantissa - (1 << (20 + vsp->exp ));
14731
        tmp <<= 3 - vsp->exp;
14732
        vsp->mantissa2 = tmp;
14733
        vsp->mantissa1 = (tmp >> 16);
14734
      }
14735
      break;
14736
    case 0xfe :
14737
    case 0xff :
14738
      *vsp = max.s;
14739
      break;
14740
    default :
14741
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
14742
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
14743
      vsp->mantissa1 = isp->mant_hi;
14744
    }
14745
14746
    vsp->sign = isp->sign;
14747
14748
14749
    ip++;
14750
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
14751
  }
14752
  return NC_NOERR;
14753
}
14754
#else
14755
int
14756
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14757
{
14758
  const char *xp = *xpp;
14759
  int status = NC_NOERR;
14760
14761
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14762
  {
14763
    const int lstatus = ncx_get_float_float(xp, tp, fillp);
14764
    if (status == NC_NOERR) /* report the first encountered error */
14765
      status = lstatus;
14766
  }
14767
14768
  *xpp = (const void *)xp;
14769
  return status;
14770
}
14771
14772
#endif
14773
int
14774
ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
14775
0
{
14776
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14777
14778
 /* basic algorithm is:
14779
  *   - ensure sane alignment of input data
14780
  *   - copy (conversion happens automatically) input data
14781
  *     to output
14782
  *   - update xpp to point at next unconverted input, and tp to point
14783
  *     at next location for converted output
14784
  */
14785
  long i, j, ni;
14786
  float tmp[LOOPCNT];        /* in case input is misaligned */
14787
  float *xp;
14788
  int nrange = 0;         /* number of range errors */
14789
  int realign = 0;        /* "do we need to fix input data alignment?" */
14790
  long cxp = (long) *((char**)xpp);
14791
14792
  realign = (cxp & 7) % SIZEOF_FLOAT;
14793
  /* sjl: manually stripmine so we can limit amount of
14794
   * vector work space reserved to LOOPCNT elements. Also
14795
   * makes vectorisation easy */
14796
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14797
    ni=Min(nelems-j,LOOPCNT);
14798
    if (realign) {
14799
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14800
      xp = tmp;
14801
    } else {
14802
      xp = (float *) *xpp;
14803
    }
14804
   /* copy the next block */
14805
#pragma cdir loopcnt=LOOPCNT
14806
#pragma cdir shortloop
14807
    for (i=0; i<ni; i++) {
14808
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
14809
     /* test for range errors (not always needed but do it anyway) */
14810
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14811
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14812
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
14813
    }
14814
   /* update xpp and tp */
14815
    if (realign) xp = (float *) *xpp;
14816
    xp += ni;
14817
    tp += ni;
14818
    *xpp = (void*)xp;
14819
  }
14820
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14821
14822
#else   /* not SX */
14823
0
  const char *xp = (const char *) *xpp;
14824
0
  int status = NC_NOERR;
14825
14826
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14827
0
  {
14828
0
    const int lstatus = ncx_get_float_schar(xp, tp);
14829
0
    if (status == NC_NOERR) /* report the first encountered error */
14830
0
      status = lstatus;
14831
0
  }
14832
14833
0
  *xpp = (const void *)xp;
14834
0
  return status;
14835
0
#endif
14836
0
}
14837
14838
int
14839
ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
14840
0
{
14841
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14842
14843
 /* basic algorithm is:
14844
  *   - ensure sane alignment of input data
14845
  *   - copy (conversion happens automatically) input data
14846
  *     to output
14847
  *   - update xpp to point at next unconverted input, and tp to point
14848
  *     at next location for converted output
14849
  */
14850
  long i, j, ni;
14851
  float tmp[LOOPCNT];        /* in case input is misaligned */
14852
  float *xp;
14853
  int nrange = 0;         /* number of range errors */
14854
  int realign = 0;        /* "do we need to fix input data alignment?" */
14855
  long cxp = (long) *((char**)xpp);
14856
14857
  realign = (cxp & 7) % SIZEOF_FLOAT;
14858
  /* sjl: manually stripmine so we can limit amount of
14859
   * vector work space reserved to LOOPCNT elements. Also
14860
   * makes vectorisation easy */
14861
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14862
    ni=Min(nelems-j,LOOPCNT);
14863
    if (realign) {
14864
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14865
      xp = tmp;
14866
    } else {
14867
      xp = (float *) *xpp;
14868
    }
14869
   /* copy the next block */
14870
#pragma cdir loopcnt=LOOPCNT
14871
#pragma cdir shortloop
14872
    for (i=0; i<ni; i++) {
14873
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
14874
     /* test for range errors (not always needed but do it anyway) */
14875
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14876
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14877
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
14878
    }
14879
   /* update xpp and tp */
14880
    if (realign) xp = (float *) *xpp;
14881
    xp += ni;
14882
    tp += ni;
14883
    *xpp = (void*)xp;
14884
  }
14885
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14886
14887
#else   /* not SX */
14888
0
  const char *xp = (const char *) *xpp;
14889
0
  int status = NC_NOERR;
14890
14891
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14892
0
  {
14893
0
    const int lstatus = ncx_get_float_short(xp, tp);
14894
0
    if (status == NC_NOERR) /* report the first encountered error */
14895
0
      status = lstatus;
14896
0
  }
14897
14898
0
  *xpp = (const void *)xp;
14899
0
  return status;
14900
0
#endif
14901
0
}
14902
14903
int
14904
ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
14905
0
{
14906
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14907
14908
 /* basic algorithm is:
14909
  *   - ensure sane alignment of input data
14910
  *   - copy (conversion happens automatically) input data
14911
  *     to output
14912
  *   - update xpp to point at next unconverted input, and tp to point
14913
  *     at next location for converted output
14914
  */
14915
  long i, j, ni;
14916
  float tmp[LOOPCNT];        /* in case input is misaligned */
14917
  float *xp;
14918
  int nrange = 0;         /* number of range errors */
14919
  int realign = 0;        /* "do we need to fix input data alignment?" */
14920
  long cxp = (long) *((char**)xpp);
14921
14922
  realign = (cxp & 7) % SIZEOF_FLOAT;
14923
  /* sjl: manually stripmine so we can limit amount of
14924
   * vector work space reserved to LOOPCNT elements. Also
14925
   * makes vectorisation easy */
14926
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14927
    ni=Min(nelems-j,LOOPCNT);
14928
    if (realign) {
14929
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14930
      xp = tmp;
14931
    } else {
14932
      xp = (float *) *xpp;
14933
    }
14934
   /* copy the next block */
14935
#pragma cdir loopcnt=LOOPCNT
14936
#pragma cdir shortloop
14937
    for (i=0; i<ni; i++) {
14938
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
14939
     /* test for range errors (not always needed but do it anyway) */
14940
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14941
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14942
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
14943
    }
14944
   /* update xpp and tp */
14945
    if (realign) xp = (float *) *xpp;
14946
    xp += ni;
14947
    tp += ni;
14948
    *xpp = (void*)xp;
14949
  }
14950
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14951
14952
#else   /* not SX */
14953
0
  const char *xp = (const char *) *xpp;
14954
0
  int status = NC_NOERR;
14955
14956
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14957
0
  {
14958
0
    const int lstatus = ncx_get_float_int(xp, tp);
14959
0
    if (status == NC_NOERR) /* report the first encountered error */
14960
0
      status = lstatus;
14961
0
  }
14962
14963
0
  *xpp = (const void *)xp;
14964
0
  return status;
14965
0
#endif
14966
0
}
14967
14968
int
14969
ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
14970
0
{
14971
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
14972
14973
 /* basic algorithm is:
14974
  *   - ensure sane alignment of input data
14975
  *   - copy (conversion happens automatically) input data
14976
  *     to output
14977
  *   - update xpp to point at next unconverted input, and tp to point
14978
  *     at next location for converted output
14979
  */
14980
  long i, j, ni;
14981
  float tmp[LOOPCNT];        /* in case input is misaligned */
14982
  float *xp;
14983
  int nrange = 0;         /* number of range errors */
14984
  int realign = 0;        /* "do we need to fix input data alignment?" */
14985
  long cxp = (long) *((char**)xpp);
14986
14987
  realign = (cxp & 7) % SIZEOF_FLOAT;
14988
  /* sjl: manually stripmine so we can limit amount of
14989
   * vector work space reserved to LOOPCNT elements. Also
14990
   * makes vectorisation easy */
14991
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14992
    ni=Min(nelems-j,LOOPCNT);
14993
    if (realign) {
14994
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
14995
      xp = tmp;
14996
    } else {
14997
      xp = (float *) *xpp;
14998
    }
14999
   /* copy the next block */
15000
#pragma cdir loopcnt=LOOPCNT
15001
#pragma cdir shortloop
15002
    for (i=0; i<ni; i++) {
15003
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
15004
     /* test for range errors (not always needed but do it anyway) */
15005
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15006
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15007
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
15008
    }
15009
   /* update xpp and tp */
15010
    if (realign) xp = (float *) *xpp;
15011
    xp += ni;
15012
    tp += ni;
15013
    *xpp = (void*)xp;
15014
  }
15015
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15016
15017
#else   /* not SX */
15018
0
  const char *xp = (const char *) *xpp;
15019
0
  int status = NC_NOERR;
15020
15021
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15022
0
  {
15023
0
    const int lstatus = ncx_get_float_long(xp, tp);
15024
0
    if (status == NC_NOERR) /* report the first encountered error */
15025
0
      status = lstatus;
15026
0
  }
15027
15028
0
  *xpp = (const void *)xp;
15029
0
  return status;
15030
0
#endif
15031
0
}
15032
15033
int
15034
ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
15035
0
{
15036
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15037
15038
 /* basic algorithm is:
15039
  *   - ensure sane alignment of input data
15040
  *   - copy (conversion happens automatically) input data
15041
  *     to output
15042
  *   - update xpp to point at next unconverted input, and tp to point
15043
  *     at next location for converted output
15044
  */
15045
  long i, j, ni;
15046
  float tmp[LOOPCNT];        /* in case input is misaligned */
15047
  float *xp;
15048
  int nrange = 0;         /* number of range errors */
15049
  int realign = 0;        /* "do we need to fix input data alignment?" */
15050
  long cxp = (long) *((char**)xpp);
15051
15052
  realign = (cxp & 7) % SIZEOF_FLOAT;
15053
  /* sjl: manually stripmine so we can limit amount of
15054
   * vector work space reserved to LOOPCNT elements. Also
15055
   * makes vectorisation easy */
15056
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15057
    ni=Min(nelems-j,LOOPCNT);
15058
    if (realign) {
15059
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15060
      xp = tmp;
15061
    } else {
15062
      xp = (float *) *xpp;
15063
    }
15064
   /* copy the next block */
15065
#pragma cdir loopcnt=LOOPCNT
15066
#pragma cdir shortloop
15067
    for (i=0; i<ni; i++) {
15068
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
15069
     /* test for range errors (not always needed but do it anyway) */
15070
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15071
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15072
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
15073
    }
15074
   /* update xpp and tp */
15075
    if (realign) xp = (float *) *xpp;
15076
    xp += ni;
15077
    tp += ni;
15078
    *xpp = (void*)xp;
15079
  }
15080
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15081
15082
#else   /* not SX */
15083
0
  const char *xp = (const char *) *xpp;
15084
0
  int status = NC_NOERR;
15085
15086
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15087
0
  {
15088
0
    const int lstatus = ncx_get_float_double(xp, tp);
15089
0
    if (status == NC_NOERR) /* report the first encountered error */
15090
0
      status = lstatus;
15091
0
  }
15092
15093
0
  *xpp = (const void *)xp;
15094
0
  return status;
15095
0
#endif
15096
0
}
15097
15098
int
15099
ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp)
15100
0
{
15101
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15102
15103
 /* basic algorithm is:
15104
  *   - ensure sane alignment of input data
15105
  *   - copy (conversion happens automatically) input data
15106
  *     to output
15107
  *   - update xpp to point at next unconverted input, and tp to point
15108
  *     at next location for converted output
15109
  */
15110
  long i, j, ni;
15111
  float tmp[LOOPCNT];        /* in case input is misaligned */
15112
  float *xp;
15113
  int nrange = 0;         /* number of range errors */
15114
  int realign = 0;        /* "do we need to fix input data alignment?" */
15115
  long cxp = (long) *((char**)xpp);
15116
15117
  realign = (cxp & 7) % SIZEOF_FLOAT;
15118
  /* sjl: manually stripmine so we can limit amount of
15119
   * vector work space reserved to LOOPCNT elements. Also
15120
   * makes vectorisation easy */
15121
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15122
    ni=Min(nelems-j,LOOPCNT);
15123
    if (realign) {
15124
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15125
      xp = tmp;
15126
    } else {
15127
      xp = (float *) *xpp;
15128
    }
15129
   /* copy the next block */
15130
#pragma cdir loopcnt=LOOPCNT
15131
#pragma cdir shortloop
15132
    for (i=0; i<ni; i++) {
15133
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
15134
     /* test for range errors (not always needed but do it anyway) */
15135
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15136
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15137
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
15138
    }
15139
   /* update xpp and tp */
15140
    if (realign) xp = (float *) *xpp;
15141
    xp += ni;
15142
    tp += ni;
15143
    *xpp = (void*)xp;
15144
  }
15145
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15146
15147
#else   /* not SX */
15148
0
  const char *xp = (const char *) *xpp;
15149
0
  int status = NC_NOERR;
15150
15151
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15152
0
  {
15153
0
    const int lstatus = ncx_get_float_longlong(xp, tp);
15154
0
    if (status == NC_NOERR) /* report the first encountered error */
15155
0
      status = lstatus;
15156
0
  }
15157
15158
0
  *xpp = (const void *)xp;
15159
0
  return status;
15160
0
#endif
15161
0
}
15162
15163
int
15164
ncx_getn_float_ushort(const void **xpp, size_t nelems, ushort *tp)
15165
0
{
15166
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15167
15168
 /* basic algorithm is:
15169
  *   - ensure sane alignment of input data
15170
  *   - copy (conversion happens automatically) input data
15171
  *     to output
15172
  *   - update xpp to point at next unconverted input, and tp to point
15173
  *     at next location for converted output
15174
  */
15175
  long i, j, ni;
15176
  float tmp[LOOPCNT];        /* in case input is misaligned */
15177
  float *xp;
15178
  int nrange = 0;         /* number of range errors */
15179
  int realign = 0;        /* "do we need to fix input data alignment?" */
15180
  long cxp = (long) *((char**)xpp);
15181
15182
  realign = (cxp & 7) % SIZEOF_FLOAT;
15183
  /* sjl: manually stripmine so we can limit amount of
15184
   * vector work space reserved to LOOPCNT elements. Also
15185
   * makes vectorisation easy */
15186
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15187
    ni=Min(nelems-j,LOOPCNT);
15188
    if (realign) {
15189
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15190
      xp = tmp;
15191
    } else {
15192
      xp = (float *) *xpp;
15193
    }
15194
   /* copy the next block */
15195
#pragma cdir loopcnt=LOOPCNT
15196
#pragma cdir shortloop
15197
    for (i=0; i<ni; i++) {
15198
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
15199
     /* test for range errors (not always needed but do it anyway) */
15200
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15201
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15202
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
15203
    }
15204
   /* update xpp and tp */
15205
    if (realign) xp = (float *) *xpp;
15206
    xp += ni;
15207
    tp += ni;
15208
    *xpp = (void*)xp;
15209
  }
15210
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15211
15212
#else   /* not SX */
15213
0
  const char *xp = (const char *) *xpp;
15214
0
  int status = NC_NOERR;
15215
15216
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15217
0
  {
15218
0
    const int lstatus = ncx_get_float_ushort(xp, tp);
15219
0
    if (status == NC_NOERR) /* report the first encountered error */
15220
0
      status = lstatus;
15221
0
  }
15222
15223
0
  *xpp = (const void *)xp;
15224
0
  return status;
15225
0
#endif
15226
0
}
15227
15228
int
15229
ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
15230
0
{
15231
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15232
15233
 /* basic algorithm is:
15234
  *   - ensure sane alignment of input data
15235
  *   - copy (conversion happens automatically) input data
15236
  *     to output
15237
  *   - update xpp to point at next unconverted input, and tp to point
15238
  *     at next location for converted output
15239
  */
15240
  long i, j, ni;
15241
  float tmp[LOOPCNT];        /* in case input is misaligned */
15242
  float *xp;
15243
  int nrange = 0;         /* number of range errors */
15244
  int realign = 0;        /* "do we need to fix input data alignment?" */
15245
  long cxp = (long) *((char**)xpp);
15246
15247
  realign = (cxp & 7) % SIZEOF_FLOAT;
15248
  /* sjl: manually stripmine so we can limit amount of
15249
   * vector work space reserved to LOOPCNT elements. Also
15250
   * makes vectorisation easy */
15251
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15252
    ni=Min(nelems-j,LOOPCNT);
15253
    if (realign) {
15254
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15255
      xp = tmp;
15256
    } else {
15257
      xp = (float *) *xpp;
15258
    }
15259
   /* copy the next block */
15260
#pragma cdir loopcnt=LOOPCNT
15261
#pragma cdir shortloop
15262
    for (i=0; i<ni; i++) {
15263
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
15264
     /* test for range errors (not always needed but do it anyway) */
15265
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15266
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15267
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
15268
    }
15269
   /* update xpp and tp */
15270
    if (realign) xp = (float *) *xpp;
15271
    xp += ni;
15272
    tp += ni;
15273
    *xpp = (void*)xp;
15274
  }
15275
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15276
15277
#else   /* not SX */
15278
0
  const char *xp = (const char *) *xpp;
15279
0
  int status = NC_NOERR;
15280
15281
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15282
0
  {
15283
0
    const int lstatus = ncx_get_float_uchar(xp, tp);
15284
0
    if (status == NC_NOERR) /* report the first encountered error */
15285
0
      status = lstatus;
15286
0
  }
15287
15288
0
  *xpp = (const void *)xp;
15289
0
  return status;
15290
0
#endif
15291
0
}
15292
15293
int
15294
ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp)
15295
0
{
15296
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15297
15298
 /* basic algorithm is:
15299
  *   - ensure sane alignment of input data
15300
  *   - copy (conversion happens automatically) input data
15301
  *     to output
15302
  *   - update xpp to point at next unconverted input, and tp to point
15303
  *     at next location for converted output
15304
  */
15305
  long i, j, ni;
15306
  float tmp[LOOPCNT];        /* in case input is misaligned */
15307
  float *xp;
15308
  int nrange = 0;         /* number of range errors */
15309
  int realign = 0;        /* "do we need to fix input data alignment?" */
15310
  long cxp = (long) *((char**)xpp);
15311
15312
  realign = (cxp & 7) % SIZEOF_FLOAT;
15313
  /* sjl: manually stripmine so we can limit amount of
15314
   * vector work space reserved to LOOPCNT elements. Also
15315
   * makes vectorisation easy */
15316
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15317
    ni=Min(nelems-j,LOOPCNT);
15318
    if (realign) {
15319
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15320
      xp = tmp;
15321
    } else {
15322
      xp = (float *) *xpp;
15323
    }
15324
   /* copy the next block */
15325
#pragma cdir loopcnt=LOOPCNT
15326
#pragma cdir shortloop
15327
    for (i=0; i<ni; i++) {
15328
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
15329
     /* test for range errors (not always needed but do it anyway) */
15330
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15331
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15332
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
15333
    }
15334
   /* update xpp and tp */
15335
    if (realign) xp = (float *) *xpp;
15336
    xp += ni;
15337
    tp += ni;
15338
    *xpp = (void*)xp;
15339
  }
15340
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15341
15342
#else   /* not SX */
15343
0
  const char *xp = (const char *) *xpp;
15344
0
  int status = NC_NOERR;
15345
15346
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15347
0
  {
15348
0
    const int lstatus = ncx_get_float_uint(xp, tp);
15349
0
    if (status == NC_NOERR) /* report the first encountered error */
15350
0
      status = lstatus;
15351
0
  }
15352
15353
0
  *xpp = (const void *)xp;
15354
0
  return status;
15355
0
#endif
15356
0
}
15357
15358
int
15359
ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
15360
0
{
15361
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15362
15363
 /* basic algorithm is:
15364
  *   - ensure sane alignment of input data
15365
  *   - copy (conversion happens automatically) input data
15366
  *     to output
15367
  *   - update xpp to point at next unconverted input, and tp to point
15368
  *     at next location for converted output
15369
  */
15370
  long i, j, ni;
15371
  float tmp[LOOPCNT];        /* in case input is misaligned */
15372
  float *xp;
15373
  int nrange = 0;         /* number of range errors */
15374
  int realign = 0;        /* "do we need to fix input data alignment?" */
15375
  long cxp = (long) *((char**)xpp);
15376
15377
  realign = (cxp & 7) % SIZEOF_FLOAT;
15378
  /* sjl: manually stripmine so we can limit amount of
15379
   * vector work space reserved to LOOPCNT elements. Also
15380
   * makes vectorisation easy */
15381
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15382
    ni=Min(nelems-j,LOOPCNT);
15383
    if (realign) {
15384
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15385
      xp = tmp;
15386
    } else {
15387
      xp = (float *) *xpp;
15388
    }
15389
   /* copy the next block */
15390
#pragma cdir loopcnt=LOOPCNT
15391
#pragma cdir shortloop
15392
    for (i=0; i<ni; i++) {
15393
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
15394
     /* test for range errors (not always needed but do it anyway) */
15395
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15396
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15397
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
15398
    }
15399
   /* update xpp and tp */
15400
    if (realign) xp = (float *) *xpp;
15401
    xp += ni;
15402
    tp += ni;
15403
    *xpp = (void*)xp;
15404
  }
15405
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15406
15407
#else   /* not SX */
15408
0
  const char *xp = (const char *) *xpp;
15409
0
  int status = NC_NOERR;
15410
15411
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15412
0
  {
15413
0
    const int lstatus = ncx_get_float_ulonglong(xp, tp);
15414
0
    if (status == NC_NOERR) /* report the first encountered error */
15415
0
      status = lstatus;
15416
0
  }
15417
15418
0
  *xpp = (const void *)xp;
15419
0
  return status;
15420
0
#endif
15421
0
}
15422
15423
15424
int
15425
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
15426
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
15427
/* optimized version */
15428
0
{
15429
#ifdef WORDS_BIGENDIAN
15430
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
15431
# else
15432
0
  swapn4b(*xpp, tp, nelems);
15433
0
# endif
15434
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
15435
0
  return NC_NOERR;
15436
0
}
15437
#elif defined(vax) && vax != 0
15438
{
15439
  const float *const end = tp + nelems;
15440
15441
  while (tp < end) {
15442
        const struct vax_single *const vsp =
15443
       (const struct vax_single *)ip;
15444
    struct ieee_single *const isp = (struct ieee_single *) (*xpp);
15445
15446
    switch(vsp->exp){
15447
    case 0 :
15448
      /* all vax float with zero exponent map to zero */
15449
      *isp = min.ieee;
15450
      break;
15451
    case 2 :
15452
    case 1 :
15453
    {
15454
      /* These will map to subnormals */
15455
      unsigned mantissa = (vsp->mantissa1 << 16)
15456
           | vsp->mantissa2;
15457
      mantissa >>= 3 - vsp->exp;
15458
      mantissa += (1 << (20 + vsp->exp));
15459
      isp->mant_lo_lo = mantissa;
15460
      isp->mant_lo_hi = mantissa >> 8;
15461
      isp->mant_hi = mantissa >> 16;
15462
      isp->exp_lo = 0;
15463
      isp->exp_hi = 0;
15464
    }
15465
      break;
15466
    case 0xff : /* max.s.exp */
15467
      if (vsp->mantissa2 == max.s.mantissa2 &&
15468
          vsp->mantissa1 == max.s.mantissa1)
15469
      {
15470
        /* map largest vax float to ieee infinity */
15471
        *isp = max.ieee;
15472
        break;
15473
      } /* else, fall thru */
15474
    default :
15475
    {
15476
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
15477
      isp->exp_hi = exp >> 1;
15478
      isp->exp_lo = exp;
15479
      isp->mant_lo_lo = vsp->mantissa2;
15480
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
15481
      isp->mant_hi = vsp->mantissa1;
15482
    }
15483
    }
15484
15485
    isp->sign = vsp->sign;
15486
15487
    tp++;
15488
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
15489
  }
15490
  return NC_NOERR;
15491
}
15492
#else
15493
{
15494
  char *xp = *xpp;
15495
  int status = NC_NOERR;
15496
15497
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
15498
    int lstatus = ncx_put_float_float(xp, tp, fillp);
15499
    if (status == NC_NOERR) /* report the first encountered error */
15500
      status = lstatus;
15501
  }
15502
15503
  *xpp = (void *)xp;
15504
  return status;
15505
}
15506
#endif
15507
int
15508
ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
15509
0
{
15510
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15511
15512
 /* basic algorithm is:
15513
  *   - ensure sane alignment of output data
15514
  *   - copy (conversion happens automatically) input data
15515
  *     to output
15516
  *   - update tp to point at next unconverted input, and xpp to point
15517
  *     at next location for converted output
15518
  */
15519
  long i, j, ni;
15520
  float tmp[LOOPCNT];        /* in case input is misaligned */
15521
  float *xp;
15522
  int nrange = 0;         /* number of range errors */
15523
  int realign = 0;        /* "do we need to fix input data alignment?" */
15524
  long cxp = (long) *((char**)xpp);
15525
15526
  realign = (cxp & 7) % SIZEOF_FLOAT;
15527
  /* sjl: manually stripmine so we can limit amount of
15528
   * vector work space reserved to LOOPCNT elements. Also
15529
   * makes vectorisation easy */
15530
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15531
    ni=Min(nelems-j,LOOPCNT);
15532
    if (realign) {
15533
      xp = tmp;
15534
    } else {
15535
      xp = (float *) *xpp;
15536
    }
15537
   /* copy the next block */
15538
#pragma cdir loopcnt=LOOPCNT
15539
#pragma cdir shortloop
15540
    for (i=0; i<ni; i++) {
15541
      /* the normal case: */
15542
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15543
     /* test for range errors (not always needed but do it anyway) */
15544
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15545
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15546
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15547
    }
15548
   /* copy workspace back if necessary */
15549
    if (realign) {
15550
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15551
      xp = (float *) *xpp;
15552
    }
15553
   /* update xpp and tp */
15554
    xp += ni;
15555
    tp += ni;
15556
    *xpp = (void*)xp;
15557
  }
15558
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15559
15560
#else   /* not SX */
15561
15562
0
  char *xp = (char *) *xpp;
15563
0
  int status = NC_NOERR;
15564
15565
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15566
0
  {
15567
0
    int lstatus = ncx_put_float_schar(xp, tp, fillp);
15568
0
    if (status == NC_NOERR) /* report the first encountered error */
15569
0
      status = lstatus;
15570
0
  }
15571
15572
0
  *xpp = (void *)xp;
15573
0
  return status;
15574
0
#endif
15575
0
}
15576
15577
int
15578
ncx_putn_float_short(void **xpp, size_t nelems, const short *tp, void *fillp)
15579
0
{
15580
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15581
15582
 /* basic algorithm is:
15583
  *   - ensure sane alignment of output data
15584
  *   - copy (conversion happens automatically) input data
15585
  *     to output
15586
  *   - update tp to point at next unconverted input, and xpp to point
15587
  *     at next location for converted output
15588
  */
15589
  long i, j, ni;
15590
  float tmp[LOOPCNT];        /* in case input is misaligned */
15591
  float *xp;
15592
  int nrange = 0;         /* number of range errors */
15593
  int realign = 0;        /* "do we need to fix input data alignment?" */
15594
  long cxp = (long) *((char**)xpp);
15595
15596
  realign = (cxp & 7) % SIZEOF_FLOAT;
15597
  /* sjl: manually stripmine so we can limit amount of
15598
   * vector work space reserved to LOOPCNT elements. Also
15599
   * makes vectorisation easy */
15600
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15601
    ni=Min(nelems-j,LOOPCNT);
15602
    if (realign) {
15603
      xp = tmp;
15604
    } else {
15605
      xp = (float *) *xpp;
15606
    }
15607
   /* copy the next block */
15608
#pragma cdir loopcnt=LOOPCNT
15609
#pragma cdir shortloop
15610
    for (i=0; i<ni; i++) {
15611
      /* the normal case: */
15612
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15613
     /* test for range errors (not always needed but do it anyway) */
15614
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15615
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15616
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15617
    }
15618
   /* copy workspace back if necessary */
15619
    if (realign) {
15620
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15621
      xp = (float *) *xpp;
15622
    }
15623
   /* update xpp and tp */
15624
    xp += ni;
15625
    tp += ni;
15626
    *xpp = (void*)xp;
15627
  }
15628
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15629
15630
#else   /* not SX */
15631
15632
0
  char *xp = (char *) *xpp;
15633
0
  int status = NC_NOERR;
15634
15635
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15636
0
  {
15637
0
    int lstatus = ncx_put_float_short(xp, tp, fillp);
15638
0
    if (status == NC_NOERR) /* report the first encountered error */
15639
0
      status = lstatus;
15640
0
  }
15641
15642
0
  *xpp = (void *)xp;
15643
0
  return status;
15644
0
#endif
15645
0
}
15646
15647
int
15648
ncx_putn_float_int(void **xpp, size_t nelems, const int *tp, void *fillp)
15649
0
{
15650
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15651
15652
 /* basic algorithm is:
15653
  *   - ensure sane alignment of output data
15654
  *   - copy (conversion happens automatically) input data
15655
  *     to output
15656
  *   - update tp to point at next unconverted input, and xpp to point
15657
  *     at next location for converted output
15658
  */
15659
  long i, j, ni;
15660
  float tmp[LOOPCNT];        /* in case input is misaligned */
15661
  float *xp;
15662
  int nrange = 0;         /* number of range errors */
15663
  int realign = 0;        /* "do we need to fix input data alignment?" */
15664
  long cxp = (long) *((char**)xpp);
15665
15666
  realign = (cxp & 7) % SIZEOF_FLOAT;
15667
  /* sjl: manually stripmine so we can limit amount of
15668
   * vector work space reserved to LOOPCNT elements. Also
15669
   * makes vectorisation easy */
15670
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15671
    ni=Min(nelems-j,LOOPCNT);
15672
    if (realign) {
15673
      xp = tmp;
15674
    } else {
15675
      xp = (float *) *xpp;
15676
    }
15677
   /* copy the next block */
15678
#pragma cdir loopcnt=LOOPCNT
15679
#pragma cdir shortloop
15680
    for (i=0; i<ni; i++) {
15681
      /* the normal case: */
15682
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15683
     /* test for range errors (not always needed but do it anyway) */
15684
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15685
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15686
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15687
    }
15688
   /* copy workspace back if necessary */
15689
    if (realign) {
15690
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15691
      xp = (float *) *xpp;
15692
    }
15693
   /* update xpp and tp */
15694
    xp += ni;
15695
    tp += ni;
15696
    *xpp = (void*)xp;
15697
  }
15698
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15699
15700
#else   /* not SX */
15701
15702
0
  char *xp = (char *) *xpp;
15703
0
  int status = NC_NOERR;
15704
15705
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15706
0
  {
15707
0
    int lstatus = ncx_put_float_int(xp, tp, fillp);
15708
0
    if (status == NC_NOERR) /* report the first encountered error */
15709
0
      status = lstatus;
15710
0
  }
15711
15712
0
  *xpp = (void *)xp;
15713
0
  return status;
15714
0
#endif
15715
0
}
15716
15717
int
15718
ncx_putn_float_long(void **xpp, size_t nelems, const long *tp, void *fillp)
15719
0
{
15720
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15721
15722
 /* basic algorithm is:
15723
  *   - ensure sane alignment of output data
15724
  *   - copy (conversion happens automatically) input data
15725
  *     to output
15726
  *   - update tp to point at next unconverted input, and xpp to point
15727
  *     at next location for converted output
15728
  */
15729
  long i, j, ni;
15730
  float tmp[LOOPCNT];        /* in case input is misaligned */
15731
  float *xp;
15732
  int nrange = 0;         /* number of range errors */
15733
  int realign = 0;        /* "do we need to fix input data alignment?" */
15734
  long cxp = (long) *((char**)xpp);
15735
15736
  realign = (cxp & 7) % SIZEOF_FLOAT;
15737
  /* sjl: manually stripmine so we can limit amount of
15738
   * vector work space reserved to LOOPCNT elements. Also
15739
   * makes vectorisation easy */
15740
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15741
    ni=Min(nelems-j,LOOPCNT);
15742
    if (realign) {
15743
      xp = tmp;
15744
    } else {
15745
      xp = (float *) *xpp;
15746
    }
15747
   /* copy the next block */
15748
#pragma cdir loopcnt=LOOPCNT
15749
#pragma cdir shortloop
15750
    for (i=0; i<ni; i++) {
15751
      /* the normal case: */
15752
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15753
     /* test for range errors (not always needed but do it anyway) */
15754
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15755
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15756
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15757
    }
15758
   /* copy workspace back if necessary */
15759
    if (realign) {
15760
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15761
      xp = (float *) *xpp;
15762
    }
15763
   /* update xpp and tp */
15764
    xp += ni;
15765
    tp += ni;
15766
    *xpp = (void*)xp;
15767
  }
15768
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15769
15770
#else   /* not SX */
15771
15772
0
  char *xp = (char *) *xpp;
15773
0
  int status = NC_NOERR;
15774
15775
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15776
0
  {
15777
0
    int lstatus = ncx_put_float_long(xp, tp, fillp);
15778
0
    if (status == NC_NOERR) /* report the first encountered error */
15779
0
      status = lstatus;
15780
0
  }
15781
15782
0
  *xpp = (void *)xp;
15783
0
  return status;
15784
0
#endif
15785
0
}
15786
15787
int
15788
ncx_putn_float_double(void **xpp, size_t nelems, const double *tp, void *fillp)
15789
0
{
15790
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15791
15792
 /* basic algorithm is:
15793
  *   - ensure sane alignment of output data
15794
  *   - copy (conversion happens automatically) input data
15795
  *     to output
15796
  *   - update tp to point at next unconverted input, and xpp to point
15797
  *     at next location for converted output
15798
  */
15799
  long i, j, ni;
15800
  float tmp[LOOPCNT];        /* in case input is misaligned */
15801
  float *xp;
15802
  int nrange = 0;         /* number of range errors */
15803
  int realign = 0;        /* "do we need to fix input data alignment?" */
15804
  long cxp = (long) *((char**)xpp);
15805
15806
  realign = (cxp & 7) % SIZEOF_FLOAT;
15807
  /* sjl: manually stripmine so we can limit amount of
15808
   * vector work space reserved to LOOPCNT elements. Also
15809
   * makes vectorisation easy */
15810
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15811
    ni=Min(nelems-j,LOOPCNT);
15812
    if (realign) {
15813
      xp = tmp;
15814
    } else {
15815
      xp = (float *) *xpp;
15816
    }
15817
   /* copy the next block */
15818
#pragma cdir loopcnt=LOOPCNT
15819
#pragma cdir shortloop
15820
    for (i=0; i<ni; i++) {
15821
      /* the normal case: */
15822
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15823
     /* test for range errors (not always needed but do it anyway) */
15824
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15825
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15826
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15827
    }
15828
   /* copy workspace back if necessary */
15829
    if (realign) {
15830
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15831
      xp = (float *) *xpp;
15832
    }
15833
   /* update xpp and tp */
15834
    xp += ni;
15835
    tp += ni;
15836
    *xpp = (void*)xp;
15837
  }
15838
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15839
15840
#else   /* not SX */
15841
15842
0
  char *xp = (char *) *xpp;
15843
0
  int status = NC_NOERR;
15844
15845
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15846
0
  {
15847
0
    int lstatus = ncx_put_float_double(xp, tp, fillp);
15848
0
    if (status == NC_NOERR) /* report the first encountered error */
15849
0
      status = lstatus;
15850
0
  }
15851
15852
0
  *xpp = (void *)xp;
15853
0
  return status;
15854
0
#endif
15855
0
}
15856
15857
int
15858
ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
15859
0
{
15860
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15861
15862
 /* basic algorithm is:
15863
  *   - ensure sane alignment of output data
15864
  *   - copy (conversion happens automatically) input data
15865
  *     to output
15866
  *   - update tp to point at next unconverted input, and xpp to point
15867
  *     at next location for converted output
15868
  */
15869
  long i, j, ni;
15870
  float tmp[LOOPCNT];        /* in case input is misaligned */
15871
  float *xp;
15872
  int nrange = 0;         /* number of range errors */
15873
  int realign = 0;        /* "do we need to fix input data alignment?" */
15874
  long cxp = (long) *((char**)xpp);
15875
15876
  realign = (cxp & 7) % SIZEOF_FLOAT;
15877
  /* sjl: manually stripmine so we can limit amount of
15878
   * vector work space reserved to LOOPCNT elements. Also
15879
   * makes vectorisation easy */
15880
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15881
    ni=Min(nelems-j,LOOPCNT);
15882
    if (realign) {
15883
      xp = tmp;
15884
    } else {
15885
      xp = (float *) *xpp;
15886
    }
15887
   /* copy the next block */
15888
#pragma cdir loopcnt=LOOPCNT
15889
#pragma cdir shortloop
15890
    for (i=0; i<ni; i++) {
15891
      /* the normal case: */
15892
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15893
     /* test for range errors (not always needed but do it anyway) */
15894
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15895
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15896
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15897
    }
15898
   /* copy workspace back if necessary */
15899
    if (realign) {
15900
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15901
      xp = (float *) *xpp;
15902
    }
15903
   /* update xpp and tp */
15904
    xp += ni;
15905
    tp += ni;
15906
    *xpp = (void*)xp;
15907
  }
15908
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15909
15910
#else   /* not SX */
15911
15912
0
  char *xp = (char *) *xpp;
15913
0
  int status = NC_NOERR;
15914
15915
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15916
0
  {
15917
0
    int lstatus = ncx_put_float_longlong(xp, tp, fillp);
15918
0
    if (status == NC_NOERR) /* report the first encountered error */
15919
0
      status = lstatus;
15920
0
  }
15921
15922
0
  *xpp = (void *)xp;
15923
0
  return status;
15924
0
#endif
15925
0
}
15926
15927
int
15928
ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
15929
0
{
15930
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15931
15932
 /* basic algorithm is:
15933
  *   - ensure sane alignment of output data
15934
  *   - copy (conversion happens automatically) input data
15935
  *     to output
15936
  *   - update tp to point at next unconverted input, and xpp to point
15937
  *     at next location for converted output
15938
  */
15939
  long i, j, ni;
15940
  float tmp[LOOPCNT];        /* in case input is misaligned */
15941
  float *xp;
15942
  int nrange = 0;         /* number of range errors */
15943
  int realign = 0;        /* "do we need to fix input data alignment?" */
15944
  long cxp = (long) *((char**)xpp);
15945
15946
  realign = (cxp & 7) % SIZEOF_FLOAT;
15947
  /* sjl: manually stripmine so we can limit amount of
15948
   * vector work space reserved to LOOPCNT elements. Also
15949
   * makes vectorisation easy */
15950
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15951
    ni=Min(nelems-j,LOOPCNT);
15952
    if (realign) {
15953
      xp = tmp;
15954
    } else {
15955
      xp = (float *) *xpp;
15956
    }
15957
   /* copy the next block */
15958
#pragma cdir loopcnt=LOOPCNT
15959
#pragma cdir shortloop
15960
    for (i=0; i<ni; i++) {
15961
      /* the normal case: */
15962
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15963
     /* test for range errors (not always needed but do it anyway) */
15964
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15965
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15966
      nrange += tp[i] > X_FLOAT_MAX ;
15967
    }
15968
   /* copy workspace back if necessary */
15969
    if (realign) {
15970
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15971
      xp = (float *) *xpp;
15972
    }
15973
   /* update xpp and tp */
15974
    xp += ni;
15975
    tp += ni;
15976
    *xpp = (void*)xp;
15977
  }
15978
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15979
15980
#else   /* not SX */
15981
15982
0
  char *xp = (char *) *xpp;
15983
0
  int status = NC_NOERR;
15984
15985
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15986
0
  {
15987
0
    int lstatus = ncx_put_float_uchar(xp, tp, fillp);
15988
0
    if (status == NC_NOERR) /* report the first encountered error */
15989
0
      status = lstatus;
15990
0
  }
15991
15992
0
  *xpp = (void *)xp;
15993
0
  return status;
15994
0
#endif
15995
0
}
15996
15997
int
15998
ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
15999
0
{
16000
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16001
16002
 /* basic algorithm is:
16003
  *   - ensure sane alignment of output data
16004
  *   - copy (conversion happens automatically) input data
16005
  *     to output
16006
  *   - update tp to point at next unconverted input, and xpp to point
16007
  *     at next location for converted output
16008
  */
16009
  long i, j, ni;
16010
  float tmp[LOOPCNT];        /* in case input is misaligned */
16011
  float *xp;
16012
  int nrange = 0;         /* number of range errors */
16013
  int realign = 0;        /* "do we need to fix input data alignment?" */
16014
  long cxp = (long) *((char**)xpp);
16015
16016
  realign = (cxp & 7) % SIZEOF_FLOAT;
16017
  /* sjl: manually stripmine so we can limit amount of
16018
   * vector work space reserved to LOOPCNT elements. Also
16019
   * makes vectorisation easy */
16020
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16021
    ni=Min(nelems-j,LOOPCNT);
16022
    if (realign) {
16023
      xp = tmp;
16024
    } else {
16025
      xp = (float *) *xpp;
16026
    }
16027
   /* copy the next block */
16028
#pragma cdir loopcnt=LOOPCNT
16029
#pragma cdir shortloop
16030
    for (i=0; i<ni; i++) {
16031
      /* the normal case: */
16032
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16033
     /* test for range errors (not always needed but do it anyway) */
16034
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16035
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16036
      nrange += tp[i] > X_FLOAT_MAX ;
16037
    }
16038
   /* copy workspace back if necessary */
16039
    if (realign) {
16040
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16041
      xp = (float *) *xpp;
16042
    }
16043
   /* update xpp and tp */
16044
    xp += ni;
16045
    tp += ni;
16046
    *xpp = (void*)xp;
16047
  }
16048
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16049
16050
#else   /* not SX */
16051
16052
0
  char *xp = (char *) *xpp;
16053
0
  int status = NC_NOERR;
16054
16055
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16056
0
  {
16057
0
    int lstatus = ncx_put_float_ushort(xp, tp, fillp);
16058
0
    if (status == NC_NOERR) /* report the first encountered error */
16059
0
      status = lstatus;
16060
0
  }
16061
16062
0
  *xpp = (void *)xp;
16063
0
  return status;
16064
0
#endif
16065
0
}
16066
16067
int
16068
ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
16069
0
{
16070
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16071
16072
 /* basic algorithm is:
16073
  *   - ensure sane alignment of output data
16074
  *   - copy (conversion happens automatically) input data
16075
  *     to output
16076
  *   - update tp to point at next unconverted input, and xpp to point
16077
  *     at next location for converted output
16078
  */
16079
  long i, j, ni;
16080
  float tmp[LOOPCNT];        /* in case input is misaligned */
16081
  float *xp;
16082
  int nrange = 0;         /* number of range errors */
16083
  int realign = 0;        /* "do we need to fix input data alignment?" */
16084
  long cxp = (long) *((char**)xpp);
16085
16086
  realign = (cxp & 7) % SIZEOF_FLOAT;
16087
  /* sjl: manually stripmine so we can limit amount of
16088
   * vector work space reserved to LOOPCNT elements. Also
16089
   * makes vectorisation easy */
16090
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16091
    ni=Min(nelems-j,LOOPCNT);
16092
    if (realign) {
16093
      xp = tmp;
16094
    } else {
16095
      xp = (float *) *xpp;
16096
    }
16097
   /* copy the next block */
16098
#pragma cdir loopcnt=LOOPCNT
16099
#pragma cdir shortloop
16100
    for (i=0; i<ni; i++) {
16101
      /* the normal case: */
16102
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16103
     /* test for range errors (not always needed but do it anyway) */
16104
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16105
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16106
      nrange += tp[i] > X_FLOAT_MAX ;
16107
    }
16108
   /* copy workspace back if necessary */
16109
    if (realign) {
16110
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16111
      xp = (float *) *xpp;
16112
    }
16113
   /* update xpp and tp */
16114
    xp += ni;
16115
    tp += ni;
16116
    *xpp = (void*)xp;
16117
  }
16118
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16119
16120
#else   /* not SX */
16121
16122
0
  char *xp = (char *) *xpp;
16123
0
  int status = NC_NOERR;
16124
16125
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16126
0
  {
16127
0
    int lstatus = ncx_put_float_uint(xp, tp, fillp);
16128
0
    if (status == NC_NOERR) /* report the first encountered error */
16129
0
      status = lstatus;
16130
0
  }
16131
16132
0
  *xpp = (void *)xp;
16133
0
  return status;
16134
0
#endif
16135
0
}
16136
16137
int
16138
ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
16139
0
{
16140
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16141
16142
 /* basic algorithm is:
16143
  *   - ensure sane alignment of output data
16144
  *   - copy (conversion happens automatically) input data
16145
  *     to output
16146
  *   - update tp to point at next unconverted input, and xpp to point
16147
  *     at next location for converted output
16148
  */
16149
  long i, j, ni;
16150
  float tmp[LOOPCNT];        /* in case input is misaligned */
16151
  float *xp;
16152
  int nrange = 0;         /* number of range errors */
16153
  int realign = 0;        /* "do we need to fix input data alignment?" */
16154
  long cxp = (long) *((char**)xpp);
16155
16156
  realign = (cxp & 7) % SIZEOF_FLOAT;
16157
  /* sjl: manually stripmine so we can limit amount of
16158
   * vector work space reserved to LOOPCNT elements. Also
16159
   * makes vectorisation easy */
16160
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16161
    ni=Min(nelems-j,LOOPCNT);
16162
    if (realign) {
16163
      xp = tmp;
16164
    } else {
16165
      xp = (float *) *xpp;
16166
    }
16167
   /* copy the next block */
16168
#pragma cdir loopcnt=LOOPCNT
16169
#pragma cdir shortloop
16170
    for (i=0; i<ni; i++) {
16171
      /* the normal case: */
16172
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16173
     /* test for range errors (not always needed but do it anyway) */
16174
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16175
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16176
      nrange += tp[i] > X_FLOAT_MAX ;
16177
    }
16178
   /* copy workspace back if necessary */
16179
    if (realign) {
16180
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16181
      xp = (float *) *xpp;
16182
    }
16183
   /* update xpp and tp */
16184
    xp += ni;
16185
    tp += ni;
16186
    *xpp = (void*)xp;
16187
  }
16188
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16189
16190
#else   /* not SX */
16191
16192
0
  char *xp = (char *) *xpp;
16193
0
  int status = NC_NOERR;
16194
16195
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16196
0
  {
16197
0
    int lstatus = ncx_put_float_ulonglong(xp, tp, fillp);
16198
0
    if (status == NC_NOERR) /* report the first encountered error */
16199
0
      status = lstatus;
16200
0
  }
16201
16202
0
  *xpp = (void *)xp;
16203
0
  return status;
16204
0
#endif
16205
0
}
16206
16207
16208
/* double --------------------------------------------------------------------*/
16209
16210
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16211
/* optimized version */
16212
int
16213
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16214
0
{
16215
#ifdef WORDS_BIGENDIAN
16216
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
16217
# else
16218
0
  swapn8b(tp, *xpp, nelems);
16219
0
# endif
16220
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16221
0
  return NC_NOERR;
16222
0
}
16223
#elif defined(vax) && vax != 0
16224
int
16225
ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
16226
{
16227
  double *const end = ip + ndoubles;
16228
16229
  while (ip < end)
16230
  {
16231
  struct vax_double *const vdp =
16232
       (struct vax_double *)ip;
16233
  const struct ieee_double *const idp =
16234
       (const struct ieee_double *) (*xpp);
16235
  {
16236
    const struct dbl_limits *lim;
16237
    int ii;
16238
    for (ii = 0, lim = dbl_limits;
16239
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
16240
      ii++, lim++)
16241
    {
16242
      if ((idp->mant_lo == lim->ieee.mant_lo)
16243
        && (idp->mant_4 == lim->ieee.mant_4)
16244
        && (idp->mant_5 == lim->ieee.mant_5)
16245
        && (idp->mant_6 == lim->ieee.mant_6)
16246
        && (idp->exp_lo == lim->ieee.exp_lo)
16247
        && (idp->exp_hi == lim->ieee.exp_hi)
16248
        )
16249
      {
16250
        *vdp = lim->d;
16251
        goto doneit;
16252
      }
16253
    }
16254
  }
16255
  {
16256
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
16257
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
16258
  }
16259
  {
16260
    unsigned mant_hi = ((idp->mant_6 << 16)
16261
         | (idp->mant_5 << 8)
16262
         | idp->mant_4);
16263
    unsigned mant_lo = SWAP4(idp->mant_lo);
16264
    vdp->mantissa1 = (mant_hi >> 13);
16265
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
16266
        | (mant_lo >> 29);
16267
    vdp->mantissa3 = (mant_lo >> 13);
16268
    vdp->mantissa4 = (mant_lo << 3);
16269
  }
16270
  doneit:
16271
    vdp->sign = idp->sign;
16272
16273
    ip++;
16274
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
16275
  }
16276
  return NC_NOERR;
16277
}
16278
  /* vax */
16279
#else
16280
int
16281
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16282
{
16283
  const char *xp = *xpp;
16284
  int status = NC_NOERR;
16285
16286
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16287
  {
16288
    const int lstatus = ncx_get_double_double(xp, tp, fillp);
16289
    if (status == NC_NOERR) /* report the first encountered error */
16290
      status = lstatus;
16291
  }
16292
16293
  *xpp = (const void *)xp;
16294
  return status;
16295
}
16296
#endif
16297
int
16298
ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
16299
0
{
16300
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16301
16302
 /* basic algorithm is:
16303
  *   - ensure sane alignment of input data
16304
  *   - copy (conversion happens automatically) input data
16305
  *     to output
16306
  *   - update xpp to point at next unconverted input, and tp to point
16307
  *     at next location for converted output
16308
  */
16309
  long i, j, ni;
16310
  double tmp[LOOPCNT];        /* in case input is misaligned */
16311
  double *xp;
16312
  int nrange = 0;         /* number of range errors */
16313
  int realign = 0;        /* "do we need to fix input data alignment?" */
16314
  long cxp = (long) *((char**)xpp);
16315
16316
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16317
  /* sjl: manually stripmine so we can limit amount of
16318
   * vector work space reserved to LOOPCNT elements. Also
16319
   * makes vectorisation easy */
16320
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16321
    ni=Min(nelems-j,LOOPCNT);
16322
    if (realign) {
16323
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16324
      xp = tmp;
16325
    } else {
16326
      xp = (double *) *xpp;
16327
    }
16328
   /* copy the next block */
16329
#pragma cdir loopcnt=LOOPCNT
16330
#pragma cdir shortloop
16331
    for (i=0; i<ni; i++) {
16332
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
16333
     /* test for range errors (not always needed but do it anyway) */
16334
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16335
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16336
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
16337
    }
16338
   /* update xpp and tp */
16339
    if (realign) xp = (double *) *xpp;
16340
    xp += ni;
16341
    tp += ni;
16342
    *xpp = (void*)xp;
16343
  }
16344
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16345
16346
#else   /* not SX */
16347
0
  const char *xp = (const char *) *xpp;
16348
0
  int status = NC_NOERR;
16349
16350
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16351
0
  {
16352
0
    const int lstatus = ncx_get_double_schar(xp, tp);
16353
0
    if (status == NC_NOERR) /* report the first encountered error */
16354
0
      status = lstatus;
16355
0
  }
16356
16357
0
  *xpp = (const void *)xp;
16358
0
  return status;
16359
0
#endif
16360
0
}
16361
16362
int
16363
ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
16364
0
{
16365
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16366
16367
 /* basic algorithm is:
16368
  *   - ensure sane alignment of input data
16369
  *   - copy (conversion happens automatically) input data
16370
  *     to output
16371
  *   - update xpp to point at next unconverted input, and tp to point
16372
  *     at next location for converted output
16373
  */
16374
  long i, j, ni;
16375
  double tmp[LOOPCNT];        /* in case input is misaligned */
16376
  double *xp;
16377
  int nrange = 0;         /* number of range errors */
16378
  int realign = 0;        /* "do we need to fix input data alignment?" */
16379
  long cxp = (long) *((char**)xpp);
16380
16381
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16382
  /* sjl: manually stripmine so we can limit amount of
16383
   * vector work space reserved to LOOPCNT elements. Also
16384
   * makes vectorisation easy */
16385
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16386
    ni=Min(nelems-j,LOOPCNT);
16387
    if (realign) {
16388
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16389
      xp = tmp;
16390
    } else {
16391
      xp = (double *) *xpp;
16392
    }
16393
   /* copy the next block */
16394
#pragma cdir loopcnt=LOOPCNT
16395
#pragma cdir shortloop
16396
    for (i=0; i<ni; i++) {
16397
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
16398
     /* test for range errors (not always needed but do it anyway) */
16399
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16400
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16401
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
16402
    }
16403
   /* update xpp and tp */
16404
    if (realign) xp = (double *) *xpp;
16405
    xp += ni;
16406
    tp += ni;
16407
    *xpp = (void*)xp;
16408
  }
16409
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16410
16411
#else   /* not SX */
16412
0
  const char *xp = (const char *) *xpp;
16413
0
  int status = NC_NOERR;
16414
16415
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16416
0
  {
16417
0
    const int lstatus = ncx_get_double_short(xp, tp);
16418
0
    if (status == NC_NOERR) /* report the first encountered error */
16419
0
      status = lstatus;
16420
0
  }
16421
16422
0
  *xpp = (const void *)xp;
16423
0
  return status;
16424
0
#endif
16425
0
}
16426
16427
int
16428
ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
16429
0
{
16430
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16431
16432
 /* basic algorithm is:
16433
  *   - ensure sane alignment of input data
16434
  *   - copy (conversion happens automatically) input data
16435
  *     to output
16436
  *   - update xpp to point at next unconverted input, and tp to point
16437
  *     at next location for converted output
16438
  */
16439
  long i, j, ni;
16440
  double tmp[LOOPCNT];        /* in case input is misaligned */
16441
  double *xp;
16442
  int nrange = 0;         /* number of range errors */
16443
  int realign = 0;        /* "do we need to fix input data alignment?" */
16444
  long cxp = (long) *((char**)xpp);
16445
16446
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16447
  /* sjl: manually stripmine so we can limit amount of
16448
   * vector work space reserved to LOOPCNT elements. Also
16449
   * makes vectorisation easy */
16450
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16451
    ni=Min(nelems-j,LOOPCNT);
16452
    if (realign) {
16453
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16454
      xp = tmp;
16455
    } else {
16456
      xp = (double *) *xpp;
16457
    }
16458
   /* copy the next block */
16459
#pragma cdir loopcnt=LOOPCNT
16460
#pragma cdir shortloop
16461
    for (i=0; i<ni; i++) {
16462
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
16463
     /* test for range errors (not always needed but do it anyway) */
16464
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16465
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16466
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
16467
    }
16468
   /* update xpp and tp */
16469
    if (realign) xp = (double *) *xpp;
16470
    xp += ni;
16471
    tp += ni;
16472
    *xpp = (void*)xp;
16473
  }
16474
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16475
16476
#else   /* not SX */
16477
0
  const char *xp = (const char *) *xpp;
16478
0
  int status = NC_NOERR;
16479
16480
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16481
0
  {
16482
0
    const int lstatus = ncx_get_double_int(xp, tp);
16483
0
    if (status == NC_NOERR) /* report the first encountered error */
16484
0
      status = lstatus;
16485
0
  }
16486
16487
0
  *xpp = (const void *)xp;
16488
0
  return status;
16489
0
#endif
16490
0
}
16491
16492
int
16493
ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
16494
0
{
16495
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16496
16497
 /* basic algorithm is:
16498
  *   - ensure sane alignment of input data
16499
  *   - copy (conversion happens automatically) input data
16500
  *     to output
16501
  *   - update xpp to point at next unconverted input, and tp to point
16502
  *     at next location for converted output
16503
  */
16504
  long i, j, ni;
16505
  double tmp[LOOPCNT];        /* in case input is misaligned */
16506
  double *xp;
16507
  int nrange = 0;         /* number of range errors */
16508
  int realign = 0;        /* "do we need to fix input data alignment?" */
16509
  long cxp = (long) *((char**)xpp);
16510
16511
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16512
  /* sjl: manually stripmine so we can limit amount of
16513
   * vector work space reserved to LOOPCNT elements. Also
16514
   * makes vectorisation easy */
16515
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16516
    ni=Min(nelems-j,LOOPCNT);
16517
    if (realign) {
16518
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16519
      xp = tmp;
16520
    } else {
16521
      xp = (double *) *xpp;
16522
    }
16523
   /* copy the next block */
16524
#pragma cdir loopcnt=LOOPCNT
16525
#pragma cdir shortloop
16526
    for (i=0; i<ni; i++) {
16527
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
16528
     /* test for range errors (not always needed but do it anyway) */
16529
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16530
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16531
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
16532
    }
16533
   /* update xpp and tp */
16534
    if (realign) xp = (double *) *xpp;
16535
    xp += ni;
16536
    tp += ni;
16537
    *xpp = (void*)xp;
16538
  }
16539
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16540
16541
#else   /* not SX */
16542
0
  const char *xp = (const char *) *xpp;
16543
0
  int status = NC_NOERR;
16544
16545
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16546
0
  {
16547
0
    const int lstatus = ncx_get_double_long(xp, tp);
16548
0
    if (status == NC_NOERR) /* report the first encountered error */
16549
0
      status = lstatus;
16550
0
  }
16551
16552
0
  *xpp = (const void *)xp;
16553
0
  return status;
16554
0
#endif
16555
0
}
16556
16557
int
16558
ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
16559
0
{
16560
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16561
16562
 /* basic algorithm is:
16563
  *   - ensure sane alignment of input data
16564
  *   - copy (conversion happens automatically) input data
16565
  *     to output
16566
  *   - update xpp to point at next unconverted input, and tp to point
16567
  *     at next location for converted output
16568
  */
16569
  long i, j, ni;
16570
  double tmp[LOOPCNT];        /* in case input is misaligned */
16571
  double *xp;
16572
  int nrange = 0;         /* number of range errors */
16573
  int realign = 0;        /* "do we need to fix input data alignment?" */
16574
  long cxp = (long) *((char**)xpp);
16575
16576
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16577
  /* sjl: manually stripmine so we can limit amount of
16578
   * vector work space reserved to LOOPCNT elements. Also
16579
   * makes vectorisation easy */
16580
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16581
    ni=Min(nelems-j,LOOPCNT);
16582
    if (realign) {
16583
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16584
      xp = tmp;
16585
    } else {
16586
      xp = (double *) *xpp;
16587
    }
16588
   /* copy the next block */
16589
#pragma cdir loopcnt=LOOPCNT
16590
#pragma cdir shortloop
16591
    for (i=0; i<ni; i++) {
16592
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
16593
     /* test for range errors (not always needed but do it anyway) */
16594
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16595
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16596
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
16597
    }
16598
   /* update xpp and tp */
16599
    if (realign) xp = (double *) *xpp;
16600
    xp += ni;
16601
    tp += ni;
16602
    *xpp = (void*)xp;
16603
  }
16604
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16605
16606
#else   /* not SX */
16607
0
  const char *xp = (const char *) *xpp;
16608
0
  int status = NC_NOERR;
16609
16610
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16611
0
  {
16612
0
    const int lstatus = ncx_get_double_float(xp, tp);
16613
0
    if (status == NC_NOERR) /* report the first encountered error */
16614
0
      status = lstatus;
16615
0
  }
16616
16617
0
  *xpp = (const void *)xp;
16618
0
  return status;
16619
0
#endif
16620
0
}
16621
16622
int
16623
ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp)
16624
0
{
16625
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16626
16627
 /* basic algorithm is:
16628
  *   - ensure sane alignment of input data
16629
  *   - copy (conversion happens automatically) input data
16630
  *     to output
16631
  *   - update xpp to point at next unconverted input, and tp to point
16632
  *     at next location for converted output
16633
  */
16634
  long i, j, ni;
16635
  double tmp[LOOPCNT];        /* in case input is misaligned */
16636
  double *xp;
16637
  int nrange = 0;         /* number of range errors */
16638
  int realign = 0;        /* "do we need to fix input data alignment?" */
16639
  long cxp = (long) *((char**)xpp);
16640
16641
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16642
  /* sjl: manually stripmine so we can limit amount of
16643
   * vector work space reserved to LOOPCNT elements. Also
16644
   * makes vectorisation easy */
16645
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16646
    ni=Min(nelems-j,LOOPCNT);
16647
    if (realign) {
16648
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16649
      xp = tmp;
16650
    } else {
16651
      xp = (double *) *xpp;
16652
    }
16653
   /* copy the next block */
16654
#pragma cdir loopcnt=LOOPCNT
16655
#pragma cdir shortloop
16656
    for (i=0; i<ni; i++) {
16657
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
16658
     /* test for range errors (not always needed but do it anyway) */
16659
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16660
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16661
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
16662
    }
16663
   /* update xpp and tp */
16664
    if (realign) xp = (double *) *xpp;
16665
    xp += ni;
16666
    tp += ni;
16667
    *xpp = (void*)xp;
16668
  }
16669
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16670
16671
#else   /* not SX */
16672
0
  const char *xp = (const char *) *xpp;
16673
0
  int status = NC_NOERR;
16674
16675
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16676
0
  {
16677
0
    const int lstatus = ncx_get_double_longlong(xp, tp);
16678
0
    if (status == NC_NOERR) /* report the first encountered error */
16679
0
      status = lstatus;
16680
0
  }
16681
16682
0
  *xpp = (const void *)xp;
16683
0
  return status;
16684
0
#endif
16685
0
}
16686
16687
int
16688
ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
16689
0
{
16690
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16691
16692
 /* basic algorithm is:
16693
  *   - ensure sane alignment of input data
16694
  *   - copy (conversion happens automatically) input data
16695
  *     to output
16696
  *   - update xpp to point at next unconverted input, and tp to point
16697
  *     at next location for converted output
16698
  */
16699
  long i, j, ni;
16700
  double tmp[LOOPCNT];        /* in case input is misaligned */
16701
  double *xp;
16702
  int nrange = 0;         /* number of range errors */
16703
  int realign = 0;        /* "do we need to fix input data alignment?" */
16704
  long cxp = (long) *((char**)xpp);
16705
16706
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16707
  /* sjl: manually stripmine so we can limit amount of
16708
   * vector work space reserved to LOOPCNT elements. Also
16709
   * makes vectorisation easy */
16710
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16711
    ni=Min(nelems-j,LOOPCNT);
16712
    if (realign) {
16713
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16714
      xp = tmp;
16715
    } else {
16716
      xp = (double *) *xpp;
16717
    }
16718
   /* copy the next block */
16719
#pragma cdir loopcnt=LOOPCNT
16720
#pragma cdir shortloop
16721
    for (i=0; i<ni; i++) {
16722
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
16723
     /* test for range errors (not always needed but do it anyway) */
16724
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16725
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16726
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
16727
    }
16728
   /* update xpp and tp */
16729
    if (realign) xp = (double *) *xpp;
16730
    xp += ni;
16731
    tp += ni;
16732
    *xpp = (void*)xp;
16733
  }
16734
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16735
16736
#else   /* not SX */
16737
0
  const char *xp = (const char *) *xpp;
16738
0
  int status = NC_NOERR;
16739
16740
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16741
0
  {
16742
0
    const int lstatus = ncx_get_double_uchar(xp, tp);
16743
0
    if (status == NC_NOERR) /* report the first encountered error */
16744
0
      status = lstatus;
16745
0
  }
16746
16747
0
  *xpp = (const void *)xp;
16748
0
  return status;
16749
0
#endif
16750
0
}
16751
16752
int
16753
ncx_getn_double_ushort(const void **xpp, size_t nelems, ushort *tp)
16754
0
{
16755
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16756
16757
 /* basic algorithm is:
16758
  *   - ensure sane alignment of input data
16759
  *   - copy (conversion happens automatically) input data
16760
  *     to output
16761
  *   - update xpp to point at next unconverted input, and tp to point
16762
  *     at next location for converted output
16763
  */
16764
  long i, j, ni;
16765
  double tmp[LOOPCNT];        /* in case input is misaligned */
16766
  double *xp;
16767
  int nrange = 0;         /* number of range errors */
16768
  int realign = 0;        /* "do we need to fix input data alignment?" */
16769
  long cxp = (long) *((char**)xpp);
16770
16771
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16772
  /* sjl: manually stripmine so we can limit amount of
16773
   * vector work space reserved to LOOPCNT elements. Also
16774
   * makes vectorisation easy */
16775
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16776
    ni=Min(nelems-j,LOOPCNT);
16777
    if (realign) {
16778
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16779
      xp = tmp;
16780
    } else {
16781
      xp = (double *) *xpp;
16782
    }
16783
   /* copy the next block */
16784
#pragma cdir loopcnt=LOOPCNT
16785
#pragma cdir shortloop
16786
    for (i=0; i<ni; i++) {
16787
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
16788
     /* test for range errors (not always needed but do it anyway) */
16789
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16790
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16791
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
16792
    }
16793
   /* update xpp and tp */
16794
    if (realign) xp = (double *) *xpp;
16795
    xp += ni;
16796
    tp += ni;
16797
    *xpp = (void*)xp;
16798
  }
16799
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16800
16801
#else   /* not SX */
16802
0
  const char *xp = (const char *) *xpp;
16803
0
  int status = NC_NOERR;
16804
16805
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16806
0
  {
16807
0
    const int lstatus = ncx_get_double_ushort(xp, tp);
16808
0
    if (status == NC_NOERR) /* report the first encountered error */
16809
0
      status = lstatus;
16810
0
  }
16811
16812
0
  *xpp = (const void *)xp;
16813
0
  return status;
16814
0
#endif
16815
0
}
16816
16817
int
16818
ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp)
16819
0
{
16820
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16821
16822
 /* basic algorithm is:
16823
  *   - ensure sane alignment of input data
16824
  *   - copy (conversion happens automatically) input data
16825
  *     to output
16826
  *   - update xpp to point at next unconverted input, and tp to point
16827
  *     at next location for converted output
16828
  */
16829
  long i, j, ni;
16830
  double tmp[LOOPCNT];        /* in case input is misaligned */
16831
  double *xp;
16832
  int nrange = 0;         /* number of range errors */
16833
  int realign = 0;        /* "do we need to fix input data alignment?" */
16834
  long cxp = (long) *((char**)xpp);
16835
16836
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16837
  /* sjl: manually stripmine so we can limit amount of
16838
   * vector work space reserved to LOOPCNT elements. Also
16839
   * makes vectorisation easy */
16840
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16841
    ni=Min(nelems-j,LOOPCNT);
16842
    if (realign) {
16843
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16844
      xp = tmp;
16845
    } else {
16846
      xp = (double *) *xpp;
16847
    }
16848
   /* copy the next block */
16849
#pragma cdir loopcnt=LOOPCNT
16850
#pragma cdir shortloop
16851
    for (i=0; i<ni; i++) {
16852
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
16853
     /* test for range errors (not always needed but do it anyway) */
16854
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16855
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16856
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
16857
    }
16858
   /* update xpp and tp */
16859
    if (realign) xp = (double *) *xpp;
16860
    xp += ni;
16861
    tp += ni;
16862
    *xpp = (void*)xp;
16863
  }
16864
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16865
16866
#else   /* not SX */
16867
0
  const char *xp = (const char *) *xpp;
16868
0
  int status = NC_NOERR;
16869
16870
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16871
0
  {
16872
0
    const int lstatus = ncx_get_double_uint(xp, tp);
16873
0
    if (status == NC_NOERR) /* report the first encountered error */
16874
0
      status = lstatus;
16875
0
  }
16876
16877
0
  *xpp = (const void *)xp;
16878
0
  return status;
16879
0
#endif
16880
0
}
16881
16882
int
16883
ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
16884
0
{
16885
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16886
16887
 /* basic algorithm is:
16888
  *   - ensure sane alignment of input data
16889
  *   - copy (conversion happens automatically) input data
16890
  *     to output
16891
  *   - update xpp to point at next unconverted input, and tp to point
16892
  *     at next location for converted output
16893
  */
16894
  long i, j, ni;
16895
  double tmp[LOOPCNT];        /* in case input is misaligned */
16896
  double *xp;
16897
  int nrange = 0;         /* number of range errors */
16898
  int realign = 0;        /* "do we need to fix input data alignment?" */
16899
  long cxp = (long) *((char**)xpp);
16900
16901
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16902
  /* sjl: manually stripmine so we can limit amount of
16903
   * vector work space reserved to LOOPCNT elements. Also
16904
   * makes vectorisation easy */
16905
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16906
    ni=Min(nelems-j,LOOPCNT);
16907
    if (realign) {
16908
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16909
      xp = tmp;
16910
    } else {
16911
      xp = (double *) *xpp;
16912
    }
16913
   /* copy the next block */
16914
#pragma cdir loopcnt=LOOPCNT
16915
#pragma cdir shortloop
16916
    for (i=0; i<ni; i++) {
16917
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
16918
     /* test for range errors (not always needed but do it anyway) */
16919
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16920
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16921
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
16922
    }
16923
   /* update xpp and tp */
16924
    if (realign) xp = (double *) *xpp;
16925
    xp += ni;
16926
    tp += ni;
16927
    *xpp = (void*)xp;
16928
  }
16929
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16930
16931
#else   /* not SX */
16932
0
  const char *xp = (const char *) *xpp;
16933
0
  int status = NC_NOERR;
16934
16935
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16936
0
  {
16937
0
    const int lstatus = ncx_get_double_ulonglong(xp, tp);
16938
0
    if (status == NC_NOERR) /* report the first encountered error */
16939
0
      status = lstatus;
16940
0
  }
16941
16942
0
  *xpp = (const void *)xp;
16943
0
  return status;
16944
0
#endif
16945
0
}
16946
16947
16948
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16949
/* optimized version */
16950
int
16951
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
16952
0
{
16953
#ifdef WORDS_BIGENDIAN
16954
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
16955
# else
16956
0
  swapn8b(*xpp, tp, nelems);
16957
0
# endif
16958
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16959
0
  return NC_NOERR;
16960
0
}
16961
#elif defined(vax) && vax != 0
16962
int
16963
ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip, void *fillp)
16964
{
16965
  const double *const end = ip + ndoubles;
16966
16967
  while (ip < end)
16968
  {
16969
  const struct vax_double *const vdp =
16970
      (const struct vax_double *)ip;
16971
  struct ieee_double *const idp =
16972
       (struct ieee_double *) (*xpp);
16973
16974
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
16975
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
16976
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
16977
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
16978
    (vdp->exp == dbl_limits[0].d.exp))
16979
  {
16980
    *idp = dbl_limits[0].ieee;
16981
    goto shipit;
16982
  }
16983
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
16984
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
16985
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
16986
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
16987
    (vdp->exp == dbl_limits[1].d.exp))
16988
  {
16989
    *idp = dbl_limits[1].ieee;
16990
    goto shipit;
16991
  }
16992
16993
  {
16994
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
16995
16996
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
16997
      (vdp->mantissa3 << 13) |
16998
      ((vdp->mantissa4 >> 3) & MASK(13));
16999
17000
    unsigned mant_hi = (vdp->mantissa1 << 13)
17001
         | (vdp->mantissa2 >> 3);
17002
17003
    if ((vdp->mantissa4 & 7) > 4)
17004
    {
17005
      /* round up */
17006
      mant_lo++;
17007
      if (mant_lo == 0)
17008
      {
17009
        mant_hi++;
17010
        if (mant_hi > 0xffffff)
17011
        {
17012
          mant_hi = 0;
17013
          exp++;
17014
        }
17015
      }
17016
    }
17017
17018
    idp->mant_lo = SWAP4(mant_lo);
17019
    idp->mant_6 = mant_hi >> 16;
17020
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
17021
    idp->mant_4 = mant_hi;
17022
    idp->exp_hi = exp >> 4;
17023
    idp->exp_lo = exp;
17024
  }
17025
17026
  shipit:
17027
    idp->sign = vdp->sign;
17028
17029
    ip++;
17030
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
17031
  }
17032
  return NC_NOERR;
17033
}
17034
  /* vax */
17035
#else
17036
int
17037
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17038
{
17039
  char *xp = *xpp;
17040
  int status = NC_NOERR;
17041
17042
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17043
  {
17044
    int lstatus = ncx_put_double_double(xp, tp, fillp);
17045
    if (status == NC_NOERR) /* report the first encountered error */
17046
      status = lstatus;
17047
  }
17048
17049
  *xpp = (void *)xp;
17050
  return status;
17051
}
17052
#endif
17053
int
17054
ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
17055
0
{
17056
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17057
17058
 /* basic algorithm is:
17059
  *   - ensure sane alignment of output data
17060
  *   - copy (conversion happens automatically) input data
17061
  *     to output
17062
  *   - update tp to point at next unconverted input, and xpp to point
17063
  *     at next location for converted output
17064
  */
17065
  long i, j, ni;
17066
  double tmp[LOOPCNT];        /* in case input is misaligned */
17067
  double *xp;
17068
  int nrange = 0;         /* number of range errors */
17069
  int realign = 0;        /* "do we need to fix input data alignment?" */
17070
  long cxp = (long) *((char**)xpp);
17071
17072
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17073
  /* sjl: manually stripmine so we can limit amount of
17074
   * vector work space reserved to LOOPCNT elements. Also
17075
   * makes vectorisation easy */
17076
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17077
    ni=Min(nelems-j,LOOPCNT);
17078
    if (realign) {
17079
      xp = tmp;
17080
    } else {
17081
      xp = (double *) *xpp;
17082
    }
17083
   /* copy the next block */
17084
#pragma cdir loopcnt=LOOPCNT
17085
#pragma cdir shortloop
17086
    for (i=0; i<ni; i++) {
17087
      /* the normal case: */
17088
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17089
     /* test for range errors (not always needed but do it anyway) */
17090
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17091
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17092
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17093
    }
17094
   /* copy workspace back if necessary */
17095
    if (realign) {
17096
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17097
      xp = (double *) *xpp;
17098
    }
17099
   /* update xpp and tp */
17100
    xp += ni;
17101
    tp += ni;
17102
    *xpp = (void*)xp;
17103
  }
17104
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17105
17106
#else   /* not SX */
17107
17108
0
  char *xp = (char *) *xpp;
17109
0
  int status = NC_NOERR;
17110
17111
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17112
0
  {
17113
0
    int lstatus = ncx_put_double_schar(xp, tp, fillp);
17114
0
    if (status == NC_NOERR) /* report the first encountered error */
17115
0
      status = lstatus;
17116
0
  }
17117
17118
0
  *xpp = (void *)xp;
17119
0
  return status;
17120
0
#endif
17121
0
}
17122
17123
int
17124
ncx_putn_double_short(void **xpp, size_t nelems, const short *tp, void *fillp)
17125
0
{
17126
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17127
17128
 /* basic algorithm is:
17129
  *   - ensure sane alignment of output data
17130
  *   - copy (conversion happens automatically) input data
17131
  *     to output
17132
  *   - update tp to point at next unconverted input, and xpp to point
17133
  *     at next location for converted output
17134
  */
17135
  long i, j, ni;
17136
  double tmp[LOOPCNT];        /* in case input is misaligned */
17137
  double *xp;
17138
  int nrange = 0;         /* number of range errors */
17139
  int realign = 0;        /* "do we need to fix input data alignment?" */
17140
  long cxp = (long) *((char**)xpp);
17141
17142
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17143
  /* sjl: manually stripmine so we can limit amount of
17144
   * vector work space reserved to LOOPCNT elements. Also
17145
   * makes vectorisation easy */
17146
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17147
    ni=Min(nelems-j,LOOPCNT);
17148
    if (realign) {
17149
      xp = tmp;
17150
    } else {
17151
      xp = (double *) *xpp;
17152
    }
17153
   /* copy the next block */
17154
#pragma cdir loopcnt=LOOPCNT
17155
#pragma cdir shortloop
17156
    for (i=0; i<ni; i++) {
17157
      /* the normal case: */
17158
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17159
     /* test for range errors (not always needed but do it anyway) */
17160
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17161
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17162
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17163
    }
17164
   /* copy workspace back if necessary */
17165
    if (realign) {
17166
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17167
      xp = (double *) *xpp;
17168
    }
17169
   /* update xpp and tp */
17170
    xp += ni;
17171
    tp += ni;
17172
    *xpp = (void*)xp;
17173
  }
17174
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17175
17176
#else   /* not SX */
17177
17178
0
  char *xp = (char *) *xpp;
17179
0
  int status = NC_NOERR;
17180
17181
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17182
0
  {
17183
0
    int lstatus = ncx_put_double_short(xp, tp, fillp);
17184
0
    if (status == NC_NOERR) /* report the first encountered error */
17185
0
      status = lstatus;
17186
0
  }
17187
17188
0
  *xpp = (void *)xp;
17189
0
  return status;
17190
0
#endif
17191
0
}
17192
17193
int
17194
ncx_putn_double_int(void **xpp, size_t nelems, const int *tp, void *fillp)
17195
0
{
17196
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17197
17198
 /* basic algorithm is:
17199
  *   - ensure sane alignment of output data
17200
  *   - copy (conversion happens automatically) input data
17201
  *     to output
17202
  *   - update tp to point at next unconverted input, and xpp to point
17203
  *     at next location for converted output
17204
  */
17205
  long i, j, ni;
17206
  double tmp[LOOPCNT];        /* in case input is misaligned */
17207
  double *xp;
17208
  int nrange = 0;         /* number of range errors */
17209
  int realign = 0;        /* "do we need to fix input data alignment?" */
17210
  long cxp = (long) *((char**)xpp);
17211
17212
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17213
  /* sjl: manually stripmine so we can limit amount of
17214
   * vector work space reserved to LOOPCNT elements. Also
17215
   * makes vectorisation easy */
17216
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17217
    ni=Min(nelems-j,LOOPCNT);
17218
    if (realign) {
17219
      xp = tmp;
17220
    } else {
17221
      xp = (double *) *xpp;
17222
    }
17223
   /* copy the next block */
17224
#pragma cdir loopcnt=LOOPCNT
17225
#pragma cdir shortloop
17226
    for (i=0; i<ni; i++) {
17227
      /* the normal case: */
17228
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17229
     /* test for range errors (not always needed but do it anyway) */
17230
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17231
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17232
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17233
    }
17234
   /* copy workspace back if necessary */
17235
    if (realign) {
17236
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17237
      xp = (double *) *xpp;
17238
    }
17239
   /* update xpp and tp */
17240
    xp += ni;
17241
    tp += ni;
17242
    *xpp = (void*)xp;
17243
  }
17244
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17245
17246
#else   /* not SX */
17247
17248
0
  char *xp = (char *) *xpp;
17249
0
  int status = NC_NOERR;
17250
17251
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17252
0
  {
17253
0
    int lstatus = ncx_put_double_int(xp, tp, fillp);
17254
0
    if (status == NC_NOERR) /* report the first encountered error */
17255
0
      status = lstatus;
17256
0
  }
17257
17258
0
  *xpp = (void *)xp;
17259
0
  return status;
17260
0
#endif
17261
0
}
17262
17263
int
17264
ncx_putn_double_long(void **xpp, size_t nelems, const long *tp, void *fillp)
17265
0
{
17266
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17267
17268
 /* basic algorithm is:
17269
  *   - ensure sane alignment of output data
17270
  *   - copy (conversion happens automatically) input data
17271
  *     to output
17272
  *   - update tp to point at next unconverted input, and xpp to point
17273
  *     at next location for converted output
17274
  */
17275
  long i, j, ni;
17276
  double tmp[LOOPCNT];        /* in case input is misaligned */
17277
  double *xp;
17278
  int nrange = 0;         /* number of range errors */
17279
  int realign = 0;        /* "do we need to fix input data alignment?" */
17280
  long cxp = (long) *((char**)xpp);
17281
17282
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17283
  /* sjl: manually stripmine so we can limit amount of
17284
   * vector work space reserved to LOOPCNT elements. Also
17285
   * makes vectorisation easy */
17286
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17287
    ni=Min(nelems-j,LOOPCNT);
17288
    if (realign) {
17289
      xp = tmp;
17290
    } else {
17291
      xp = (double *) *xpp;
17292
    }
17293
   /* copy the next block */
17294
#pragma cdir loopcnt=LOOPCNT
17295
#pragma cdir shortloop
17296
    for (i=0; i<ni; i++) {
17297
      /* the normal case: */
17298
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17299
     /* test for range errors (not always needed but do it anyway) */
17300
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17301
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17302
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17303
    }
17304
   /* copy workspace back if necessary */
17305
    if (realign) {
17306
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17307
      xp = (double *) *xpp;
17308
    }
17309
   /* update xpp and tp */
17310
    xp += ni;
17311
    tp += ni;
17312
    *xpp = (void*)xp;
17313
  }
17314
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17315
17316
#else   /* not SX */
17317
17318
0
  char *xp = (char *) *xpp;
17319
0
  int status = NC_NOERR;
17320
17321
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17322
0
  {
17323
0
    int lstatus = ncx_put_double_long(xp, tp, fillp);
17324
0
    if (status == NC_NOERR) /* report the first encountered error */
17325
0
      status = lstatus;
17326
0
  }
17327
17328
0
  *xpp = (void *)xp;
17329
0
  return status;
17330
0
#endif
17331
0
}
17332
17333
int
17334
ncx_putn_double_float(void **xpp, size_t nelems, const float *tp, void *fillp)
17335
0
{
17336
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17337
17338
 /* basic algorithm is:
17339
  *   - ensure sane alignment of output data
17340
  *   - copy (conversion happens automatically) input data
17341
  *     to output
17342
  *   - update tp to point at next unconverted input, and xpp to point
17343
  *     at next location for converted output
17344
  */
17345
  long i, j, ni;
17346
  double tmp[LOOPCNT];        /* in case input is misaligned */
17347
  double *xp;
17348
  int nrange = 0;         /* number of range errors */
17349
  int realign = 0;        /* "do we need to fix input data alignment?" */
17350
  long cxp = (long) *((char**)xpp);
17351
17352
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17353
  /* sjl: manually stripmine so we can limit amount of
17354
   * vector work space reserved to LOOPCNT elements. Also
17355
   * makes vectorisation easy */
17356
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17357
    ni=Min(nelems-j,LOOPCNT);
17358
    if (realign) {
17359
      xp = tmp;
17360
    } else {
17361
      xp = (double *) *xpp;
17362
    }
17363
   /* copy the next block */
17364
#pragma cdir loopcnt=LOOPCNT
17365
#pragma cdir shortloop
17366
    for (i=0; i<ni; i++) {
17367
      /* the normal case: */
17368
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17369
     /* test for range errors (not always needed but do it anyway) */
17370
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17371
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17372
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17373
    }
17374
   /* copy workspace back if necessary */
17375
    if (realign) {
17376
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17377
      xp = (double *) *xpp;
17378
    }
17379
   /* update xpp and tp */
17380
    xp += ni;
17381
    tp += ni;
17382
    *xpp = (void*)xp;
17383
  }
17384
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17385
17386
#else   /* not SX */
17387
17388
0
  char *xp = (char *) *xpp;
17389
0
  int status = NC_NOERR;
17390
17391
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17392
0
  {
17393
0
    int lstatus = ncx_put_double_float(xp, tp, fillp);
17394
0
    if (status == NC_NOERR) /* report the first encountered error */
17395
0
      status = lstatus;
17396
0
  }
17397
17398
0
  *xpp = (void *)xp;
17399
0
  return status;
17400
0
#endif
17401
0
}
17402
17403
int
17404
ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
17405
0
{
17406
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17407
17408
 /* basic algorithm is:
17409
  *   - ensure sane alignment of output data
17410
  *   - copy (conversion happens automatically) input data
17411
  *     to output
17412
  *   - update tp to point at next unconverted input, and xpp to point
17413
  *     at next location for converted output
17414
  */
17415
  long i, j, ni;
17416
  double tmp[LOOPCNT];        /* in case input is misaligned */
17417
  double *xp;
17418
  int nrange = 0;         /* number of range errors */
17419
  int realign = 0;        /* "do we need to fix input data alignment?" */
17420
  long cxp = (long) *((char**)xpp);
17421
17422
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17423
  /* sjl: manually stripmine so we can limit amount of
17424
   * vector work space reserved to LOOPCNT elements. Also
17425
   * makes vectorisation easy */
17426
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17427
    ni=Min(nelems-j,LOOPCNT);
17428
    if (realign) {
17429
      xp = tmp;
17430
    } else {
17431
      xp = (double *) *xpp;
17432
    }
17433
   /* copy the next block */
17434
#pragma cdir loopcnt=LOOPCNT
17435
#pragma cdir shortloop
17436
    for (i=0; i<ni; i++) {
17437
      /* the normal case: */
17438
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17439
     /* test for range errors (not always needed but do it anyway) */
17440
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17441
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17442
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17443
    }
17444
   /* copy workspace back if necessary */
17445
    if (realign) {
17446
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17447
      xp = (double *) *xpp;
17448
    }
17449
   /* update xpp and tp */
17450
    xp += ni;
17451
    tp += ni;
17452
    *xpp = (void*)xp;
17453
  }
17454
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17455
17456
#else   /* not SX */
17457
17458
0
  char *xp = (char *) *xpp;
17459
0
  int status = NC_NOERR;
17460
17461
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17462
0
  {
17463
0
    int lstatus = ncx_put_double_longlong(xp, tp, fillp);
17464
0
    if (status == NC_NOERR) /* report the first encountered error */
17465
0
      status = lstatus;
17466
0
  }
17467
17468
0
  *xpp = (void *)xp;
17469
0
  return status;
17470
0
#endif
17471
0
}
17472
17473
int
17474
ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
17475
0
{
17476
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17477
17478
 /* basic algorithm is:
17479
  *   - ensure sane alignment of output data
17480
  *   - copy (conversion happens automatically) input data
17481
  *     to output
17482
  *   - update tp to point at next unconverted input, and xpp to point
17483
  *     at next location for converted output
17484
  */
17485
  long i, j, ni;
17486
  double tmp[LOOPCNT];        /* in case input is misaligned */
17487
  double *xp;
17488
  int nrange = 0;         /* number of range errors */
17489
  int realign = 0;        /* "do we need to fix input data alignment?" */
17490
  long cxp = (long) *((char**)xpp);
17491
17492
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17493
  /* sjl: manually stripmine so we can limit amount of
17494
   * vector work space reserved to LOOPCNT elements. Also
17495
   * makes vectorisation easy */
17496
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17497
    ni=Min(nelems-j,LOOPCNT);
17498
    if (realign) {
17499
      xp = tmp;
17500
    } else {
17501
      xp = (double *) *xpp;
17502
    }
17503
   /* copy the next block */
17504
#pragma cdir loopcnt=LOOPCNT
17505
#pragma cdir shortloop
17506
    for (i=0; i<ni; i++) {
17507
      /* the normal case: */
17508
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17509
     /* test for range errors (not always needed but do it anyway) */
17510
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17511
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17512
      nrange += tp[i] > X_DOUBLE_MAX ;
17513
    }
17514
   /* copy workspace back if necessary */
17515
    if (realign) {
17516
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17517
      xp = (double *) *xpp;
17518
    }
17519
   /* update xpp and tp */
17520
    xp += ni;
17521
    tp += ni;
17522
    *xpp = (void*)xp;
17523
  }
17524
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17525
17526
#else   /* not SX */
17527
17528
0
  char *xp = (char *) *xpp;
17529
0
  int status = NC_NOERR;
17530
17531
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17532
0
  {
17533
0
    int lstatus = ncx_put_double_uchar(xp, tp, fillp);
17534
0
    if (status == NC_NOERR) /* report the first encountered error */
17535
0
      status = lstatus;
17536
0
  }
17537
17538
0
  *xpp = (void *)xp;
17539
0
  return status;
17540
0
#endif
17541
0
}
17542
17543
int
17544
ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
17545
0
{
17546
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17547
17548
 /* basic algorithm is:
17549
  *   - ensure sane alignment of output data
17550
  *   - copy (conversion happens automatically) input data
17551
  *     to output
17552
  *   - update tp to point at next unconverted input, and xpp to point
17553
  *     at next location for converted output
17554
  */
17555
  long i, j, ni;
17556
  double tmp[LOOPCNT];        /* in case input is misaligned */
17557
  double *xp;
17558
  int nrange = 0;         /* number of range errors */
17559
  int realign = 0;        /* "do we need to fix input data alignment?" */
17560
  long cxp = (long) *((char**)xpp);
17561
17562
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17563
  /* sjl: manually stripmine so we can limit amount of
17564
   * vector work space reserved to LOOPCNT elements. Also
17565
   * makes vectorisation easy */
17566
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17567
    ni=Min(nelems-j,LOOPCNT);
17568
    if (realign) {
17569
      xp = tmp;
17570
    } else {
17571
      xp = (double *) *xpp;
17572
    }
17573
   /* copy the next block */
17574
#pragma cdir loopcnt=LOOPCNT
17575
#pragma cdir shortloop
17576
    for (i=0; i<ni; i++) {
17577
      /* the normal case: */
17578
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17579
     /* test for range errors (not always needed but do it anyway) */
17580
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17581
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17582
      nrange += tp[i] > X_DOUBLE_MAX ;
17583
    }
17584
   /* copy workspace back if necessary */
17585
    if (realign) {
17586
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17587
      xp = (double *) *xpp;
17588
    }
17589
   /* update xpp and tp */
17590
    xp += ni;
17591
    tp += ni;
17592
    *xpp = (void*)xp;
17593
  }
17594
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17595
17596
#else   /* not SX */
17597
17598
0
  char *xp = (char *) *xpp;
17599
0
  int status = NC_NOERR;
17600
17601
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17602
0
  {
17603
0
    int lstatus = ncx_put_double_ushort(xp, tp, fillp);
17604
0
    if (status == NC_NOERR) /* report the first encountered error */
17605
0
      status = lstatus;
17606
0
  }
17607
17608
0
  *xpp = (void *)xp;
17609
0
  return status;
17610
0
#endif
17611
0
}
17612
17613
int
17614
ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
17615
0
{
17616
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17617
17618
 /* basic algorithm is:
17619
  *   - ensure sane alignment of output data
17620
  *   - copy (conversion happens automatically) input data
17621
  *     to output
17622
  *   - update tp to point at next unconverted input, and xpp to point
17623
  *     at next location for converted output
17624
  */
17625
  long i, j, ni;
17626
  double tmp[LOOPCNT];        /* in case input is misaligned */
17627
  double *xp;
17628
  int nrange = 0;         /* number of range errors */
17629
  int realign = 0;        /* "do we need to fix input data alignment?" */
17630
  long cxp = (long) *((char**)xpp);
17631
17632
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17633
  /* sjl: manually stripmine so we can limit amount of
17634
   * vector work space reserved to LOOPCNT elements. Also
17635
   * makes vectorisation easy */
17636
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17637
    ni=Min(nelems-j,LOOPCNT);
17638
    if (realign) {
17639
      xp = tmp;
17640
    } else {
17641
      xp = (double *) *xpp;
17642
    }
17643
   /* copy the next block */
17644
#pragma cdir loopcnt=LOOPCNT
17645
#pragma cdir shortloop
17646
    for (i=0; i<ni; i++) {
17647
      /* the normal case: */
17648
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17649
     /* test for range errors (not always needed but do it anyway) */
17650
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17651
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17652
      nrange += tp[i] > X_DOUBLE_MAX ;
17653
    }
17654
   /* copy workspace back if necessary */
17655
    if (realign) {
17656
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17657
      xp = (double *) *xpp;
17658
    }
17659
   /* update xpp and tp */
17660
    xp += ni;
17661
    tp += ni;
17662
    *xpp = (void*)xp;
17663
  }
17664
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17665
17666
#else   /* not SX */
17667
17668
0
  char *xp = (char *) *xpp;
17669
0
  int status = NC_NOERR;
17670
17671
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17672
0
  {
17673
0
    int lstatus = ncx_put_double_uint(xp, tp, fillp);
17674
0
    if (status == NC_NOERR) /* report the first encountered error */
17675
0
      status = lstatus;
17676
0
  }
17677
17678
0
  *xpp = (void *)xp;
17679
0
  return status;
17680
0
#endif
17681
0
}
17682
17683
int
17684
ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
17685
0
{
17686
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17687
17688
 /* basic algorithm is:
17689
  *   - ensure sane alignment of output data
17690
  *   - copy (conversion happens automatically) input data
17691
  *     to output
17692
  *   - update tp to point at next unconverted input, and xpp to point
17693
  *     at next location for converted output
17694
  */
17695
  long i, j, ni;
17696
  double tmp[LOOPCNT];        /* in case input is misaligned */
17697
  double *xp;
17698
  int nrange = 0;         /* number of range errors */
17699
  int realign = 0;        /* "do we need to fix input data alignment?" */
17700
  long cxp = (long) *((char**)xpp);
17701
17702
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17703
  /* sjl: manually stripmine so we can limit amount of
17704
   * vector work space reserved to LOOPCNT elements. Also
17705
   * makes vectorisation easy */
17706
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17707
    ni=Min(nelems-j,LOOPCNT);
17708
    if (realign) {
17709
      xp = tmp;
17710
    } else {
17711
      xp = (double *) *xpp;
17712
    }
17713
   /* copy the next block */
17714
#pragma cdir loopcnt=LOOPCNT
17715
#pragma cdir shortloop
17716
    for (i=0; i<ni; i++) {
17717
      /* the normal case: */
17718
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17719
     /* test for range errors (not always needed but do it anyway) */
17720
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17721
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17722
      nrange += tp[i] > X_DOUBLE_MAX ;
17723
    }
17724
   /* copy workspace back if necessary */
17725
    if (realign) {
17726
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17727
      xp = (double *) *xpp;
17728
    }
17729
   /* update xpp and tp */
17730
    xp += ni;
17731
    tp += ni;
17732
    *xpp = (void*)xp;
17733
  }
17734
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17735
17736
#else   /* not SX */
17737
17738
0
  char *xp = (char *) *xpp;
17739
0
  int status = NC_NOERR;
17740
17741
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17742
0
  {
17743
0
    int lstatus = ncx_put_double_ulonglong(xp, tp, fillp);
17744
0
    if (status == NC_NOERR) /* report the first encountered error */
17745
0
      status = lstatus;
17746
0
  }
17747
17748
0
  *xpp = (void *)xp;
17749
0
  return status;
17750
0
#endif
17751
0
}
17752
17753
17754
17755
/* longlong ------------------------------------------------------------------*/
17756
17757
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
17758
/* optimized version */
17759
int
17760
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
17761
0
{
17762
#ifdef WORDS_BIGENDIAN
17763
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
17764
# else
17765
0
  swapn8b(tp, *xpp, nelems);
17766
0
# endif
17767
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
17768
0
  return NC_NOERR;
17769
0
}
17770
#else
17771
int
17772
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, longlong *tp)
17773
{
17774
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17775
17776
 /* basic algorithm is:
17777
  *   - ensure sane alignment of input data
17778
  *   - copy (conversion happens automatically) input data
17779
  *     to output
17780
  *   - update xpp to point at next unconverted input, and tp to point
17781
  *     at next location for converted output
17782
  */
17783
  long i, j, ni;
17784
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17785
  int64 *xp;
17786
  int nrange = 0;         /* number of range errors */
17787
  int realign = 0;        /* "do we need to fix input data alignment?" */
17788
  long cxp = (long) *((char**)xpp);
17789
17790
  realign = (cxp & 7) % SIZEOF_INT64;
17791
  /* sjl: manually stripmine so we can limit amount of
17792
   * vector work space reserved to LOOPCNT elements. Also
17793
   * makes vectorisation easy */
17794
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17795
    ni=Min(nelems-j,LOOPCNT);
17796
    if (realign) {
17797
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17798
      xp = tmp;
17799
    } else {
17800
      xp = (int64 *) *xpp;
17801
    }
17802
   /* copy the next block */
17803
#pragma cdir loopcnt=LOOPCNT
17804
#pragma cdir shortloop
17805
    for (i=0; i<ni; i++) {
17806
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
17807
     /* test for range errors (not always needed but do it anyway) */
17808
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17809
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17810
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
17811
    }
17812
   /* update xpp and tp */
17813
    if (realign) xp = (int64 *) *xpp;
17814
    xp += ni;
17815
    tp += ni;
17816
    *xpp = (void*)xp;
17817
  }
17818
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17819
17820
#else   /* not SX */
17821
  const char *xp = (const char *) *xpp;
17822
  int status = NC_NOERR;
17823
17824
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
17825
  {
17826
    const int lstatus = ncx_get_longlong_longlong(xp, tp);
17827
    if (status == NC_NOERR) /* report the first encountered error */
17828
      status = lstatus;
17829
  }
17830
17831
  *xpp = (const void *)xp;
17832
  return status;
17833
#endif
17834
}
17835
17836
#endif
17837
int
17838
ncx_getn_longlong_schar(const void **xpp, size_t nelems, schar *tp)
17839
0
{
17840
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17841
17842
 /* basic algorithm is:
17843
  *   - ensure sane alignment of input data
17844
  *   - copy (conversion happens automatically) input data
17845
  *     to output
17846
  *   - update xpp to point at next unconverted input, and tp to point
17847
  *     at next location for converted output
17848
  */
17849
  long i, j, ni;
17850
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17851
  int64 *xp;
17852
  int nrange = 0;         /* number of range errors */
17853
  int realign = 0;        /* "do we need to fix input data alignment?" */
17854
  long cxp = (long) *((char**)xpp);
17855
17856
  realign = (cxp & 7) % SIZEOF_INT64;
17857
  /* sjl: manually stripmine so we can limit amount of
17858
   * vector work space reserved to LOOPCNT elements. Also
17859
   * makes vectorisation easy */
17860
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17861
    ni=Min(nelems-j,LOOPCNT);
17862
    if (realign) {
17863
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17864
      xp = tmp;
17865
    } else {
17866
      xp = (int64 *) *xpp;
17867
    }
17868
   /* copy the next block */
17869
#pragma cdir loopcnt=LOOPCNT
17870
#pragma cdir shortloop
17871
    for (i=0; i<ni; i++) {
17872
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
17873
     /* test for range errors (not always needed but do it anyway) */
17874
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17875
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17876
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
17877
    }
17878
   /* update xpp and tp */
17879
    if (realign) xp = (int64 *) *xpp;
17880
    xp += ni;
17881
    tp += ni;
17882
    *xpp = (void*)xp;
17883
  }
17884
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17885
17886
#else   /* not SX */
17887
0
  const char *xp = (const char *) *xpp;
17888
0
  int status = NC_NOERR;
17889
17890
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
17891
0
  {
17892
0
    const int lstatus = ncx_get_longlong_schar(xp, tp);
17893
0
    if (status == NC_NOERR) /* report the first encountered error */
17894
0
      status = lstatus;
17895
0
  }
17896
17897
0
  *xpp = (const void *)xp;
17898
0
  return status;
17899
0
#endif
17900
0
}
17901
17902
int
17903
ncx_getn_longlong_short(const void **xpp, size_t nelems, short *tp)
17904
0
{
17905
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17906
17907
 /* basic algorithm is:
17908
  *   - ensure sane alignment of input data
17909
  *   - copy (conversion happens automatically) input data
17910
  *     to output
17911
  *   - update xpp to point at next unconverted input, and tp to point
17912
  *     at next location for converted output
17913
  */
17914
  long i, j, ni;
17915
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17916
  int64 *xp;
17917
  int nrange = 0;         /* number of range errors */
17918
  int realign = 0;        /* "do we need to fix input data alignment?" */
17919
  long cxp = (long) *((char**)xpp);
17920
17921
  realign = (cxp & 7) % SIZEOF_INT64;
17922
  /* sjl: manually stripmine so we can limit amount of
17923
   * vector work space reserved to LOOPCNT elements. Also
17924
   * makes vectorisation easy */
17925
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17926
    ni=Min(nelems-j,LOOPCNT);
17927
    if (realign) {
17928
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17929
      xp = tmp;
17930
    } else {
17931
      xp = (int64 *) *xpp;
17932
    }
17933
   /* copy the next block */
17934
#pragma cdir loopcnt=LOOPCNT
17935
#pragma cdir shortloop
17936
    for (i=0; i<ni; i++) {
17937
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
17938
     /* test for range errors (not always needed but do it anyway) */
17939
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17940
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17941
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
17942
    }
17943
   /* update xpp and tp */
17944
    if (realign) xp = (int64 *) *xpp;
17945
    xp += ni;
17946
    tp += ni;
17947
    *xpp = (void*)xp;
17948
  }
17949
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17950
17951
#else   /* not SX */
17952
0
  const char *xp = (const char *) *xpp;
17953
0
  int status = NC_NOERR;
17954
17955
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
17956
0
  {
17957
0
    const int lstatus = ncx_get_longlong_short(xp, tp);
17958
0
    if (status == NC_NOERR) /* report the first encountered error */
17959
0
      status = lstatus;
17960
0
  }
17961
17962
0
  *xpp = (const void *)xp;
17963
0
  return status;
17964
0
#endif
17965
0
}
17966
17967
int
17968
ncx_getn_longlong_int(const void **xpp, size_t nelems, int *tp)
17969
1.07k
{
17970
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
17971
17972
 /* basic algorithm is:
17973
  *   - ensure sane alignment of input data
17974
  *   - copy (conversion happens automatically) input data
17975
  *     to output
17976
  *   - update xpp to point at next unconverted input, and tp to point
17977
  *     at next location for converted output
17978
  */
17979
  long i, j, ni;
17980
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
17981
  int64 *xp;
17982
  int nrange = 0;         /* number of range errors */
17983
  int realign = 0;        /* "do we need to fix input data alignment?" */
17984
  long cxp = (long) *((char**)xpp);
17985
17986
  realign = (cxp & 7) % SIZEOF_INT64;
17987
  /* sjl: manually stripmine so we can limit amount of
17988
   * vector work space reserved to LOOPCNT elements. Also
17989
   * makes vectorisation easy */
17990
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17991
    ni=Min(nelems-j,LOOPCNT);
17992
    if (realign) {
17993
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
17994
      xp = tmp;
17995
    } else {
17996
      xp = (int64 *) *xpp;
17997
    }
17998
   /* copy the next block */
17999
#pragma cdir loopcnt=LOOPCNT
18000
#pragma cdir shortloop
18001
    for (i=0; i<ni; i++) {
18002
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
18003
     /* test for range errors (not always needed but do it anyway) */
18004
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18005
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18006
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
18007
    }
18008
   /* update xpp and tp */
18009
    if (realign) xp = (int64 *) *xpp;
18010
    xp += ni;
18011
    tp += ni;
18012
    *xpp = (void*)xp;
18013
  }
18014
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18015
18016
#else   /* not SX */
18017
1.07k
  const char *xp = (const char *) *xpp;
18018
1.07k
  int status = NC_NOERR;
18019
18020
5.32k
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18021
4.25k
  {
18022
4.25k
    const int lstatus = ncx_get_longlong_int(xp, tp);
18023
4.25k
    if (status == NC_NOERR) /* report the first encountered error */
18024
18
      status = lstatus;
18025
4.25k
  }
18026
18027
1.07k
  *xpp = (const void *)xp;
18028
1.07k
  return status;
18029
1.07k
#endif
18030
1.07k
}
18031
18032
int
18033
ncx_getn_longlong_long(const void **xpp, size_t nelems, long *tp)
18034
0
{
18035
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18036
18037
 /* basic algorithm is:
18038
  *   - ensure sane alignment of input data
18039
  *   - copy (conversion happens automatically) input data
18040
  *     to output
18041
  *   - update xpp to point at next unconverted input, and tp to point
18042
  *     at next location for converted output
18043
  */
18044
  long i, j, ni;
18045
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18046
  int64 *xp;
18047
  int nrange = 0;         /* number of range errors */
18048
  int realign = 0;        /* "do we need to fix input data alignment?" */
18049
  long cxp = (long) *((char**)xpp);
18050
18051
  realign = (cxp & 7) % SIZEOF_INT64;
18052
  /* sjl: manually stripmine so we can limit amount of
18053
   * vector work space reserved to LOOPCNT elements. Also
18054
   * makes vectorisation easy */
18055
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18056
    ni=Min(nelems-j,LOOPCNT);
18057
    if (realign) {
18058
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18059
      xp = tmp;
18060
    } else {
18061
      xp = (int64 *) *xpp;
18062
    }
18063
   /* copy the next block */
18064
#pragma cdir loopcnt=LOOPCNT
18065
#pragma cdir shortloop
18066
    for (i=0; i<ni; i++) {
18067
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
18068
     /* test for range errors (not always needed but do it anyway) */
18069
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18070
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18071
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
18072
    }
18073
   /* update xpp and tp */
18074
    if (realign) xp = (int64 *) *xpp;
18075
    xp += ni;
18076
    tp += ni;
18077
    *xpp = (void*)xp;
18078
  }
18079
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18080
18081
#else   /* not SX */
18082
0
  const char *xp = (const char *) *xpp;
18083
0
  int status = NC_NOERR;
18084
18085
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18086
0
  {
18087
0
    const int lstatus = ncx_get_longlong_long(xp, tp);
18088
0
    if (status == NC_NOERR) /* report the first encountered error */
18089
0
      status = lstatus;
18090
0
  }
18091
18092
0
  *xpp = (const void *)xp;
18093
0
  return status;
18094
0
#endif
18095
0
}
18096
18097
int
18098
ncx_getn_longlong_float(const void **xpp, size_t nelems, float *tp)
18099
0
{
18100
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18101
18102
 /* basic algorithm is:
18103
  *   - ensure sane alignment of input data
18104
  *   - copy (conversion happens automatically) input data
18105
  *     to output
18106
  *   - update xpp to point at next unconverted input, and tp to point
18107
  *     at next location for converted output
18108
  */
18109
  long i, j, ni;
18110
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18111
  int64 *xp;
18112
  int nrange = 0;         /* number of range errors */
18113
  int realign = 0;        /* "do we need to fix input data alignment?" */
18114
  long cxp = (long) *((char**)xpp);
18115
18116
  realign = (cxp & 7) % SIZEOF_INT64;
18117
  /* sjl: manually stripmine so we can limit amount of
18118
   * vector work space reserved to LOOPCNT elements. Also
18119
   * makes vectorisation easy */
18120
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18121
    ni=Min(nelems-j,LOOPCNT);
18122
    if (realign) {
18123
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18124
      xp = tmp;
18125
    } else {
18126
      xp = (int64 *) *xpp;
18127
    }
18128
   /* copy the next block */
18129
#pragma cdir loopcnt=LOOPCNT
18130
#pragma cdir shortloop
18131
    for (i=0; i<ni; i++) {
18132
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
18133
     /* test for range errors (not always needed but do it anyway) */
18134
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18135
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18136
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
18137
    }
18138
   /* update xpp and tp */
18139
    if (realign) xp = (int64 *) *xpp;
18140
    xp += ni;
18141
    tp += ni;
18142
    *xpp = (void*)xp;
18143
  }
18144
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18145
18146
#else   /* not SX */
18147
0
  const char *xp = (const char *) *xpp;
18148
0
  int status = NC_NOERR;
18149
18150
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18151
0
  {
18152
0
    const int lstatus = ncx_get_longlong_float(xp, tp);
18153
0
    if (status == NC_NOERR) /* report the first encountered error */
18154
0
      status = lstatus;
18155
0
  }
18156
18157
0
  *xpp = (const void *)xp;
18158
0
  return status;
18159
0
#endif
18160
0
}
18161
18162
int
18163
ncx_getn_longlong_double(const void **xpp, size_t nelems, double *tp)
18164
0
{
18165
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18166
18167
 /* basic algorithm is:
18168
  *   - ensure sane alignment of input data
18169
  *   - copy (conversion happens automatically) input data
18170
  *     to output
18171
  *   - update xpp to point at next unconverted input, and tp to point
18172
  *     at next location for converted output
18173
  */
18174
  long i, j, ni;
18175
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18176
  int64 *xp;
18177
  int nrange = 0;         /* number of range errors */
18178
  int realign = 0;        /* "do we need to fix input data alignment?" */
18179
  long cxp = (long) *((char**)xpp);
18180
18181
  realign = (cxp & 7) % SIZEOF_INT64;
18182
  /* sjl: manually stripmine so we can limit amount of
18183
   * vector work space reserved to LOOPCNT elements. Also
18184
   * makes vectorisation easy */
18185
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18186
    ni=Min(nelems-j,LOOPCNT);
18187
    if (realign) {
18188
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18189
      xp = tmp;
18190
    } else {
18191
      xp = (int64 *) *xpp;
18192
    }
18193
   /* copy the next block */
18194
#pragma cdir loopcnt=LOOPCNT
18195
#pragma cdir shortloop
18196
    for (i=0; i<ni; i++) {
18197
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
18198
     /* test for range errors (not always needed but do it anyway) */
18199
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18200
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18201
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
18202
    }
18203
   /* update xpp and tp */
18204
    if (realign) xp = (int64 *) *xpp;
18205
    xp += ni;
18206
    tp += ni;
18207
    *xpp = (void*)xp;
18208
  }
18209
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18210
18211
#else   /* not SX */
18212
0
  const char *xp = (const char *) *xpp;
18213
0
  int status = NC_NOERR;
18214
18215
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18216
0
  {
18217
0
    const int lstatus = ncx_get_longlong_double(xp, tp);
18218
0
    if (status == NC_NOERR) /* report the first encountered error */
18219
0
      status = lstatus;
18220
0
  }
18221
18222
0
  *xpp = (const void *)xp;
18223
0
  return status;
18224
0
#endif
18225
0
}
18226
18227
int
18228
ncx_getn_longlong_uchar(const void **xpp, size_t nelems, uchar *tp)
18229
0
{
18230
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18231
18232
 /* basic algorithm is:
18233
  *   - ensure sane alignment of input data
18234
  *   - copy (conversion happens automatically) input data
18235
  *     to output
18236
  *   - update xpp to point at next unconverted input, and tp to point
18237
  *     at next location for converted output
18238
  */
18239
  long i, j, ni;
18240
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18241
  int64 *xp;
18242
  int nrange = 0;         /* number of range errors */
18243
  int realign = 0;        /* "do we need to fix input data alignment?" */
18244
  long cxp = (long) *((char**)xpp);
18245
18246
  realign = (cxp & 7) % SIZEOF_INT64;
18247
  /* sjl: manually stripmine so we can limit amount of
18248
   * vector work space reserved to LOOPCNT elements. Also
18249
   * makes vectorisation easy */
18250
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18251
    ni=Min(nelems-j,LOOPCNT);
18252
    if (realign) {
18253
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18254
      xp = tmp;
18255
    } else {
18256
      xp = (int64 *) *xpp;
18257
    }
18258
   /* copy the next block */
18259
#pragma cdir loopcnt=LOOPCNT
18260
#pragma cdir shortloop
18261
    for (i=0; i<ni; i++) {
18262
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
18263
     /* test for range errors (not always needed but do it anyway) */
18264
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18265
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18266
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
18267
    }
18268
   /* update xpp and tp */
18269
    if (realign) xp = (int64 *) *xpp;
18270
    xp += ni;
18271
    tp += ni;
18272
    *xpp = (void*)xp;
18273
  }
18274
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18275
18276
#else   /* not SX */
18277
0
  const char *xp = (const char *) *xpp;
18278
0
  int status = NC_NOERR;
18279
18280
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18281
0
  {
18282
0
    const int lstatus = ncx_get_longlong_uchar(xp, tp);
18283
0
    if (status == NC_NOERR) /* report the first encountered error */
18284
0
      status = lstatus;
18285
0
  }
18286
18287
0
  *xpp = (const void *)xp;
18288
0
  return status;
18289
0
#endif
18290
0
}
18291
18292
int
18293
ncx_getn_longlong_ushort(const void **xpp, size_t nelems, ushort *tp)
18294
0
{
18295
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18296
18297
 /* basic algorithm is:
18298
  *   - ensure sane alignment of input data
18299
  *   - copy (conversion happens automatically) input data
18300
  *     to output
18301
  *   - update xpp to point at next unconverted input, and tp to point
18302
  *     at next location for converted output
18303
  */
18304
  long i, j, ni;
18305
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18306
  int64 *xp;
18307
  int nrange = 0;         /* number of range errors */
18308
  int realign = 0;        /* "do we need to fix input data alignment?" */
18309
  long cxp = (long) *((char**)xpp);
18310
18311
  realign = (cxp & 7) % SIZEOF_INT64;
18312
  /* sjl: manually stripmine so we can limit amount of
18313
   * vector work space reserved to LOOPCNT elements. Also
18314
   * makes vectorisation easy */
18315
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18316
    ni=Min(nelems-j,LOOPCNT);
18317
    if (realign) {
18318
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18319
      xp = tmp;
18320
    } else {
18321
      xp = (int64 *) *xpp;
18322
    }
18323
   /* copy the next block */
18324
#pragma cdir loopcnt=LOOPCNT
18325
#pragma cdir shortloop
18326
    for (i=0; i<ni; i++) {
18327
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
18328
     /* test for range errors (not always needed but do it anyway) */
18329
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18330
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18331
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
18332
    }
18333
   /* update xpp and tp */
18334
    if (realign) xp = (int64 *) *xpp;
18335
    xp += ni;
18336
    tp += ni;
18337
    *xpp = (void*)xp;
18338
  }
18339
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18340
18341
#else   /* not SX */
18342
0
  const char *xp = (const char *) *xpp;
18343
0
  int status = NC_NOERR;
18344
18345
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18346
0
  {
18347
0
    const int lstatus = ncx_get_longlong_ushort(xp, tp);
18348
0
    if (status == NC_NOERR) /* report the first encountered error */
18349
0
      status = lstatus;
18350
0
  }
18351
18352
0
  *xpp = (const void *)xp;
18353
0
  return status;
18354
0
#endif
18355
0
}
18356
18357
int
18358
ncx_getn_longlong_uint(const void **xpp, size_t nelems, uint *tp)
18359
0
{
18360
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18361
18362
 /* basic algorithm is:
18363
  *   - ensure sane alignment of input data
18364
  *   - copy (conversion happens automatically) input data
18365
  *     to output
18366
  *   - update xpp to point at next unconverted input, and tp to point
18367
  *     at next location for converted output
18368
  */
18369
  long i, j, ni;
18370
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18371
  int64 *xp;
18372
  int nrange = 0;         /* number of range errors */
18373
  int realign = 0;        /* "do we need to fix input data alignment?" */
18374
  long cxp = (long) *((char**)xpp);
18375
18376
  realign = (cxp & 7) % SIZEOF_INT64;
18377
  /* sjl: manually stripmine so we can limit amount of
18378
   * vector work space reserved to LOOPCNT elements. Also
18379
   * makes vectorisation easy */
18380
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18381
    ni=Min(nelems-j,LOOPCNT);
18382
    if (realign) {
18383
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18384
      xp = tmp;
18385
    } else {
18386
      xp = (int64 *) *xpp;
18387
    }
18388
   /* copy the next block */
18389
#pragma cdir loopcnt=LOOPCNT
18390
#pragma cdir shortloop
18391
    for (i=0; i<ni; i++) {
18392
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
18393
     /* test for range errors (not always needed but do it anyway) */
18394
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18395
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18396
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
18397
    }
18398
   /* update xpp and tp */
18399
    if (realign) xp = (int64 *) *xpp;
18400
    xp += ni;
18401
    tp += ni;
18402
    *xpp = (void*)xp;
18403
  }
18404
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18405
18406
#else   /* not SX */
18407
0
  const char *xp = (const char *) *xpp;
18408
0
  int status = NC_NOERR;
18409
18410
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18411
0
  {
18412
0
    const int lstatus = ncx_get_longlong_uint(xp, tp);
18413
0
    if (status == NC_NOERR) /* report the first encountered error */
18414
0
      status = lstatus;
18415
0
  }
18416
18417
0
  *xpp = (const void *)xp;
18418
0
  return status;
18419
0
#endif
18420
0
}
18421
18422
int
18423
ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
18424
0
{
18425
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18426
18427
 /* basic algorithm is:
18428
  *   - ensure sane alignment of input data
18429
  *   - copy (conversion happens automatically) input data
18430
  *     to output
18431
  *   - update xpp to point at next unconverted input, and tp to point
18432
  *     at next location for converted output
18433
  */
18434
  long i, j, ni;
18435
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18436
  int64 *xp;
18437
  int nrange = 0;         /* number of range errors */
18438
  int realign = 0;        /* "do we need to fix input data alignment?" */
18439
  long cxp = (long) *((char**)xpp);
18440
18441
  realign = (cxp & 7) % SIZEOF_INT64;
18442
  /* sjl: manually stripmine so we can limit amount of
18443
   * vector work space reserved to LOOPCNT elements. Also
18444
   * makes vectorisation easy */
18445
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18446
    ni=Min(nelems-j,LOOPCNT);
18447
    if (realign) {
18448
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18449
      xp = tmp;
18450
    } else {
18451
      xp = (int64 *) *xpp;
18452
    }
18453
   /* copy the next block */
18454
#pragma cdir loopcnt=LOOPCNT
18455
#pragma cdir shortloop
18456
    for (i=0; i<ni; i++) {
18457
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
18458
     /* test for range errors (not always needed but do it anyway) */
18459
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18460
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18461
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
18462
    }
18463
   /* update xpp and tp */
18464
    if (realign) xp = (int64 *) *xpp;
18465
    xp += ni;
18466
    tp += ni;
18467
    *xpp = (void*)xp;
18468
  }
18469
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18470
18471
#else   /* not SX */
18472
0
  const char *xp = (const char *) *xpp;
18473
0
  int status = NC_NOERR;
18474
18475
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18476
0
  {
18477
0
    const int lstatus = ncx_get_longlong_ulonglong(xp, tp);
18478
0
    if (status == NC_NOERR) /* report the first encountered error */
18479
0
      status = lstatus;
18480
0
  }
18481
18482
0
  *xpp = (const void *)xp;
18483
0
  return status;
18484
0
#endif
18485
0
}
18486
18487
18488
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
18489
/* optimized version */
18490
int
18491
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp, void *fillp)
18492
0
{
18493
#ifdef WORDS_BIGENDIAN
18494
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
18495
# else
18496
0
  swapn8b(*xpp, tp, nelems);
18497
0
# endif
18498
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
18499
0
  return NC_NOERR;
18500
0
}
18501
#else
18502
int
18503
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
18504
{
18505
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18506
18507
 /* basic algorithm is:
18508
  *   - ensure sane alignment of output data
18509
  *   - copy (conversion happens automatically) input data
18510
  *     to output
18511
  *   - update tp to point at next unconverted input, and xpp to point
18512
  *     at next location for converted output
18513
  */
18514
  long i, j, ni;
18515
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18516
  int64 *xp;
18517
  int nrange = 0;         /* number of range errors */
18518
  int realign = 0;        /* "do we need to fix input data alignment?" */
18519
  long cxp = (long) *((char**)xpp);
18520
18521
  realign = (cxp & 7) % SIZEOF_INT64;
18522
  /* sjl: manually stripmine so we can limit amount of
18523
   * vector work space reserved to LOOPCNT elements. Also
18524
   * makes vectorisation easy */
18525
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18526
    ni=Min(nelems-j,LOOPCNT);
18527
    if (realign) {
18528
      xp = tmp;
18529
    } else {
18530
      xp = (int64 *) *xpp;
18531
    }
18532
   /* copy the next block */
18533
#pragma cdir loopcnt=LOOPCNT
18534
#pragma cdir shortloop
18535
    for (i=0; i<ni; i++) {
18536
      /* the normal case: */
18537
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18538
     /* test for range errors (not always needed but do it anyway) */
18539
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18540
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18541
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18542
    }
18543
   /* copy workspace back if necessary */
18544
    if (realign) {
18545
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18546
      xp = (int64 *) *xpp;
18547
    }
18548
   /* update xpp and tp */
18549
    xp += ni;
18550
    tp += ni;
18551
    *xpp = (void*)xp;
18552
  }
18553
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18554
18555
#else   /* not SX */
18556
18557
  char *xp = (char *) *xpp;
18558
  int status = NC_NOERR;
18559
18560
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18561
  {
18562
    int lstatus = ncx_put_longlong_longlong(xp, tp, fillp);
18563
    if (status == NC_NOERR) /* report the first encountered error */
18564
      status = lstatus;
18565
  }
18566
18567
  *xpp = (void *)xp;
18568
  return status;
18569
#endif
18570
}
18571
18572
#endif
18573
int
18574
ncx_putn_longlong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
18575
0
{
18576
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18577
18578
 /* basic algorithm is:
18579
  *   - ensure sane alignment of output data
18580
  *   - copy (conversion happens automatically) input data
18581
  *     to output
18582
  *   - update tp to point at next unconverted input, and xpp to point
18583
  *     at next location for converted output
18584
  */
18585
  long i, j, ni;
18586
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18587
  int64 *xp;
18588
  int nrange = 0;         /* number of range errors */
18589
  int realign = 0;        /* "do we need to fix input data alignment?" */
18590
  long cxp = (long) *((char**)xpp);
18591
18592
  realign = (cxp & 7) % SIZEOF_INT64;
18593
  /* sjl: manually stripmine so we can limit amount of
18594
   * vector work space reserved to LOOPCNT elements. Also
18595
   * makes vectorisation easy */
18596
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18597
    ni=Min(nelems-j,LOOPCNT);
18598
    if (realign) {
18599
      xp = tmp;
18600
    } else {
18601
      xp = (int64 *) *xpp;
18602
    }
18603
   /* copy the next block */
18604
#pragma cdir loopcnt=LOOPCNT
18605
#pragma cdir shortloop
18606
    for (i=0; i<ni; i++) {
18607
      /* the normal case: */
18608
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18609
     /* test for range errors (not always needed but do it anyway) */
18610
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18611
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18612
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18613
    }
18614
   /* copy workspace back if necessary */
18615
    if (realign) {
18616
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18617
      xp = (int64 *) *xpp;
18618
    }
18619
   /* update xpp and tp */
18620
    xp += ni;
18621
    tp += ni;
18622
    *xpp = (void*)xp;
18623
  }
18624
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18625
18626
#else   /* not SX */
18627
18628
0
  char *xp = (char *) *xpp;
18629
0
  int status = NC_NOERR;
18630
18631
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18632
0
  {
18633
0
    int lstatus = ncx_put_longlong_schar(xp, tp, fillp);
18634
0
    if (status == NC_NOERR) /* report the first encountered error */
18635
0
      status = lstatus;
18636
0
  }
18637
18638
0
  *xpp = (void *)xp;
18639
0
  return status;
18640
0
#endif
18641
0
}
18642
18643
int
18644
ncx_putn_longlong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
18645
0
{
18646
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18647
18648
 /* basic algorithm is:
18649
  *   - ensure sane alignment of output data
18650
  *   - copy (conversion happens automatically) input data
18651
  *     to output
18652
  *   - update tp to point at next unconverted input, and xpp to point
18653
  *     at next location for converted output
18654
  */
18655
  long i, j, ni;
18656
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18657
  int64 *xp;
18658
  int nrange = 0;         /* number of range errors */
18659
  int realign = 0;        /* "do we need to fix input data alignment?" */
18660
  long cxp = (long) *((char**)xpp);
18661
18662
  realign = (cxp & 7) % SIZEOF_INT64;
18663
  /* sjl: manually stripmine so we can limit amount of
18664
   * vector work space reserved to LOOPCNT elements. Also
18665
   * makes vectorisation easy */
18666
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18667
    ni=Min(nelems-j,LOOPCNT);
18668
    if (realign) {
18669
      xp = tmp;
18670
    } else {
18671
      xp = (int64 *) *xpp;
18672
    }
18673
   /* copy the next block */
18674
#pragma cdir loopcnt=LOOPCNT
18675
#pragma cdir shortloop
18676
    for (i=0; i<ni; i++) {
18677
      /* the normal case: */
18678
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18679
     /* test for range errors (not always needed but do it anyway) */
18680
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18681
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18682
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18683
    }
18684
   /* copy workspace back if necessary */
18685
    if (realign) {
18686
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18687
      xp = (int64 *) *xpp;
18688
    }
18689
   /* update xpp and tp */
18690
    xp += ni;
18691
    tp += ni;
18692
    *xpp = (void*)xp;
18693
  }
18694
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18695
18696
#else   /* not SX */
18697
18698
0
  char *xp = (char *) *xpp;
18699
0
  int status = NC_NOERR;
18700
18701
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18702
0
  {
18703
0
    int lstatus = ncx_put_longlong_short(xp, tp, fillp);
18704
0
    if (status == NC_NOERR) /* report the first encountered error */
18705
0
      status = lstatus;
18706
0
  }
18707
18708
0
  *xpp = (void *)xp;
18709
0
  return status;
18710
0
#endif
18711
0
}
18712
18713
int
18714
ncx_putn_longlong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
18715
0
{
18716
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18717
18718
 /* basic algorithm is:
18719
  *   - ensure sane alignment of output data
18720
  *   - copy (conversion happens automatically) input data
18721
  *     to output
18722
  *   - update tp to point at next unconverted input, and xpp to point
18723
  *     at next location for converted output
18724
  */
18725
  long i, j, ni;
18726
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18727
  int64 *xp;
18728
  int nrange = 0;         /* number of range errors */
18729
  int realign = 0;        /* "do we need to fix input data alignment?" */
18730
  long cxp = (long) *((char**)xpp);
18731
18732
  realign = (cxp & 7) % SIZEOF_INT64;
18733
  /* sjl: manually stripmine so we can limit amount of
18734
   * vector work space reserved to LOOPCNT elements. Also
18735
   * makes vectorisation easy */
18736
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18737
    ni=Min(nelems-j,LOOPCNT);
18738
    if (realign) {
18739
      xp = tmp;
18740
    } else {
18741
      xp = (int64 *) *xpp;
18742
    }
18743
   /* copy the next block */
18744
#pragma cdir loopcnt=LOOPCNT
18745
#pragma cdir shortloop
18746
    for (i=0; i<ni; i++) {
18747
      /* the normal case: */
18748
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18749
     /* test for range errors (not always needed but do it anyway) */
18750
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18751
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18752
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18753
    }
18754
   /* copy workspace back if necessary */
18755
    if (realign) {
18756
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18757
      xp = (int64 *) *xpp;
18758
    }
18759
   /* update xpp and tp */
18760
    xp += ni;
18761
    tp += ni;
18762
    *xpp = (void*)xp;
18763
  }
18764
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18765
18766
#else   /* not SX */
18767
18768
0
  char *xp = (char *) *xpp;
18769
0
  int status = NC_NOERR;
18770
18771
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18772
0
  {
18773
0
    int lstatus = ncx_put_longlong_int(xp, tp, fillp);
18774
0
    if (status == NC_NOERR) /* report the first encountered error */
18775
0
      status = lstatus;
18776
0
  }
18777
18778
0
  *xpp = (void *)xp;
18779
0
  return status;
18780
0
#endif
18781
0
}
18782
18783
int
18784
ncx_putn_longlong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
18785
0
{
18786
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18787
18788
 /* basic algorithm is:
18789
  *   - ensure sane alignment of output data
18790
  *   - copy (conversion happens automatically) input data
18791
  *     to output
18792
  *   - update tp to point at next unconverted input, and xpp to point
18793
  *     at next location for converted output
18794
  */
18795
  long i, j, ni;
18796
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18797
  int64 *xp;
18798
  int nrange = 0;         /* number of range errors */
18799
  int realign = 0;        /* "do we need to fix input data alignment?" */
18800
  long cxp = (long) *((char**)xpp);
18801
18802
  realign = (cxp & 7) % SIZEOF_INT64;
18803
  /* sjl: manually stripmine so we can limit amount of
18804
   * vector work space reserved to LOOPCNT elements. Also
18805
   * makes vectorisation easy */
18806
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18807
    ni=Min(nelems-j,LOOPCNT);
18808
    if (realign) {
18809
      xp = tmp;
18810
    } else {
18811
      xp = (int64 *) *xpp;
18812
    }
18813
   /* copy the next block */
18814
#pragma cdir loopcnt=LOOPCNT
18815
#pragma cdir shortloop
18816
    for (i=0; i<ni; i++) {
18817
      /* the normal case: */
18818
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18819
     /* test for range errors (not always needed but do it anyway) */
18820
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18821
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18822
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18823
    }
18824
   /* copy workspace back if necessary */
18825
    if (realign) {
18826
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18827
      xp = (int64 *) *xpp;
18828
    }
18829
   /* update xpp and tp */
18830
    xp += ni;
18831
    tp += ni;
18832
    *xpp = (void*)xp;
18833
  }
18834
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18835
18836
#else   /* not SX */
18837
18838
0
  char *xp = (char *) *xpp;
18839
0
  int status = NC_NOERR;
18840
18841
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18842
0
  {
18843
0
    int lstatus = ncx_put_longlong_long(xp, tp, fillp);
18844
0
    if (status == NC_NOERR) /* report the first encountered error */
18845
0
      status = lstatus;
18846
0
  }
18847
18848
0
  *xpp = (void *)xp;
18849
0
  return status;
18850
0
#endif
18851
0
}
18852
18853
int
18854
ncx_putn_longlong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
18855
0
{
18856
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18857
18858
 /* basic algorithm is:
18859
  *   - ensure sane alignment of output data
18860
  *   - copy (conversion happens automatically) input data
18861
  *     to output
18862
  *   - update tp to point at next unconverted input, and xpp to point
18863
  *     at next location for converted output
18864
  */
18865
  long i, j, ni;
18866
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18867
  int64 *xp;
18868
  int nrange = 0;         /* number of range errors */
18869
  int realign = 0;        /* "do we need to fix input data alignment?" */
18870
  long cxp = (long) *((char**)xpp);
18871
18872
  realign = (cxp & 7) % SIZEOF_INT64;
18873
  /* sjl: manually stripmine so we can limit amount of
18874
   * vector work space reserved to LOOPCNT elements. Also
18875
   * makes vectorisation easy */
18876
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18877
    ni=Min(nelems-j,LOOPCNT);
18878
    if (realign) {
18879
      xp = tmp;
18880
    } else {
18881
      xp = (int64 *) *xpp;
18882
    }
18883
   /* copy the next block */
18884
#pragma cdir loopcnt=LOOPCNT
18885
#pragma cdir shortloop
18886
    for (i=0; i<ni; i++) {
18887
      /* the normal case: */
18888
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18889
     /* test for range errors (not always needed but do it anyway) */
18890
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18891
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18892
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18893
    }
18894
   /* copy workspace back if necessary */
18895
    if (realign) {
18896
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18897
      xp = (int64 *) *xpp;
18898
    }
18899
   /* update xpp and tp */
18900
    xp += ni;
18901
    tp += ni;
18902
    *xpp = (void*)xp;
18903
  }
18904
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18905
18906
#else   /* not SX */
18907
18908
0
  char *xp = (char *) *xpp;
18909
0
  int status = NC_NOERR;
18910
18911
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18912
0
  {
18913
0
    int lstatus = ncx_put_longlong_float(xp, tp, fillp);
18914
0
    if (status == NC_NOERR) /* report the first encountered error */
18915
0
      status = lstatus;
18916
0
  }
18917
18918
0
  *xpp = (void *)xp;
18919
0
  return status;
18920
0
#endif
18921
0
}
18922
18923
int
18924
ncx_putn_longlong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
18925
0
{
18926
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18927
18928
 /* basic algorithm is:
18929
  *   - ensure sane alignment of output data
18930
  *   - copy (conversion happens automatically) input data
18931
  *     to output
18932
  *   - update tp to point at next unconverted input, and xpp to point
18933
  *     at next location for converted output
18934
  */
18935
  long i, j, ni;
18936
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18937
  int64 *xp;
18938
  int nrange = 0;         /* number of range errors */
18939
  int realign = 0;        /* "do we need to fix input data alignment?" */
18940
  long cxp = (long) *((char**)xpp);
18941
18942
  realign = (cxp & 7) % SIZEOF_INT64;
18943
  /* sjl: manually stripmine so we can limit amount of
18944
   * vector work space reserved to LOOPCNT elements. Also
18945
   * makes vectorisation easy */
18946
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18947
    ni=Min(nelems-j,LOOPCNT);
18948
    if (realign) {
18949
      xp = tmp;
18950
    } else {
18951
      xp = (int64 *) *xpp;
18952
    }
18953
   /* copy the next block */
18954
#pragma cdir loopcnt=LOOPCNT
18955
#pragma cdir shortloop
18956
    for (i=0; i<ni; i++) {
18957
      /* the normal case: */
18958
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18959
     /* test for range errors (not always needed but do it anyway) */
18960
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18961
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18962
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18963
    }
18964
   /* copy workspace back if necessary */
18965
    if (realign) {
18966
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18967
      xp = (int64 *) *xpp;
18968
    }
18969
   /* update xpp and tp */
18970
    xp += ni;
18971
    tp += ni;
18972
    *xpp = (void*)xp;
18973
  }
18974
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18975
18976
#else   /* not SX */
18977
18978
0
  char *xp = (char *) *xpp;
18979
0
  int status = NC_NOERR;
18980
18981
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18982
0
  {
18983
0
    int lstatus = ncx_put_longlong_double(xp, tp, fillp);
18984
0
    if (status == NC_NOERR) /* report the first encountered error */
18985
0
      status = lstatus;
18986
0
  }
18987
18988
0
  *xpp = (void *)xp;
18989
0
  return status;
18990
0
#endif
18991
0
}
18992
18993
int
18994
ncx_putn_longlong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
18995
0
{
18996
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18997
18998
 /* basic algorithm is:
18999
  *   - ensure sane alignment of output data
19000
  *   - copy (conversion happens automatically) input data
19001
  *     to output
19002
  *   - update tp to point at next unconverted input, and xpp to point
19003
  *     at next location for converted output
19004
  */
19005
  long i, j, ni;
19006
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19007
  int64 *xp;
19008
  int nrange = 0;         /* number of range errors */
19009
  int realign = 0;        /* "do we need to fix input data alignment?" */
19010
  long cxp = (long) *((char**)xpp);
19011
19012
  realign = (cxp & 7) % SIZEOF_INT64;
19013
  /* sjl: manually stripmine so we can limit amount of
19014
   * vector work space reserved to LOOPCNT elements. Also
19015
   * makes vectorisation easy */
19016
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19017
    ni=Min(nelems-j,LOOPCNT);
19018
    if (realign) {
19019
      xp = tmp;
19020
    } else {
19021
      xp = (int64 *) *xpp;
19022
    }
19023
   /* copy the next block */
19024
#pragma cdir loopcnt=LOOPCNT
19025
#pragma cdir shortloop
19026
    for (i=0; i<ni; i++) {
19027
      /* the normal case: */
19028
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19029
     /* test for range errors (not always needed but do it anyway) */
19030
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19031
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19032
      nrange += tp[i] > X_INT64_MAX ;
19033
    }
19034
   /* copy workspace back if necessary */
19035
    if (realign) {
19036
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19037
      xp = (int64 *) *xpp;
19038
    }
19039
   /* update xpp and tp */
19040
    xp += ni;
19041
    tp += ni;
19042
    *xpp = (void*)xp;
19043
  }
19044
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19045
19046
#else   /* not SX */
19047
19048
0
  char *xp = (char *) *xpp;
19049
0
  int status = NC_NOERR;
19050
19051
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19052
0
  {
19053
0
    int lstatus = ncx_put_longlong_uchar(xp, tp, fillp);
19054
0
    if (status == NC_NOERR) /* report the first encountered error */
19055
0
      status = lstatus;
19056
0
  }
19057
19058
0
  *xpp = (void *)xp;
19059
0
  return status;
19060
0
#endif
19061
0
}
19062
19063
int
19064
ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
19065
0
{
19066
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19067
19068
 /* basic algorithm is:
19069
  *   - ensure sane alignment of output data
19070
  *   - copy (conversion happens automatically) input data
19071
  *     to output
19072
  *   - update tp to point at next unconverted input, and xpp to point
19073
  *     at next location for converted output
19074
  */
19075
  long i, j, ni;
19076
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19077
  int64 *xp;
19078
  int nrange = 0;         /* number of range errors */
19079
  int realign = 0;        /* "do we need to fix input data alignment?" */
19080
  long cxp = (long) *((char**)xpp);
19081
19082
  realign = (cxp & 7) % SIZEOF_INT64;
19083
  /* sjl: manually stripmine so we can limit amount of
19084
   * vector work space reserved to LOOPCNT elements. Also
19085
   * makes vectorisation easy */
19086
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19087
    ni=Min(nelems-j,LOOPCNT);
19088
    if (realign) {
19089
      xp = tmp;
19090
    } else {
19091
      xp = (int64 *) *xpp;
19092
    }
19093
   /* copy the next block */
19094
#pragma cdir loopcnt=LOOPCNT
19095
#pragma cdir shortloop
19096
    for (i=0; i<ni; i++) {
19097
      /* the normal case: */
19098
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19099
     /* test for range errors (not always needed but do it anyway) */
19100
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19101
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19102
      nrange += tp[i] > X_INT64_MAX ;
19103
    }
19104
   /* copy workspace back if necessary */
19105
    if (realign) {
19106
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19107
      xp = (int64 *) *xpp;
19108
    }
19109
   /* update xpp and tp */
19110
    xp += ni;
19111
    tp += ni;
19112
    *xpp = (void*)xp;
19113
  }
19114
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19115
19116
#else   /* not SX */
19117
19118
0
  char *xp = (char *) *xpp;
19119
0
  int status = NC_NOERR;
19120
19121
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19122
0
  {
19123
0
    int lstatus = ncx_put_longlong_ushort(xp, tp, fillp);
19124
0
    if (status == NC_NOERR) /* report the first encountered error */
19125
0
      status = lstatus;
19126
0
  }
19127
19128
0
  *xpp = (void *)xp;
19129
0
  return status;
19130
0
#endif
19131
0
}
19132
19133
int
19134
ncx_putn_longlong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
19135
0
{
19136
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19137
19138
 /* basic algorithm is:
19139
  *   - ensure sane alignment of output data
19140
  *   - copy (conversion happens automatically) input data
19141
  *     to output
19142
  *   - update tp to point at next unconverted input, and xpp to point
19143
  *     at next location for converted output
19144
  */
19145
  long i, j, ni;
19146
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19147
  int64 *xp;
19148
  int nrange = 0;         /* number of range errors */
19149
  int realign = 0;        /* "do we need to fix input data alignment?" */
19150
  long cxp = (long) *((char**)xpp);
19151
19152
  realign = (cxp & 7) % SIZEOF_INT64;
19153
  /* sjl: manually stripmine so we can limit amount of
19154
   * vector work space reserved to LOOPCNT elements. Also
19155
   * makes vectorisation easy */
19156
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19157
    ni=Min(nelems-j,LOOPCNT);
19158
    if (realign) {
19159
      xp = tmp;
19160
    } else {
19161
      xp = (int64 *) *xpp;
19162
    }
19163
   /* copy the next block */
19164
#pragma cdir loopcnt=LOOPCNT
19165
#pragma cdir shortloop
19166
    for (i=0; i<ni; i++) {
19167
      /* the normal case: */
19168
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19169
     /* test for range errors (not always needed but do it anyway) */
19170
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19171
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19172
      nrange += tp[i] > X_INT64_MAX ;
19173
    }
19174
   /* copy workspace back if necessary */
19175
    if (realign) {
19176
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19177
      xp = (int64 *) *xpp;
19178
    }
19179
   /* update xpp and tp */
19180
    xp += ni;
19181
    tp += ni;
19182
    *xpp = (void*)xp;
19183
  }
19184
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19185
19186
#else   /* not SX */
19187
19188
0
  char *xp = (char *) *xpp;
19189
0
  int status = NC_NOERR;
19190
19191
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19192
0
  {
19193
0
    int lstatus = ncx_put_longlong_uint(xp, tp, fillp);
19194
0
    if (status == NC_NOERR) /* report the first encountered error */
19195
0
      status = lstatus;
19196
0
  }
19197
19198
0
  *xpp = (void *)xp;
19199
0
  return status;
19200
0
#endif
19201
0
}
19202
19203
int
19204
ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
19205
0
{
19206
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19207
19208
 /* basic algorithm is:
19209
  *   - ensure sane alignment of output data
19210
  *   - copy (conversion happens automatically) input data
19211
  *     to output
19212
  *   - update tp to point at next unconverted input, and xpp to point
19213
  *     at next location for converted output
19214
  */
19215
  long i, j, ni;
19216
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19217
  int64 *xp;
19218
  int nrange = 0;         /* number of range errors */
19219
  int realign = 0;        /* "do we need to fix input data alignment?" */
19220
  long cxp = (long) *((char**)xpp);
19221
19222
  realign = (cxp & 7) % SIZEOF_INT64;
19223
  /* sjl: manually stripmine so we can limit amount of
19224
   * vector work space reserved to LOOPCNT elements. Also
19225
   * makes vectorisation easy */
19226
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19227
    ni=Min(nelems-j,LOOPCNT);
19228
    if (realign) {
19229
      xp = tmp;
19230
    } else {
19231
      xp = (int64 *) *xpp;
19232
    }
19233
   /* copy the next block */
19234
#pragma cdir loopcnt=LOOPCNT
19235
#pragma cdir shortloop
19236
    for (i=0; i<ni; i++) {
19237
      /* the normal case: */
19238
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19239
     /* test for range errors (not always needed but do it anyway) */
19240
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19241
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19242
      nrange += tp[i] > X_INT64_MAX ;
19243
    }
19244
   /* copy workspace back if necessary */
19245
    if (realign) {
19246
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19247
      xp = (int64 *) *xpp;
19248
    }
19249
   /* update xpp and tp */
19250
    xp += ni;
19251
    tp += ni;
19252
    *xpp = (void*)xp;
19253
  }
19254
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19255
19256
#else   /* not SX */
19257
19258
0
  char *xp = (char *) *xpp;
19259
0
  int status = NC_NOERR;
19260
19261
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19262
0
  {
19263
0
    int lstatus = ncx_put_longlong_ulonglong(xp, tp, fillp);
19264
0
    if (status == NC_NOERR) /* report the first encountered error */
19265
0
      status = lstatus;
19266
0
  }
19267
19268
0
  *xpp = (void *)xp;
19269
0
  return status;
19270
0
#endif
19271
0
}
19272
19273
19274
/* uint64 --------------------------------------------------------------------*/
19275
19276
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
19277
/* optimized version */
19278
int
19279
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp)
19280
0
{
19281
#ifdef WORDS_BIGENDIAN
19282
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
19283
# else
19284
0
  swapn8b(tp, *xpp, nelems);
19285
0
# endif
19286
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
19287
0
  return NC_NOERR;
19288
0
}
19289
#else
19290
int
19291
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
19292
{
19293
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19294
19295
 /* basic algorithm is:
19296
  *   - ensure sane alignment of input data
19297
  *   - copy (conversion happens automatically) input data
19298
  *     to output
19299
  *   - update xpp to point at next unconverted input, and tp to point
19300
  *     at next location for converted output
19301
  */
19302
  long i, j, ni;
19303
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19304
  uint64 *xp;
19305
  int nrange = 0;         /* number of range errors */
19306
  int realign = 0;        /* "do we need to fix input data alignment?" */
19307
  long cxp = (long) *((char**)xpp);
19308
19309
  realign = (cxp & 7) % SIZEOF_UINT64;
19310
  /* sjl: manually stripmine so we can limit amount of
19311
   * vector work space reserved to LOOPCNT elements. Also
19312
   * makes vectorisation easy */
19313
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19314
    ni=Min(nelems-j,LOOPCNT);
19315
    if (realign) {
19316
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19317
      xp = tmp;
19318
    } else {
19319
      xp = (uint64 *) *xpp;
19320
    }
19321
   /* copy the next block */
19322
#pragma cdir loopcnt=LOOPCNT
19323
#pragma cdir shortloop
19324
    for (i=0; i<ni; i++) {
19325
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
19326
     /* test for range errors (not always needed but do it anyway) */
19327
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19328
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19329
      nrange += xp[i] > ULONGLONG_MAX ;
19330
    }
19331
   /* update xpp and tp */
19332
    if (realign) xp = (uint64 *) *xpp;
19333
    xp += ni;
19334
    tp += ni;
19335
    *xpp = (void*)xp;
19336
  }
19337
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19338
19339
#else   /* not SX */
19340
  const char *xp = (const char *) *xpp;
19341
  int status = NC_NOERR;
19342
19343
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19344
  {
19345
    const int lstatus = ncx_get_ulonglong_ulonglong(xp, tp);
19346
    if (status == NC_NOERR) /* report the first encountered error */
19347
      status = lstatus;
19348
  }
19349
19350
  *xpp = (const void *)xp;
19351
  return status;
19352
#endif
19353
}
19354
19355
#endif
19356
int
19357
ncx_getn_ulonglong_schar(const void **xpp, size_t nelems, schar *tp)
19358
0
{
19359
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19360
19361
 /* basic algorithm is:
19362
  *   - ensure sane alignment of input data
19363
  *   - copy (conversion happens automatically) input data
19364
  *     to output
19365
  *   - update xpp to point at next unconverted input, and tp to point
19366
  *     at next location for converted output
19367
  */
19368
  long i, j, ni;
19369
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19370
  uint64 *xp;
19371
  int nrange = 0;         /* number of range errors */
19372
  int realign = 0;        /* "do we need to fix input data alignment?" */
19373
  long cxp = (long) *((char**)xpp);
19374
19375
  realign = (cxp & 7) % SIZEOF_UINT64;
19376
  /* sjl: manually stripmine so we can limit amount of
19377
   * vector work space reserved to LOOPCNT elements. Also
19378
   * makes vectorisation easy */
19379
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19380
    ni=Min(nelems-j,LOOPCNT);
19381
    if (realign) {
19382
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19383
      xp = tmp;
19384
    } else {
19385
      xp = (uint64 *) *xpp;
19386
    }
19387
   /* copy the next block */
19388
#pragma cdir loopcnt=LOOPCNT
19389
#pragma cdir shortloop
19390
    for (i=0; i<ni; i++) {
19391
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
19392
     /* test for range errors (not always needed but do it anyway) */
19393
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19394
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19395
      nrange += xp[i] > SCHAR_MAX ;
19396
    }
19397
   /* update xpp and tp */
19398
    if (realign) xp = (uint64 *) *xpp;
19399
    xp += ni;
19400
    tp += ni;
19401
    *xpp = (void*)xp;
19402
  }
19403
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19404
19405
#else   /* not SX */
19406
0
  const char *xp = (const char *) *xpp;
19407
0
  int status = NC_NOERR;
19408
19409
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19410
0
  {
19411
0
    const int lstatus = ncx_get_ulonglong_schar(xp, tp);
19412
0
    if (status == NC_NOERR) /* report the first encountered error */
19413
0
      status = lstatus;
19414
0
  }
19415
19416
0
  *xpp = (const void *)xp;
19417
0
  return status;
19418
0
#endif
19419
0
}
19420
19421
int
19422
ncx_getn_ulonglong_short(const void **xpp, size_t nelems, short *tp)
19423
0
{
19424
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19425
19426
 /* basic algorithm is:
19427
  *   - ensure sane alignment of input data
19428
  *   - copy (conversion happens automatically) input data
19429
  *     to output
19430
  *   - update xpp to point at next unconverted input, and tp to point
19431
  *     at next location for converted output
19432
  */
19433
  long i, j, ni;
19434
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19435
  uint64 *xp;
19436
  int nrange = 0;         /* number of range errors */
19437
  int realign = 0;        /* "do we need to fix input data alignment?" */
19438
  long cxp = (long) *((char**)xpp);
19439
19440
  realign = (cxp & 7) % SIZEOF_UINT64;
19441
  /* sjl: manually stripmine so we can limit amount of
19442
   * vector work space reserved to LOOPCNT elements. Also
19443
   * makes vectorisation easy */
19444
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19445
    ni=Min(nelems-j,LOOPCNT);
19446
    if (realign) {
19447
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19448
      xp = tmp;
19449
    } else {
19450
      xp = (uint64 *) *xpp;
19451
    }
19452
   /* copy the next block */
19453
#pragma cdir loopcnt=LOOPCNT
19454
#pragma cdir shortloop
19455
    for (i=0; i<ni; i++) {
19456
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
19457
     /* test for range errors (not always needed but do it anyway) */
19458
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19459
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19460
      nrange += xp[i] > SHORT_MAX ;
19461
    }
19462
   /* update xpp and tp */
19463
    if (realign) xp = (uint64 *) *xpp;
19464
    xp += ni;
19465
    tp += ni;
19466
    *xpp = (void*)xp;
19467
  }
19468
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19469
19470
#else   /* not SX */
19471
0
  const char *xp = (const char *) *xpp;
19472
0
  int status = NC_NOERR;
19473
19474
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19475
0
  {
19476
0
    const int lstatus = ncx_get_ulonglong_short(xp, tp);
19477
0
    if (status == NC_NOERR) /* report the first encountered error */
19478
0
      status = lstatus;
19479
0
  }
19480
19481
0
  *xpp = (const void *)xp;
19482
0
  return status;
19483
0
#endif
19484
0
}
19485
19486
int
19487
ncx_getn_ulonglong_int(const void **xpp, size_t nelems, int *tp)
19488
0
{
19489
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19490
19491
 /* basic algorithm is:
19492
  *   - ensure sane alignment of input data
19493
  *   - copy (conversion happens automatically) input data
19494
  *     to output
19495
  *   - update xpp to point at next unconverted input, and tp to point
19496
  *     at next location for converted output
19497
  */
19498
  long i, j, ni;
19499
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19500
  uint64 *xp;
19501
  int nrange = 0;         /* number of range errors */
19502
  int realign = 0;        /* "do we need to fix input data alignment?" */
19503
  long cxp = (long) *((char**)xpp);
19504
19505
  realign = (cxp & 7) % SIZEOF_UINT64;
19506
  /* sjl: manually stripmine so we can limit amount of
19507
   * vector work space reserved to LOOPCNT elements. Also
19508
   * makes vectorisation easy */
19509
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19510
    ni=Min(nelems-j,LOOPCNT);
19511
    if (realign) {
19512
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19513
      xp = tmp;
19514
    } else {
19515
      xp = (uint64 *) *xpp;
19516
    }
19517
   /* copy the next block */
19518
#pragma cdir loopcnt=LOOPCNT
19519
#pragma cdir shortloop
19520
    for (i=0; i<ni; i++) {
19521
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
19522
     /* test for range errors (not always needed but do it anyway) */
19523
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19524
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19525
      nrange += xp[i] > INT_MAX ;
19526
    }
19527
   /* update xpp and tp */
19528
    if (realign) xp = (uint64 *) *xpp;
19529
    xp += ni;
19530
    tp += ni;
19531
    *xpp = (void*)xp;
19532
  }
19533
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19534
19535
#else   /* not SX */
19536
0
  const char *xp = (const char *) *xpp;
19537
0
  int status = NC_NOERR;
19538
19539
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19540
0
  {
19541
0
    const int lstatus = ncx_get_ulonglong_int(xp, tp);
19542
0
    if (status == NC_NOERR) /* report the first encountered error */
19543
0
      status = lstatus;
19544
0
  }
19545
19546
0
  *xpp = (const void *)xp;
19547
0
  return status;
19548
0
#endif
19549
0
}
19550
19551
int
19552
ncx_getn_ulonglong_long(const void **xpp, size_t nelems, long *tp)
19553
0
{
19554
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19555
19556
 /* basic algorithm is:
19557
  *   - ensure sane alignment of input data
19558
  *   - copy (conversion happens automatically) input data
19559
  *     to output
19560
  *   - update xpp to point at next unconverted input, and tp to point
19561
  *     at next location for converted output
19562
  */
19563
  long i, j, ni;
19564
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19565
  uint64 *xp;
19566
  int nrange = 0;         /* number of range errors */
19567
  int realign = 0;        /* "do we need to fix input data alignment?" */
19568
  long cxp = (long) *((char**)xpp);
19569
19570
  realign = (cxp & 7) % SIZEOF_UINT64;
19571
  /* sjl: manually stripmine so we can limit amount of
19572
   * vector work space reserved to LOOPCNT elements. Also
19573
   * makes vectorisation easy */
19574
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19575
    ni=Min(nelems-j,LOOPCNT);
19576
    if (realign) {
19577
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19578
      xp = tmp;
19579
    } else {
19580
      xp = (uint64 *) *xpp;
19581
    }
19582
   /* copy the next block */
19583
#pragma cdir loopcnt=LOOPCNT
19584
#pragma cdir shortloop
19585
    for (i=0; i<ni; i++) {
19586
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
19587
     /* test for range errors (not always needed but do it anyway) */
19588
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19589
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19590
      nrange += xp[i] > LONG_MAX ;
19591
    }
19592
   /* update xpp and tp */
19593
    if (realign) xp = (uint64 *) *xpp;
19594
    xp += ni;
19595
    tp += ni;
19596
    *xpp = (void*)xp;
19597
  }
19598
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19599
19600
#else   /* not SX */
19601
0
  const char *xp = (const char *) *xpp;
19602
0
  int status = NC_NOERR;
19603
19604
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19605
0
  {
19606
0
    const int lstatus = ncx_get_ulonglong_long(xp, tp);
19607
0
    if (status == NC_NOERR) /* report the first encountered error */
19608
0
      status = lstatus;
19609
0
  }
19610
19611
0
  *xpp = (const void *)xp;
19612
0
  return status;
19613
0
#endif
19614
0
}
19615
19616
int
19617
ncx_getn_ulonglong_float(const void **xpp, size_t nelems, float *tp)
19618
0
{
19619
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19620
19621
 /* basic algorithm is:
19622
  *   - ensure sane alignment of input data
19623
  *   - copy (conversion happens automatically) input data
19624
  *     to output
19625
  *   - update xpp to point at next unconverted input, and tp to point
19626
  *     at next location for converted output
19627
  */
19628
  long i, j, ni;
19629
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19630
  uint64 *xp;
19631
  int nrange = 0;         /* number of range errors */
19632
  int realign = 0;        /* "do we need to fix input data alignment?" */
19633
  long cxp = (long) *((char**)xpp);
19634
19635
  realign = (cxp & 7) % SIZEOF_UINT64;
19636
  /* sjl: manually stripmine so we can limit amount of
19637
   * vector work space reserved to LOOPCNT elements. Also
19638
   * makes vectorisation easy */
19639
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19640
    ni=Min(nelems-j,LOOPCNT);
19641
    if (realign) {
19642
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19643
      xp = tmp;
19644
    } else {
19645
      xp = (uint64 *) *xpp;
19646
    }
19647
   /* copy the next block */
19648
#pragma cdir loopcnt=LOOPCNT
19649
#pragma cdir shortloop
19650
    for (i=0; i<ni; i++) {
19651
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
19652
     /* test for range errors (not always needed but do it anyway) */
19653
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19654
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19655
      nrange += xp[i] > FLOAT_MAX ;
19656
    }
19657
   /* update xpp and tp */
19658
    if (realign) xp = (uint64 *) *xpp;
19659
    xp += ni;
19660
    tp += ni;
19661
    *xpp = (void*)xp;
19662
  }
19663
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19664
19665
#else   /* not SX */
19666
0
  const char *xp = (const char *) *xpp;
19667
0
  int status = NC_NOERR;
19668
19669
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19670
0
  {
19671
0
    const int lstatus = ncx_get_ulonglong_float(xp, tp);
19672
0
    if (status == NC_NOERR) /* report the first encountered error */
19673
0
      status = lstatus;
19674
0
  }
19675
19676
0
  *xpp = (const void *)xp;
19677
0
  return status;
19678
0
#endif
19679
0
}
19680
19681
int
19682
ncx_getn_ulonglong_double(const void **xpp, size_t nelems, double *tp)
19683
0
{
19684
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19685
19686
 /* basic algorithm is:
19687
  *   - ensure sane alignment of input data
19688
  *   - copy (conversion happens automatically) input data
19689
  *     to output
19690
  *   - update xpp to point at next unconverted input, and tp to point
19691
  *     at next location for converted output
19692
  */
19693
  long i, j, ni;
19694
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19695
  uint64 *xp;
19696
  int nrange = 0;         /* number of range errors */
19697
  int realign = 0;        /* "do we need to fix input data alignment?" */
19698
  long cxp = (long) *((char**)xpp);
19699
19700
  realign = (cxp & 7) % SIZEOF_UINT64;
19701
  /* sjl: manually stripmine so we can limit amount of
19702
   * vector work space reserved to LOOPCNT elements. Also
19703
   * makes vectorisation easy */
19704
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19705
    ni=Min(nelems-j,LOOPCNT);
19706
    if (realign) {
19707
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19708
      xp = tmp;
19709
    } else {
19710
      xp = (uint64 *) *xpp;
19711
    }
19712
   /* copy the next block */
19713
#pragma cdir loopcnt=LOOPCNT
19714
#pragma cdir shortloop
19715
    for (i=0; i<ni; i++) {
19716
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
19717
     /* test for range errors (not always needed but do it anyway) */
19718
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19719
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19720
      nrange += xp[i] > DOUBLE_MAX ;
19721
    }
19722
   /* update xpp and tp */
19723
    if (realign) xp = (uint64 *) *xpp;
19724
    xp += ni;
19725
    tp += ni;
19726
    *xpp = (void*)xp;
19727
  }
19728
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19729
19730
#else   /* not SX */
19731
0
  const char *xp = (const char *) *xpp;
19732
0
  int status = NC_NOERR;
19733
19734
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19735
0
  {
19736
0
    const int lstatus = ncx_get_ulonglong_double(xp, tp);
19737
0
    if (status == NC_NOERR) /* report the first encountered error */
19738
0
      status = lstatus;
19739
0
  }
19740
19741
0
  *xpp = (const void *)xp;
19742
0
  return status;
19743
0
#endif
19744
0
}
19745
19746
int
19747
ncx_getn_ulonglong_longlong(const void **xpp, size_t nelems, longlong *tp)
19748
0
{
19749
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19750
19751
 /* basic algorithm is:
19752
  *   - ensure sane alignment of input data
19753
  *   - copy (conversion happens automatically) input data
19754
  *     to output
19755
  *   - update xpp to point at next unconverted input, and tp to point
19756
  *     at next location for converted output
19757
  */
19758
  long i, j, ni;
19759
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19760
  uint64 *xp;
19761
  int nrange = 0;         /* number of range errors */
19762
  int realign = 0;        /* "do we need to fix input data alignment?" */
19763
  long cxp = (long) *((char**)xpp);
19764
19765
  realign = (cxp & 7) % SIZEOF_UINT64;
19766
  /* sjl: manually stripmine so we can limit amount of
19767
   * vector work space reserved to LOOPCNT elements. Also
19768
   * makes vectorisation easy */
19769
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19770
    ni=Min(nelems-j,LOOPCNT);
19771
    if (realign) {
19772
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19773
      xp = tmp;
19774
    } else {
19775
      xp = (uint64 *) *xpp;
19776
    }
19777
   /* copy the next block */
19778
#pragma cdir loopcnt=LOOPCNT
19779
#pragma cdir shortloop
19780
    for (i=0; i<ni; i++) {
19781
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
19782
     /* test for range errors (not always needed but do it anyway) */
19783
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19784
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19785
      nrange += xp[i] > LONGLONG_MAX ;
19786
    }
19787
   /* update xpp and tp */
19788
    if (realign) xp = (uint64 *) *xpp;
19789
    xp += ni;
19790
    tp += ni;
19791
    *xpp = (void*)xp;
19792
  }
19793
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19794
19795
#else   /* not SX */
19796
0
  const char *xp = (const char *) *xpp;
19797
0
  int status = NC_NOERR;
19798
19799
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19800
0
  {
19801
0
    const int lstatus = ncx_get_ulonglong_longlong(xp, tp);
19802
0
    if (status == NC_NOERR) /* report the first encountered error */
19803
0
      status = lstatus;
19804
0
  }
19805
19806
0
  *xpp = (const void *)xp;
19807
0
  return status;
19808
0
#endif
19809
0
}
19810
19811
int
19812
ncx_getn_ulonglong_uchar(const void **xpp, size_t nelems, uchar *tp)
19813
0
{
19814
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19815
19816
 /* basic algorithm is:
19817
  *   - ensure sane alignment of input data
19818
  *   - copy (conversion happens automatically) input data
19819
  *     to output
19820
  *   - update xpp to point at next unconverted input, and tp to point
19821
  *     at next location for converted output
19822
  */
19823
  long i, j, ni;
19824
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19825
  uint64 *xp;
19826
  int nrange = 0;         /* number of range errors */
19827
  int realign = 0;        /* "do we need to fix input data alignment?" */
19828
  long cxp = (long) *((char**)xpp);
19829
19830
  realign = (cxp & 7) % SIZEOF_UINT64;
19831
  /* sjl: manually stripmine so we can limit amount of
19832
   * vector work space reserved to LOOPCNT elements. Also
19833
   * makes vectorisation easy */
19834
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19835
    ni=Min(nelems-j,LOOPCNT);
19836
    if (realign) {
19837
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19838
      xp = tmp;
19839
    } else {
19840
      xp = (uint64 *) *xpp;
19841
    }
19842
   /* copy the next block */
19843
#pragma cdir loopcnt=LOOPCNT
19844
#pragma cdir shortloop
19845
    for (i=0; i<ni; i++) {
19846
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
19847
     /* test for range errors (not always needed but do it anyway) */
19848
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19849
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19850
      nrange += xp[i] > UCHAR_MAX ;
19851
    }
19852
   /* update xpp and tp */
19853
    if (realign) xp = (uint64 *) *xpp;
19854
    xp += ni;
19855
    tp += ni;
19856
    *xpp = (void*)xp;
19857
  }
19858
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19859
19860
#else   /* not SX */
19861
0
  const char *xp = (const char *) *xpp;
19862
0
  int status = NC_NOERR;
19863
19864
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19865
0
  {
19866
0
    const int lstatus = ncx_get_ulonglong_uchar(xp, tp);
19867
0
    if (status == NC_NOERR) /* report the first encountered error */
19868
0
      status = lstatus;
19869
0
  }
19870
19871
0
  *xpp = (const void *)xp;
19872
0
  return status;
19873
0
#endif
19874
0
}
19875
19876
int
19877
ncx_getn_ulonglong_ushort(const void **xpp, size_t nelems, ushort *tp)
19878
0
{
19879
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19880
19881
 /* basic algorithm is:
19882
  *   - ensure sane alignment of input data
19883
  *   - copy (conversion happens automatically) input data
19884
  *     to output
19885
  *   - update xpp to point at next unconverted input, and tp to point
19886
  *     at next location for converted output
19887
  */
19888
  long i, j, ni;
19889
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19890
  uint64 *xp;
19891
  int nrange = 0;         /* number of range errors */
19892
  int realign = 0;        /* "do we need to fix input data alignment?" */
19893
  long cxp = (long) *((char**)xpp);
19894
19895
  realign = (cxp & 7) % SIZEOF_UINT64;
19896
  /* sjl: manually stripmine so we can limit amount of
19897
   * vector work space reserved to LOOPCNT elements. Also
19898
   * makes vectorisation easy */
19899
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19900
    ni=Min(nelems-j,LOOPCNT);
19901
    if (realign) {
19902
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19903
      xp = tmp;
19904
    } else {
19905
      xp = (uint64 *) *xpp;
19906
    }
19907
   /* copy the next block */
19908
#pragma cdir loopcnt=LOOPCNT
19909
#pragma cdir shortloop
19910
    for (i=0; i<ni; i++) {
19911
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
19912
     /* test for range errors (not always needed but do it anyway) */
19913
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19914
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19915
      nrange += xp[i] > USHORT_MAX ;
19916
    }
19917
   /* update xpp and tp */
19918
    if (realign) xp = (uint64 *) *xpp;
19919
    xp += ni;
19920
    tp += ni;
19921
    *xpp = (void*)xp;
19922
  }
19923
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19924
19925
#else   /* not SX */
19926
0
  const char *xp = (const char *) *xpp;
19927
0
  int status = NC_NOERR;
19928
19929
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19930
0
  {
19931
0
    const int lstatus = ncx_get_ulonglong_ushort(xp, tp);
19932
0
    if (status == NC_NOERR) /* report the first encountered error */
19933
0
      status = lstatus;
19934
0
  }
19935
19936
0
  *xpp = (const void *)xp;
19937
0
  return status;
19938
0
#endif
19939
0
}
19940
19941
int
19942
ncx_getn_ulonglong_uint(const void **xpp, size_t nelems, uint *tp)
19943
0
{
19944
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19945
19946
 /* basic algorithm is:
19947
  *   - ensure sane alignment of input data
19948
  *   - copy (conversion happens automatically) input data
19949
  *     to output
19950
  *   - update xpp to point at next unconverted input, and tp to point
19951
  *     at next location for converted output
19952
  */
19953
  long i, j, ni;
19954
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19955
  uint64 *xp;
19956
  int nrange = 0;         /* number of range errors */
19957
  int realign = 0;        /* "do we need to fix input data alignment?" */
19958
  long cxp = (long) *((char**)xpp);
19959
19960
  realign = (cxp & 7) % SIZEOF_UINT64;
19961
  /* sjl: manually stripmine so we can limit amount of
19962
   * vector work space reserved to LOOPCNT elements. Also
19963
   * makes vectorisation easy */
19964
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19965
    ni=Min(nelems-j,LOOPCNT);
19966
    if (realign) {
19967
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19968
      xp = tmp;
19969
    } else {
19970
      xp = (uint64 *) *xpp;
19971
    }
19972
   /* copy the next block */
19973
#pragma cdir loopcnt=LOOPCNT
19974
#pragma cdir shortloop
19975
    for (i=0; i<ni; i++) {
19976
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
19977
     /* test for range errors (not always needed but do it anyway) */
19978
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19979
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19980
      nrange += xp[i] > UINT_MAX ;
19981
    }
19982
   /* update xpp and tp */
19983
    if (realign) xp = (uint64 *) *xpp;
19984
    xp += ni;
19985
    tp += ni;
19986
    *xpp = (void*)xp;
19987
  }
19988
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19989
19990
#else   /* not SX */
19991
0
  const char *xp = (const char *) *xpp;
19992
0
  int status = NC_NOERR;
19993
19994
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19995
0
  {
19996
0
    const int lstatus = ncx_get_ulonglong_uint(xp, tp);
19997
0
    if (status == NC_NOERR) /* report the first encountered error */
19998
0
      status = lstatus;
19999
0
  }
20000
20001
0
  *xpp = (const void *)xp;
20002
0
  return status;
20003
0
#endif
20004
0
}
20005
20006
20007
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
20008
/* optimized version */
20009
int
20010
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp, void *fillp)
20011
0
{
20012
#ifdef WORDS_BIGENDIAN
20013
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
20014
# else
20015
0
  swapn8b(*xpp, tp, nelems);
20016
0
# endif
20017
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
20018
0
  return NC_NOERR;
20019
0
}
20020
#else
20021
int
20022
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
20023
{
20024
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20025
20026
 /* basic algorithm is:
20027
  *   - ensure sane alignment of output data
20028
  *   - copy (conversion happens automatically) input data
20029
  *     to output
20030
  *   - update tp to point at next unconverted input, and xpp to point
20031
  *     at next location for converted output
20032
  */
20033
  long i, j, ni;
20034
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20035
  uint64 *xp;
20036
  int nrange = 0;         /* number of range errors */
20037
  int realign = 0;        /* "do we need to fix input data alignment?" */
20038
  long cxp = (long) *((char**)xpp);
20039
20040
  realign = (cxp & 7) % SIZEOF_UINT64;
20041
  /* sjl: manually stripmine so we can limit amount of
20042
   * vector work space reserved to LOOPCNT elements. Also
20043
   * makes vectorisation easy */
20044
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20045
    ni=Min(nelems-j,LOOPCNT);
20046
    if (realign) {
20047
      xp = tmp;
20048
    } else {
20049
      xp = (uint64 *) *xpp;
20050
    }
20051
   /* copy the next block */
20052
#pragma cdir loopcnt=LOOPCNT
20053
#pragma cdir shortloop
20054
    for (i=0; i<ni; i++) {
20055
      /* the normal case: */
20056
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20057
     /* test for range errors (not always needed but do it anyway) */
20058
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20059
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20060
      nrange += tp[i] > X_UINT64_MAX ;
20061
    }
20062
   /* copy workspace back if necessary */
20063
    if (realign) {
20064
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20065
      xp = (uint64 *) *xpp;
20066
    }
20067
   /* update xpp and tp */
20068
    xp += ni;
20069
    tp += ni;
20070
    *xpp = (void*)xp;
20071
  }
20072
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20073
20074
#else   /* not SX */
20075
20076
  char *xp = (char *) *xpp;
20077
  int status = NC_NOERR;
20078
20079
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20080
  {
20081
    int lstatus = ncx_put_ulonglong_ulonglong(xp, tp, fillp);
20082
    if (status == NC_NOERR) /* report the first encountered error */
20083
      status = lstatus;
20084
  }
20085
20086
  *xpp = (void *)xp;
20087
  return status;
20088
#endif
20089
}
20090
20091
#endif
20092
int
20093
ncx_putn_ulonglong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
20094
0
{
20095
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20096
20097
 /* basic algorithm is:
20098
  *   - ensure sane alignment of output data
20099
  *   - copy (conversion happens automatically) input data
20100
  *     to output
20101
  *   - update tp to point at next unconverted input, and xpp to point
20102
  *     at next location for converted output
20103
  */
20104
  long i, j, ni;
20105
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20106
  uint64 *xp;
20107
  int nrange = 0;         /* number of range errors */
20108
  int realign = 0;        /* "do we need to fix input data alignment?" */
20109
  long cxp = (long) *((char**)xpp);
20110
20111
  realign = (cxp & 7) % SIZEOF_UINT64;
20112
  /* sjl: manually stripmine so we can limit amount of
20113
   * vector work space reserved to LOOPCNT elements. Also
20114
   * makes vectorisation easy */
20115
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20116
    ni=Min(nelems-j,LOOPCNT);
20117
    if (realign) {
20118
      xp = tmp;
20119
    } else {
20120
      xp = (uint64 *) *xpp;
20121
    }
20122
   /* copy the next block */
20123
#pragma cdir loopcnt=LOOPCNT
20124
#pragma cdir shortloop
20125
    for (i=0; i<ni; i++) {
20126
      /* the normal case: */
20127
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20128
     /* test for range errors (not always needed but do it anyway) */
20129
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20130
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20131
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20132
    }
20133
   /* copy workspace back if necessary */
20134
    if (realign) {
20135
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20136
      xp = (uint64 *) *xpp;
20137
    }
20138
   /* update xpp and tp */
20139
    xp += ni;
20140
    tp += ni;
20141
    *xpp = (void*)xp;
20142
  }
20143
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20144
20145
#else   /* not SX */
20146
20147
0
  char *xp = (char *) *xpp;
20148
0
  int status = NC_NOERR;
20149
20150
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20151
0
  {
20152
0
    int lstatus = ncx_put_ulonglong_schar(xp, tp, fillp);
20153
0
    if (status == NC_NOERR) /* report the first encountered error */
20154
0
      status = lstatus;
20155
0
  }
20156
20157
0
  *xpp = (void *)xp;
20158
0
  return status;
20159
0
#endif
20160
0
}
20161
20162
int
20163
ncx_putn_ulonglong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
20164
0
{
20165
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20166
20167
 /* basic algorithm is:
20168
  *   - ensure sane alignment of output data
20169
  *   - copy (conversion happens automatically) input data
20170
  *     to output
20171
  *   - update tp to point at next unconverted input, and xpp to point
20172
  *     at next location for converted output
20173
  */
20174
  long i, j, ni;
20175
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20176
  uint64 *xp;
20177
  int nrange = 0;         /* number of range errors */
20178
  int realign = 0;        /* "do we need to fix input data alignment?" */
20179
  long cxp = (long) *((char**)xpp);
20180
20181
  realign = (cxp & 7) % SIZEOF_UINT64;
20182
  /* sjl: manually stripmine so we can limit amount of
20183
   * vector work space reserved to LOOPCNT elements. Also
20184
   * makes vectorisation easy */
20185
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20186
    ni=Min(nelems-j,LOOPCNT);
20187
    if (realign) {
20188
      xp = tmp;
20189
    } else {
20190
      xp = (uint64 *) *xpp;
20191
    }
20192
   /* copy the next block */
20193
#pragma cdir loopcnt=LOOPCNT
20194
#pragma cdir shortloop
20195
    for (i=0; i<ni; i++) {
20196
      /* the normal case: */
20197
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20198
     /* test for range errors (not always needed but do it anyway) */
20199
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20200
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20201
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20202
    }
20203
   /* copy workspace back if necessary */
20204
    if (realign) {
20205
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20206
      xp = (uint64 *) *xpp;
20207
    }
20208
   /* update xpp and tp */
20209
    xp += ni;
20210
    tp += ni;
20211
    *xpp = (void*)xp;
20212
  }
20213
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20214
20215
#else   /* not SX */
20216
20217
0
  char *xp = (char *) *xpp;
20218
0
  int status = NC_NOERR;
20219
20220
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20221
0
  {
20222
0
    int lstatus = ncx_put_ulonglong_short(xp, tp, fillp);
20223
0
    if (status == NC_NOERR) /* report the first encountered error */
20224
0
      status = lstatus;
20225
0
  }
20226
20227
0
  *xpp = (void *)xp;
20228
0
  return status;
20229
0
#endif
20230
0
}
20231
20232
int
20233
ncx_putn_ulonglong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
20234
0
{
20235
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20236
20237
 /* basic algorithm is:
20238
  *   - ensure sane alignment of output data
20239
  *   - copy (conversion happens automatically) input data
20240
  *     to output
20241
  *   - update tp to point at next unconverted input, and xpp to point
20242
  *     at next location for converted output
20243
  */
20244
  long i, j, ni;
20245
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20246
  uint64 *xp;
20247
  int nrange = 0;         /* number of range errors */
20248
  int realign = 0;        /* "do we need to fix input data alignment?" */
20249
  long cxp = (long) *((char**)xpp);
20250
20251
  realign = (cxp & 7) % SIZEOF_UINT64;
20252
  /* sjl: manually stripmine so we can limit amount of
20253
   * vector work space reserved to LOOPCNT elements. Also
20254
   * makes vectorisation easy */
20255
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20256
    ni=Min(nelems-j,LOOPCNT);
20257
    if (realign) {
20258
      xp = tmp;
20259
    } else {
20260
      xp = (uint64 *) *xpp;
20261
    }
20262
   /* copy the next block */
20263
#pragma cdir loopcnt=LOOPCNT
20264
#pragma cdir shortloop
20265
    for (i=0; i<ni; i++) {
20266
      /* the normal case: */
20267
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20268
     /* test for range errors (not always needed but do it anyway) */
20269
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20270
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20271
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20272
    }
20273
   /* copy workspace back if necessary */
20274
    if (realign) {
20275
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20276
      xp = (uint64 *) *xpp;
20277
    }
20278
   /* update xpp and tp */
20279
    xp += ni;
20280
    tp += ni;
20281
    *xpp = (void*)xp;
20282
  }
20283
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20284
20285
#else   /* not SX */
20286
20287
0
  char *xp = (char *) *xpp;
20288
0
  int status = NC_NOERR;
20289
20290
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20291
0
  {
20292
0
    int lstatus = ncx_put_ulonglong_int(xp, tp, fillp);
20293
0
    if (status == NC_NOERR) /* report the first encountered error */
20294
0
      status = lstatus;
20295
0
  }
20296
20297
0
  *xpp = (void *)xp;
20298
0
  return status;
20299
0
#endif
20300
0
}
20301
20302
int
20303
ncx_putn_ulonglong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
20304
0
{
20305
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20306
20307
 /* basic algorithm is:
20308
  *   - ensure sane alignment of output data
20309
  *   - copy (conversion happens automatically) input data
20310
  *     to output
20311
  *   - update tp to point at next unconverted input, and xpp to point
20312
  *     at next location for converted output
20313
  */
20314
  long i, j, ni;
20315
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20316
  uint64 *xp;
20317
  int nrange = 0;         /* number of range errors */
20318
  int realign = 0;        /* "do we need to fix input data alignment?" */
20319
  long cxp = (long) *((char**)xpp);
20320
20321
  realign = (cxp & 7) % SIZEOF_UINT64;
20322
  /* sjl: manually stripmine so we can limit amount of
20323
   * vector work space reserved to LOOPCNT elements. Also
20324
   * makes vectorisation easy */
20325
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20326
    ni=Min(nelems-j,LOOPCNT);
20327
    if (realign) {
20328
      xp = tmp;
20329
    } else {
20330
      xp = (uint64 *) *xpp;
20331
    }
20332
   /* copy the next block */
20333
#pragma cdir loopcnt=LOOPCNT
20334
#pragma cdir shortloop
20335
    for (i=0; i<ni; i++) {
20336
      /* the normal case: */
20337
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20338
     /* test for range errors (not always needed but do it anyway) */
20339
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20340
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20341
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20342
    }
20343
   /* copy workspace back if necessary */
20344
    if (realign) {
20345
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20346
      xp = (uint64 *) *xpp;
20347
    }
20348
   /* update xpp and tp */
20349
    xp += ni;
20350
    tp += ni;
20351
    *xpp = (void*)xp;
20352
  }
20353
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20354
20355
#else   /* not SX */
20356
20357
0
  char *xp = (char *) *xpp;
20358
0
  int status = NC_NOERR;
20359
20360
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20361
0
  {
20362
0
    int lstatus = ncx_put_ulonglong_long(xp, tp, fillp);
20363
0
    if (status == NC_NOERR) /* report the first encountered error */
20364
0
      status = lstatus;
20365
0
  }
20366
20367
0
  *xpp = (void *)xp;
20368
0
  return status;
20369
0
#endif
20370
0
}
20371
20372
int
20373
ncx_putn_ulonglong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
20374
0
{
20375
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20376
20377
 /* basic algorithm is:
20378
  *   - ensure sane alignment of output data
20379
  *   - copy (conversion happens automatically) input data
20380
  *     to output
20381
  *   - update tp to point at next unconverted input, and xpp to point
20382
  *     at next location for converted output
20383
  */
20384
  long i, j, ni;
20385
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20386
  uint64 *xp;
20387
  int nrange = 0;         /* number of range errors */
20388
  int realign = 0;        /* "do we need to fix input data alignment?" */
20389
  long cxp = (long) *((char**)xpp);
20390
20391
  realign = (cxp & 7) % SIZEOF_UINT64;
20392
  /* sjl: manually stripmine so we can limit amount of
20393
   * vector work space reserved to LOOPCNT elements. Also
20394
   * makes vectorisation easy */
20395
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20396
    ni=Min(nelems-j,LOOPCNT);
20397
    if (realign) {
20398
      xp = tmp;
20399
    } else {
20400
      xp = (uint64 *) *xpp;
20401
    }
20402
   /* copy the next block */
20403
#pragma cdir loopcnt=LOOPCNT
20404
#pragma cdir shortloop
20405
    for (i=0; i<ni; i++) {
20406
      /* the normal case: */
20407
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20408
     /* test for range errors (not always needed but do it anyway) */
20409
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20410
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20411
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20412
    }
20413
   /* copy workspace back if necessary */
20414
    if (realign) {
20415
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20416
      xp = (uint64 *) *xpp;
20417
    }
20418
   /* update xpp and tp */
20419
    xp += ni;
20420
    tp += ni;
20421
    *xpp = (void*)xp;
20422
  }
20423
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20424
20425
#else   /* not SX */
20426
20427
0
  char *xp = (char *) *xpp;
20428
0
  int status = NC_NOERR;
20429
20430
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20431
0
  {
20432
0
    int lstatus = ncx_put_ulonglong_float(xp, tp, fillp);
20433
0
    if (status == NC_NOERR) /* report the first encountered error */
20434
0
      status = lstatus;
20435
0
  }
20436
20437
0
  *xpp = (void *)xp;
20438
0
  return status;
20439
0
#endif
20440
0
}
20441
20442
int
20443
ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
20444
0
{
20445
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20446
20447
 /* basic algorithm is:
20448
  *   - ensure sane alignment of output data
20449
  *   - copy (conversion happens automatically) input data
20450
  *     to output
20451
  *   - update tp to point at next unconverted input, and xpp to point
20452
  *     at next location for converted output
20453
  */
20454
  long i, j, ni;
20455
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20456
  uint64 *xp;
20457
  int nrange = 0;         /* number of range errors */
20458
  int realign = 0;        /* "do we need to fix input data alignment?" */
20459
  long cxp = (long) *((char**)xpp);
20460
20461
  realign = (cxp & 7) % SIZEOF_UINT64;
20462
  /* sjl: manually stripmine so we can limit amount of
20463
   * vector work space reserved to LOOPCNT elements. Also
20464
   * makes vectorisation easy */
20465
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20466
    ni=Min(nelems-j,LOOPCNT);
20467
    if (realign) {
20468
      xp = tmp;
20469
    } else {
20470
      xp = (uint64 *) *xpp;
20471
    }
20472
   /* copy the next block */
20473
#pragma cdir loopcnt=LOOPCNT
20474
#pragma cdir shortloop
20475
    for (i=0; i<ni; i++) {
20476
      /* the normal case: */
20477
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20478
     /* test for range errors (not always needed but do it anyway) */
20479
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20480
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20481
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20482
    }
20483
   /* copy workspace back if necessary */
20484
    if (realign) {
20485
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20486
      xp = (uint64 *) *xpp;
20487
    }
20488
   /* update xpp and tp */
20489
    xp += ni;
20490
    tp += ni;
20491
    *xpp = (void*)xp;
20492
  }
20493
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20494
20495
#else   /* not SX */
20496
20497
0
  char *xp = (char *) *xpp;
20498
0
  int status = NC_NOERR;
20499
20500
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20501
0
  {
20502
0
    int lstatus = ncx_put_ulonglong_double(xp, tp, fillp);
20503
0
    if (status == NC_NOERR) /* report the first encountered error */
20504
0
      status = lstatus;
20505
0
  }
20506
20507
0
  *xpp = (void *)xp;
20508
0
  return status;
20509
0
#endif
20510
0
}
20511
20512
int
20513
ncx_putn_ulonglong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
20514
0
{
20515
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20516
20517
 /* basic algorithm is:
20518
  *   - ensure sane alignment of output data
20519
  *   - copy (conversion happens automatically) input data
20520
  *     to output
20521
  *   - update tp to point at next unconverted input, and xpp to point
20522
  *     at next location for converted output
20523
  */
20524
  long i, j, ni;
20525
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20526
  uint64 *xp;
20527
  int nrange = 0;         /* number of range errors */
20528
  int realign = 0;        /* "do we need to fix input data alignment?" */
20529
  long cxp = (long) *((char**)xpp);
20530
20531
  realign = (cxp & 7) % SIZEOF_UINT64;
20532
  /* sjl: manually stripmine so we can limit amount of
20533
   * vector work space reserved to LOOPCNT elements. Also
20534
   * makes vectorisation easy */
20535
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20536
    ni=Min(nelems-j,LOOPCNT);
20537
    if (realign) {
20538
      xp = tmp;
20539
    } else {
20540
      xp = (uint64 *) *xpp;
20541
    }
20542
   /* copy the next block */
20543
#pragma cdir loopcnt=LOOPCNT
20544
#pragma cdir shortloop
20545
    for (i=0; i<ni; i++) {
20546
      /* the normal case: */
20547
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20548
     /* test for range errors (not always needed but do it anyway) */
20549
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20550
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20551
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20552
    }
20553
   /* copy workspace back if necessary */
20554
    if (realign) {
20555
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20556
      xp = (uint64 *) *xpp;
20557
    }
20558
   /* update xpp and tp */
20559
    xp += ni;
20560
    tp += ni;
20561
    *xpp = (void*)xp;
20562
  }
20563
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20564
20565
#else   /* not SX */
20566
20567
0
  char *xp = (char *) *xpp;
20568
0
  int status = NC_NOERR;
20569
20570
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20571
0
  {
20572
0
    int lstatus = ncx_put_ulonglong_longlong(xp, tp, fillp);
20573
0
    if (status == NC_NOERR) /* report the first encountered error */
20574
0
      status = lstatus;
20575
0
  }
20576
20577
0
  *xpp = (void *)xp;
20578
0
  return status;
20579
0
#endif
20580
0
}
20581
20582
int
20583
ncx_putn_ulonglong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
20584
0
{
20585
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20586
20587
 /* basic algorithm is:
20588
  *   - ensure sane alignment of output data
20589
  *   - copy (conversion happens automatically) input data
20590
  *     to output
20591
  *   - update tp to point at next unconverted input, and xpp to point
20592
  *     at next location for converted output
20593
  */
20594
  long i, j, ni;
20595
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20596
  uint64 *xp;
20597
  int nrange = 0;         /* number of range errors */
20598
  int realign = 0;        /* "do we need to fix input data alignment?" */
20599
  long cxp = (long) *((char**)xpp);
20600
20601
  realign = (cxp & 7) % SIZEOF_UINT64;
20602
  /* sjl: manually stripmine so we can limit amount of
20603
   * vector work space reserved to LOOPCNT elements. Also
20604
   * makes vectorisation easy */
20605
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20606
    ni=Min(nelems-j,LOOPCNT);
20607
    if (realign) {
20608
      xp = tmp;
20609
    } else {
20610
      xp = (uint64 *) *xpp;
20611
    }
20612
   /* copy the next block */
20613
#pragma cdir loopcnt=LOOPCNT
20614
#pragma cdir shortloop
20615
    for (i=0; i<ni; i++) {
20616
      /* the normal case: */
20617
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20618
     /* test for range errors (not always needed but do it anyway) */
20619
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20620
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20621
      nrange += tp[i] > X_UINT64_MAX ;
20622
    }
20623
   /* copy workspace back if necessary */
20624
    if (realign) {
20625
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20626
      xp = (uint64 *) *xpp;
20627
    }
20628
   /* update xpp and tp */
20629
    xp += ni;
20630
    tp += ni;
20631
    *xpp = (void*)xp;
20632
  }
20633
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20634
20635
#else   /* not SX */
20636
20637
0
  char *xp = (char *) *xpp;
20638
0
  int status = NC_NOERR;
20639
20640
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20641
0
  {
20642
0
    int lstatus = ncx_put_ulonglong_uchar(xp, tp, fillp);
20643
0
    if (status == NC_NOERR) /* report the first encountered error */
20644
0
      status = lstatus;
20645
0
  }
20646
20647
0
  *xpp = (void *)xp;
20648
0
  return status;
20649
0
#endif
20650
0
}
20651
20652
int
20653
ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
20654
0
{
20655
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20656
20657
 /* basic algorithm is:
20658
  *   - ensure sane alignment of output data
20659
  *   - copy (conversion happens automatically) input data
20660
  *     to output
20661
  *   - update tp to point at next unconverted input, and xpp to point
20662
  *     at next location for converted output
20663
  */
20664
  long i, j, ni;
20665
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20666
  uint64 *xp;
20667
  int nrange = 0;         /* number of range errors */
20668
  int realign = 0;        /* "do we need to fix input data alignment?" */
20669
  long cxp = (long) *((char**)xpp);
20670
20671
  realign = (cxp & 7) % SIZEOF_UINT64;
20672
  /* sjl: manually stripmine so we can limit amount of
20673
   * vector work space reserved to LOOPCNT elements. Also
20674
   * makes vectorisation easy */
20675
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20676
    ni=Min(nelems-j,LOOPCNT);
20677
    if (realign) {
20678
      xp = tmp;
20679
    } else {
20680
      xp = (uint64 *) *xpp;
20681
    }
20682
   /* copy the next block */
20683
#pragma cdir loopcnt=LOOPCNT
20684
#pragma cdir shortloop
20685
    for (i=0; i<ni; i++) {
20686
      /* the normal case: */
20687
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20688
     /* test for range errors (not always needed but do it anyway) */
20689
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20690
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20691
      nrange += tp[i] > X_UINT64_MAX ;
20692
    }
20693
   /* copy workspace back if necessary */
20694
    if (realign) {
20695
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20696
      xp = (uint64 *) *xpp;
20697
    }
20698
   /* update xpp and tp */
20699
    xp += ni;
20700
    tp += ni;
20701
    *xpp = (void*)xp;
20702
  }
20703
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20704
20705
#else   /* not SX */
20706
20707
0
  char *xp = (char *) *xpp;
20708
0
  int status = NC_NOERR;
20709
20710
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20711
0
  {
20712
0
    int lstatus = ncx_put_ulonglong_ushort(xp, tp, fillp);
20713
0
    if (status == NC_NOERR) /* report the first encountered error */
20714
0
      status = lstatus;
20715
0
  }
20716
20717
0
  *xpp = (void *)xp;
20718
0
  return status;
20719
0
#endif
20720
0
}
20721
20722
int
20723
ncx_putn_ulonglong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
20724
0
{
20725
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20726
20727
 /* basic algorithm is:
20728
  *   - ensure sane alignment of output data
20729
  *   - copy (conversion happens automatically) input data
20730
  *     to output
20731
  *   - update tp to point at next unconverted input, and xpp to point
20732
  *     at next location for converted output
20733
  */
20734
  long i, j, ni;
20735
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20736
  uint64 *xp;
20737
  int nrange = 0;         /* number of range errors */
20738
  int realign = 0;        /* "do we need to fix input data alignment?" */
20739
  long cxp = (long) *((char**)xpp);
20740
20741
  realign = (cxp & 7) % SIZEOF_UINT64;
20742
  /* sjl: manually stripmine so we can limit amount of
20743
   * vector work space reserved to LOOPCNT elements. Also
20744
   * makes vectorisation easy */
20745
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20746
    ni=Min(nelems-j,LOOPCNT);
20747
    if (realign) {
20748
      xp = tmp;
20749
    } else {
20750
      xp = (uint64 *) *xpp;
20751
    }
20752
   /* copy the next block */
20753
#pragma cdir loopcnt=LOOPCNT
20754
#pragma cdir shortloop
20755
    for (i=0; i<ni; i++) {
20756
      /* the normal case: */
20757
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20758
     /* test for range errors (not always needed but do it anyway) */
20759
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20760
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20761
      nrange += tp[i] > X_UINT64_MAX ;
20762
    }
20763
   /* copy workspace back if necessary */
20764
    if (realign) {
20765
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20766
      xp = (uint64 *) *xpp;
20767
    }
20768
   /* update xpp and tp */
20769
    xp += ni;
20770
    tp += ni;
20771
    *xpp = (void*)xp;
20772
  }
20773
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20774
20775
#else   /* not SX */
20776
20777
0
  char *xp = (char *) *xpp;
20778
0
  int status = NC_NOERR;
20779
20780
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20781
0
  {
20782
0
    int lstatus = ncx_put_ulonglong_uint(xp, tp, fillp);
20783
0
    if (status == NC_NOERR) /* report the first encountered error */
20784
0
      status = lstatus;
20785
0
  }
20786
20787
0
  *xpp = (void *)xp;
20788
0
  return status;
20789
0
#endif
20790
0
}
20791
20792
20793
20794
/*
20795
 * Other aggregate conversion functions.
20796
 */
20797
20798
/* text */
20799
20800
int
20801
ncx_getn_text(const void **xpp, size_t nelems, char *tp)
20802
0
{
20803
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
20804
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20805
0
  return NC_NOERR;
20806
20807
0
}
20808
20809
int
20810
ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
20811
488k
{
20812
488k
  size_t rndup = nelems % X_ALIGN;
20813
20814
488k
  if (rndup)
20815
10.9k
    rndup = X_ALIGN - rndup;
20816
20817
488k
  (void) memcpy(tp, *xpp, (size_t)nelems);
20818
488k
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
20819
20820
488k
  return NC_NOERR;
20821
20822
488k
}
20823
20824
int
20825
ncx_putn_text(void **xpp, size_t nelems, const char *tp)
20826
0
{
20827
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20828
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20829
20830
0
  return NC_NOERR;
20831
20832
0
}
20833
20834
int
20835
ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
20836
0
{
20837
0
  size_t rndup = nelems % X_ALIGN;
20838
20839
0
  if (rndup)
20840
0
    rndup = X_ALIGN - rndup;
20841
20842
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20843
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20844
20845
0
  if (rndup)
20846
0
  {
20847
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
20848
0
    *xpp = (void *)((char *)(*xpp) + rndup);
20849
0
  }
20850
20851
0
  return NC_NOERR;
20852
20853
0
}
20854
20855
20856
/* opaque */
20857
20858
int
20859
ncx_getn_void(const void **xpp, size_t nelems, void *tp)
20860
0
{
20861
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
20862
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20863
0
  return NC_NOERR;
20864
20865
0
}
20866
20867
int
20868
ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
20869
0
{
20870
0
  size_t rndup = nelems % X_ALIGN;
20871
20872
0
  if (rndup)
20873
0
    rndup = X_ALIGN - rndup;
20874
20875
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
20876
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
20877
20878
0
  return NC_NOERR;
20879
20880
0
}
20881
20882
int
20883
ncx_putn_void(void **xpp, size_t nelems, const void *tp)
20884
0
{
20885
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20886
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20887
20888
0
  return NC_NOERR;
20889
20890
0
}
20891
20892
int
20893
ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
20894
0
{
20895
0
  size_t rndup = nelems % X_ALIGN;
20896
20897
0
  if (rndup)
20898
0
    rndup = X_ALIGN - rndup;
20899
20900
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
20901
0
  *xpp = (void *)((char *)(*xpp) + nelems);
20902
20903
0
  if (rndup)
20904
0
  {
20905
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
20906
0
    *xpp = (void *)((char *)(*xpp) + rndup);
20907
0
  }
20908
20909
0
  return NC_NOERR;
20910
20911
0
}