Coverage Report

Created: 2023-05-28 06:42

/src/netcdf-c/build/libsrc/ncx.c
Line
Count
Source (jump to first uncovered line)
1
/* Do not edit this file. It is produced from the corresponding .m4 source */
2
/*
3
 *  Copyright (C) 2014, Northwestern University and Argonne National Laboratory
4
 *  See COPYRIGHT notice in top-level directory.
5
 */
6
/* $Id: ncx.m4 2601 2016-11-07 04:54:42Z wkliao $ */
7
8
#ifdef __GNUC__
9
#pragma GCC diagnostic ignored "-Wunused-parameter"
10
#endif
11
12
13
14
15
16
17
#if HAVE_CONFIG_H
18
#include <config.h>
19
#endif
20
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <limits.h>
25
26
27
#pragma GCC diagnostic ignored "-Wdeprecated"
28
#include "ncx.h"
29
#include "nc3dispatch.h"
30
31
32
33
34
35
#ifdef HAVE_INTTYPES_H
36
#include <inttypes.h> /* uint16_t, uint32_t, uint64_t */
37
#elif defined(HAVE_STDINT_H)
38
#include <stdint.h>   /* uint16_t, uint32_t, uint64_t */
39
#endif
40
41
42
43
/*
44
 * The only error code returned from subroutines in this file is NC_ERANGE,
45
 * if errors are detected.
46
 */
47
48
/*
49
 * An external data representation interface.
50
 */
51
52
/* alias poorly named limits.h macros */
53
0
#define  SHORT_MAX  SHRT_MAX
54
0
#define  SHORT_MIN  SHRT_MIN
55
0
#define USHORT_MAX USHRT_MAX
56
#ifndef LLONG_MAX
57
#   define LLONG_MAX  9223372036854775807LL
58
#   define LLONG_MIN  (-LLONG_MAX - 1LL)
59
#   define ULLONG_MAX 18446744073709551615ULL
60
#endif
61
#ifndef LONG_LONG_MAX
62
0
#define LONG_LONG_MAX LLONG_MAX
63
#endif
64
#ifndef LONGLONG_MAX
65
0
#define LONGLONG_MAX LONG_LONG_MAX
66
#endif
67
#ifndef LONG_LONG_MIN
68
0
#define LONG_LONG_MIN LLONG_MIN
69
#endif
70
#ifndef LONGLONG_MIN
71
0
#define LONGLONG_MIN LONG_LONG_MIN
72
#endif
73
#ifndef ULONG_LONG_MAX
74
0
#define ULONG_LONG_MAX ULLONG_MAX
75
#endif
76
#ifndef ULONGLONG_MAX
77
0
#define ULONGLONG_MAX ULONG_LONG_MAX
78
#endif
79
#include <float.h>
80
#ifndef FLT_MAX /* This POSIX macro missing on some systems */
81
# ifndef NO_IEEE_FLOAT
82
# define FLT_MAX 3.40282347e+38f
83
# else
84
# error "You will need to define FLT_MAX"
85
# endif
86
#endif
87
/* alias poorly named float.h macros */
88
#define FLOAT_MAX FLT_MAX
89
#define FLOAT_MIN (-FLT_MAX)
90
#define DOUBLE_MAX DBL_MAX
91
#define DOUBLE_MIN (-DBL_MAX)
92
#define FLOAT_MAX_EXP FLT_MAX_EXP
93
#define DOUBLE_MAX_EXP DBL_MAX_EXP
94
#include <assert.h>
95
#define UCHAR_MIN 0
96
#define Min(a,b) ((a) < (b) ? (a) : (b))
97
#define Max(a,b) ((a) > (b) ? (a) : (b))
98
99
#ifndef SIZEOF_UCHAR
100
#ifdef  SIZEOF_UNSIGNED_CHAR
101
#define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR
102
#else
103
#error "unknown SIZEOF_UCHAR"
104
#endif
105
#endif
106
107
#ifndef SIZEOF_USHORT
108
#ifdef  SIZEOF_UNSIGNED_SHORT_INT
109
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
110
#elif defined(SIZEOF_UNSIGNED_SHORT)
111
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT
112
#else
113
#error "unknown SIZEOF_USHORT"
114
#endif
115
#endif
116
117
#ifndef SIZEOF_UINT
118
#ifdef  SIZEOF_UNSIGNED_INT
119
#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
120
#else
121
#error "unknown SIZEOF_UINT"
122
#endif
123
#endif
124
125
#ifndef SIZEOF_LONGLONG
126
#ifdef  SIZEOF_LONG_LONG
127
#define SIZEOF_LONGLONG SIZEOF_LONG_LONG
128
#else
129
#error "unknown SIZEOF_LONGLONG"
130
#endif
131
#endif
132
133
#ifndef SIZEOF_INT64
134
#ifdef  SIZEOF_LONG_LONG
135
#define SIZEOF_INT64 SIZEOF_LONG_LONG
136
#elif defined(SIZEOF_LONGLONG)
137
#define SIZEOF_INT64 SIZEOF_LONGLONG
138
#else
139
#error "unknown SIZEOF_INT64"
140
#endif
141
#endif
142
143
#ifndef SIZEOF_ULONGLONG
144
#ifdef  SIZEOF_UNSIGNED_LONG_LONG
145
#define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG
146
#else
147
#error "unknown SIZEOF_ULONGLONG"
148
#endif
149
#endif
150
151
#ifndef SIZEOF_UINT64
152
#ifdef  SIZEOF_UNSIGNED_LONG_LONG
153
#define SIZEOF_UINT64 SIZEOF_UNSIGNED_LONG_LONG
154
#elif defined(SIZEOF_ULONGLONG)
155
#define SIZEOF_UINT64 SIZEOF_ULONGLONG
156
#else
157
#error "unknown SIZEOF_UINT64"
158
#endif
159
#endif
160
161
/*
162
 * If the machine's float domain is "smaller" than the external one
163
 * use the machine domain
164
 */
165
#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */
166
#undef X_FLOAT_MAX
167
# define X_FLOAT_MAX FLT_MAX
168
#undef X_FLOAT_MIN
169
# define X_FLOAT_MIN (-X_FLOAT_MAX)
170
#endif
171
172
#if defined(_SX) && _SX != 0 /* NEC SUPER UX */
173
#define LOOPCNT 256    /* must be no longer than hardware vector length */
174
#if _INT64
175
#undef  INT_MAX /* workaround cpp bug */
176
#define INT_MAX  X_INT_MAX
177
#undef  INT_MIN /* workaround cpp bug */
178
#define INT_MIN  X_INT_MIN
179
#undef  LONG_MAX /* workaround cpp bug */
180
#define LONG_MAX  X_INT_MAX
181
#undef  LONG_MIN /* workaround cpp bug */
182
#define LONG_MIN  X_INT_MIN
183
#elif _LONG64
184
#undef  LONG_MAX /* workaround cpp bug */
185
#define LONG_MAX  4294967295L
186
#undef  LONG_MIN /* workaround cpp bug */
187
#define LONG_MIN -4294967295L
188
#endif
189
#if !_FLOAT0
190
#error "FLOAT1 and FLOAT2 not supported"
191
#endif
192
#endif /* _SX */
193
194
static const char nada[X_ALIGN] = {0, 0, 0, 0};
195
196
#ifndef WORDS_BIGENDIAN
197
/* LITTLE_ENDIAN: DEC and intel */
198
/*
199
 * Routines to convert to BIG ENDIAN.
200
 * Optimize the swapn?b() and swap?b() routines aggressively.
201
 */
202
203
0
#define SWAP2(a) ( (((a) & 0xff) << 8) | \
204
0
                   (((a) >> 8) & 0xff) )
205
206
241k
#define SWAP4(a) ( ((a) << 24) | \
207
241k
                  (((a) <<  8) & 0x00ff0000) | \
208
241k
                  (((a) >>  8) & 0x0000ff00) | \
209
241k
                  (((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
    for (i=0; i<nn; i++) {
232
0
        op[i] = ip[i];
233
0
        op[i] = (uint16_t)SWAP2(op[i]);
234
0
    }
235
#if 0
236
  char *op = dst;
237
  const char *ip = src;
238
239
/* unroll the following to reduce loop overhead
240
 *
241
 *  while (nn-- > 0)
242
 *  {
243
 *    *op++ = *(++ip);
244
 *    *op++ = *(ip++ -1);
245
 *  }
246
 */
247
  while (nn > 3)
248
  {
249
    *op++ = *(++ip);
250
    *op++ = *(ip++ -1);
251
    *op++ = *(++ip);
252
    *op++ = *(ip++ -1);
253
    *op++ = *(++ip);
254
    *op++ = *(ip++ -1);
255
    *op++ = *(++ip);
256
    *op++ = *(ip++ -1);
257
    nn -= 4;
258
  }
259
  while (nn-- > 0)
260
  {
261
    *op++ = *(++ip);
262
    *op++ = *(ip++ -1);
263
  }
264
#endif
265
0
}
266
267
# ifndef vax
268
inline static void
269
swap4b(void *dst, const void *src)
270
0
{
271
    /* copy over, make the below swap in-place */
272
0
    uint32_t tmp;
273
    /* use memcpy to avoid type punning */
274
0
    memcpy(&tmp, src, sizeof(tmp));
275
0
    tmp = SWAP4(tmp);
276
0
    memcpy(dst, &tmp, 4);
277
278
    /* Codes below will cause "break strict-aliasing rules" in gcc
279
    uint32_t *op = (uint32_t*)dst;
280
    *op = *(uint32_t*)src;
281
    *op = SWAP4(*op);
282
    */
283
284
    /* Below are copied from netCDF-4.
285
     * See https://bugtracking.unidata.ucar.edu/browse/NCF-338
286
     * Quote "One issue we are wrestling with is how compilers optimize this
287
     * code.  For some reason, we are actually needing to add an artificial
288
     * move to a 4 byte space to get it to work.  I think what is happening is
289
     * that the optimizer is bit shifting within a double, which is incorrect.
290
     * The following code actually does work correctly.
291
     *  This is in Linux land, gcc.
292
     *
293
     * However, the above in-place byte-swap does not appear affected by this.
294
     */
295
#if 0
296
    uint32_t *ip = (uint32_t*)src;
297
    uint32_t tempOut;  /* cannot use pointer when gcc O2 optimizer is used */
298
    tempOut = SWAP4(*ip);
299
300
    *(float *)dst = *(float *)(&tempOut);
301
#endif
302
303
    /* OLD implementation that results in four load and four store CPU
304
       instructions
305
    char *op = dst;
306
    const char *ip = src;
307
    op[0] = ip[3];
308
    op[1] = ip[2];
309
    op[2] = ip[1];
310
    op[3] = ip[0];
311
    */
312
313
0
}
314
# endif /* !vax */
315
316
inline static void
317
swapn4b(void *dst, const void *src, size_t nn)
318
41.5k
{
319
41.5k
    size_t i;
320
41.5k
    uint32_t *op = (uint32_t*) dst;
321
41.5k
    uint32_t *ip = (uint32_t*) src;
322
283k
    for (i=0; i<nn; i++) {
323
        /* copy over, make the below swap in-place */
324
241k
        op[i] = ip[i];
325
241k
        op[i] = SWAP4(op[i]);
326
241k
    }
327
328
#if 0
329
  char *op = dst;
330
  const char *ip = src;
331
332
/* unroll the following to reduce loop overhead
333
 *  while (nn-- > 0)
334
 *  {
335
 *    op[0] = ip[3];
336
 *    op[1] = ip[2];
337
 *    op[2] = ip[1];
338
 *    op[3] = ip[0];
339
 *    op += 4;
340
 *    ip += 4;
341
 *  }
342
 */
343
  while (nn > 3)
344
  {
345
    op[0] = ip[3];
346
    op[1] = ip[2];
347
    op[2] = ip[1];
348
    op[3] = ip[0];
349
    op[4] = ip[7];
350
    op[5] = ip[6];
351
    op[6] = ip[5];
352
    op[7] = ip[4];
353
    op[8] = ip[11];
354
    op[9] = ip[10];
355
    op[10] = ip[9];
356
    op[11] = ip[8];
357
    op[12] = ip[15];
358
    op[13] = ip[14];
359
    op[14] = ip[13];
360
    op[15] = ip[12];
361
    op += 16;
362
    ip += 16;
363
    nn -= 4;
364
  }
365
  while (nn-- > 0)
366
  {
367
    op[0] = ip[3];
368
    op[1] = ip[2];
369
    op[2] = ip[1];
370
    op[3] = ip[0];
371
    op += 4;
372
    ip += 4;
373
  }
374
#endif
375
41.5k
}
376
377
# ifndef vax
378
inline static void
379
swap8b(void *dst, const void *src)
380
0
{
381
#ifdef FLOAT_WORDS_BIGENDIAN
382
    /* copy over, make the below swap in-place */
383
    *(uint64_t*)dst = *(uint64_t*)src;
384
385
    uint32_t *op = (uint32_t*)dst;
386
    *op = SWAP4(*op);
387
    op = (uint32_t*)((char*)dst+4);
388
    *op = SWAP4(*op);
389
#else
390
0
    uint64_t tmp;
391
    /* use memcpy to avoid type punning */
392
0
    memcpy(&tmp, src, sizeof(tmp));
393
0
    tmp = SWAP8(tmp);
394
0
    memcpy(dst, &tmp, 8);
395
396
    /* Codes below will cause "break strict-aliasing rules" in gcc
397
    uint64_t *op = (uint64_t*)dst;
398
    *op = *(uint64_t*)src;
399
    *op = SWAP8(*op);
400
    */
401
0
#endif
402
403
#if 0
404
  char *op = dst;
405
  const char *ip = src;
406
#  ifndef FLOAT_WORDS_BIGENDIAN
407
  op[0] = ip[7];
408
  op[1] = ip[6];
409
  op[2] = ip[5];
410
  op[3] = ip[4];
411
  op[4] = ip[3];
412
  op[5] = ip[2];
413
  op[6] = ip[1];
414
  op[7] = ip[0];
415
#  else
416
  op[0] = ip[3];
417
  op[1] = ip[2];
418
  op[2] = ip[1];
419
  op[3] = ip[0];
420
  op[4] = ip[7];
421
  op[5] = ip[6];
422
  op[6] = ip[5];
423
  op[7] = ip[4];
424
#endif
425
#endif
426
0
}
427
# endif /* !vax */
428
429
# ifndef vax
430
inline static void
431
swapn8b(void *dst, const void *src, size_t nn)
432
0
{
433
#ifdef FLOAT_WORDS_BIGENDIAN
434
    size_t i;
435
    uint64_t *dst_p = (uint64_t*) dst;
436
    uint64_t *src_p = (uint64_t*) src;
437
    for (i=0; i<nn; i++) {
438
        /* copy over, make the below swap in-place */
439
        dst_p[i] = src_p[i];
440
        uint32_t *op = (uint32_t*)(&dst_p[i]);
441
        *op = SWAP4(*op);
442
        op = (uint32_t*)((char*)op+4);
443
        *op = SWAP4(*op);
444
    }
445
#else
446
0
    size_t i;
447
0
    uint64_t *op = (uint64_t*) dst;
448
0
    uint64_t *ip = (uint64_t*) src;
449
0
    for (i=0; i<nn; i++) {
450
        /* copy over, make the below swap in-place */
451
0
        op[i] = ip[i];
452
0
        op[i] = SWAP8(op[i]);
453
0
    }
454
0
#endif
455
456
#if 0
457
  char *op = dst;
458
  const char *ip = src;
459
460
/* unroll the following to reduce loop overhead
461
 *  while (nn-- > 0)
462
 *  {
463
 *    op[0] = ip[7];
464
 *    op[1] = ip[6];
465
 *    op[2] = ip[5];
466
 *    op[3] = ip[4];
467
 *    op[4] = ip[3];
468
 *    op[5] = ip[2];
469
 *    op[6] = ip[1];
470
 *    op[7] = ip[0];
471
 *    op += 8;
472
 *    ip += 8;
473
 *  }
474
 */
475
#  ifndef FLOAT_WORDS_BIGENDIAN
476
  while (nn > 1)
477
  {
478
    op[0] = ip[7];
479
    op[1] = ip[6];
480
    op[2] = ip[5];
481
    op[3] = ip[4];
482
    op[4] = ip[3];
483
    op[5] = ip[2];
484
    op[6] = ip[1];
485
    op[7] = ip[0];
486
    op[8] = ip[15];
487
    op[9] = ip[14];
488
    op[10] = ip[13];
489
    op[11] = ip[12];
490
    op[12] = ip[11];
491
    op[13] = ip[10];
492
    op[14] = ip[9];
493
    op[15] = ip[8];
494
    op += 16;
495
    ip += 16;
496
    nn -= 2;
497
  }
498
  while (nn-- > 0)
499
  {
500
    op[0] = ip[7];
501
    op[1] = ip[6];
502
    op[2] = ip[5];
503
    op[3] = ip[4];
504
    op[4] = ip[3];
505
    op[5] = ip[2];
506
    op[6] = ip[1];
507
    op[7] = ip[0];
508
    op += 8;
509
    ip += 8;
510
  }
511
#  else
512
  while (nn-- > 0)
513
  {
514
    op[0] = ip[3];
515
    op[1] = ip[2];
516
    op[2] = ip[1];
517
    op[3] = ip[0];
518
    op[4] = ip[7];
519
    op[5] = ip[6];
520
    op[6] = ip[5];
521
    op[7] = ip[4];
522
    op += 8;
523
    ip += 8;
524
  }
525
#endif
526
#endif
527
0
}
528
# endif /* !vax */
529
530
#endif /* LITTLE_ENDIAN */
531
532
533
534
535
536
537
/*
538
 * Primitive numeric conversion functions.
539
 */
540
541
542
543
544
545
/* x_schar */
546
/* x_uchar */
547
548
/* We don't implement any x_schar and x_uchar primitives. */
549
550
551
/* external NC_SHORT --------------------------------------------------------*/
552
553
#if SHORT_MAX == X_SHORT_MAX
554
typedef short ix_short;
555
#define SIZEOF_IX_SHORT SIZEOF_SHORT
556
0
#define IX_SHORT_MAX SHORT_MAX
557
#elif INT_MAX >= X_SHORT_MAX
558
typedef int ix_short;
559
#define SIZEOF_IX_SHORT SIZEOF_INT
560
#define IX_SHORT_MAX INT_MAX
561
#elif LONG_MAX >= X_SHORT_MAX
562
typedef long ix_short;
563
#define SIZEOF_IX_SHORT SIZEOF_LONG
564
#define IX_SHORT_MAX LONG_MAX
565
#elif LLONG_MAX >= X_SHORT_MAX
566
typedef long long ix_short;
567
#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
568
#define IX_SHORT_MAX LLONG_MAX
569
#else
570
#error "ix_short implementation"
571
#endif
572
573
static void
574
get_ix_short(const void *xp, ix_short *ip)
575
0
{
576
0
  const uchar *cp = (const uchar *) xp;
577
0
  *ip = (ix_short)(*cp++ << 8);
578
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
579
  if (*ip & 0x8000)
580
  {
581
    /* extern is negative */
582
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
583
  }
584
#endif
585
0
  *ip = (ix_short)(*ip | *cp);
586
0
}
587
588
static void
589
put_ix_short(void *xp, const ix_short *ip)
590
0
{
591
0
  uchar *cp = (uchar *) xp;
592
0
  *cp++ = (uchar)((*ip) >> 8);
593
0
  *cp   = (uchar)((*ip) & 0xff);
594
0
}
595
596
static int
597
ncx_get_short_schar(const void *xp, schar *ip)
598
0
{
599
0
    int err=NC_NOERR;
600
0
    ix_short xx = 0;
601
0
    get_ix_short(xp, &xx);
602
603
0
#if IX_SHORT_MAX > SCHAR_MAX
604
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
605
#ifdef ERANGE_FILL
606
        *ip = NC_FILL_BYTE;
607
        return NC_ERANGE;
608
#else
609
0
        err = NC_ERANGE;
610
0
#endif
611
0
    }
612
0
#endif
613
614
615
0
    *ip = (schar) xx;
616
0
    return err;
617
0
}
618
619
static int
620
ncx_get_short_short(const void *xp, short *ip)
621
0
{
622
0
    int err=NC_NOERR;
623
0
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
624
0
    get_ix_short(xp, (ix_short *)ip);
625
#else
626
    ix_short xx = 0;
627
    get_ix_short(xp, &xx);
628
629
#if IX_SHORT_MAX > SHORT_MAX
630
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
631
#ifdef ERANGE_FILL
632
        *ip = NC_FILL_SHORT;
633
        return NC_ERANGE;
634
#else
635
        err = NC_ERANGE;
636
#endif
637
    }
638
#endif
639
640
641
    *ip = (short) xx;
642
#endif
643
0
    return err;
644
0
}
645
646
static int
647
ncx_get_short_int(const void *xp, int *ip)
648
0
{
649
0
    int err=NC_NOERR;
650
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
651
    get_ix_short(xp, (ix_short *)ip);
652
#else
653
0
    ix_short xx = 0;
654
0
    get_ix_short(xp, &xx);
655
656
#if IX_SHORT_MAX > INT_MAX
657
    if (xx > INT_MAX || xx < INT_MIN) {
658
#ifdef ERANGE_FILL
659
        *ip = NC_FILL_INT;
660
        return NC_ERANGE;
661
#else
662
        err = NC_ERANGE;
663
#endif
664
    }
665
#endif
666
667
668
0
    *ip = (int) xx;
669
0
#endif
670
0
    return err;
671
0
}
672
673
static int
674
ncx_get_short_long(const void *xp, long *ip)
675
0
{
676
0
    int err=NC_NOERR;
677
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
678
    get_ix_short(xp, (ix_short *)ip);
679
#else
680
0
    ix_short xx = 0;
681
0
    get_ix_short(xp, &xx);
682
683
#if IX_SHORT_MAX > LONG_MAX
684
    if (xx > LONG_MAX || xx < LONG_MIN) {
685
#ifdef ERANGE_FILL
686
        *ip = NC_FILL_INT;
687
        return NC_ERANGE;
688
#else
689
        err = NC_ERANGE;
690
#endif
691
    }
692
#endif
693
694
695
0
    *ip = (long) xx;
696
0
#endif
697
0
    return err;
698
0
}
699
700
static int
701
ncx_get_short_longlong(const void *xp, longlong *ip)
702
0
{
703
0
    int err=NC_NOERR;
704
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
705
    get_ix_short(xp, (ix_short *)ip);
706
#else
707
0
    ix_short xx = 0;
708
0
    get_ix_short(xp, &xx);
709
710
#if IX_SHORT_MAX > LONGLONG_MAX
711
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
712
#ifdef ERANGE_FILL
713
        *ip = NC_FILL_INT64;
714
        return NC_ERANGE;
715
#else
716
        err = NC_ERANGE;
717
#endif
718
    }
719
#endif
720
721
722
0
    *ip = (longlong) xx;
723
0
#endif
724
0
    return err;
725
0
}
726
727
static int
728
ncx_get_short_ushort(const void *xp, ushort *ip)
729
0
{
730
0
    int err=NC_NOERR;
731
0
    ix_short xx = 0;
732
0
    get_ix_short(xp, &xx);
733
734
#if IX_SHORT_MAX > USHORT_MAX
735
    if (xx > USHORT_MAX) {
736
#ifdef ERANGE_FILL
737
        *ip = NC_FILL_USHORT;
738
        return NC_ERANGE;
739
#else
740
        err = NC_ERANGE;
741
#endif
742
    }
743
#endif
744
745
0
    if (xx < 0) {
746
#ifdef ERANGE_FILL
747
        *ip = NC_FILL_USHORT;
748
        return NC_ERANGE;
749
#else
750
0
        err = NC_ERANGE; /* because ip is unsigned */
751
0
#endif
752
0
    }
753
0
    *ip = (ushort) xx;
754
0
    return err;
755
0
}
756
757
static int
758
ncx_get_short_uchar(const void *xp, uchar *ip)
759
0
{
760
0
    int err=NC_NOERR;
761
0
    ix_short xx = 0;
762
0
    get_ix_short(xp, &xx);
763
764
0
#if IX_SHORT_MAX > UCHAR_MAX
765
0
    if (xx > UCHAR_MAX) {
766
#ifdef ERANGE_FILL
767
        *ip = NC_FILL_UBYTE;
768
        return NC_ERANGE;
769
#else
770
0
        err = NC_ERANGE;
771
0
#endif
772
0
    }
773
0
#endif
774
775
0
    if (xx < 0) {
776
#ifdef ERANGE_FILL
777
        *ip = NC_FILL_UBYTE;
778
        return NC_ERANGE;
779
#else
780
0
        err = NC_ERANGE; /* because ip is unsigned */
781
0
#endif
782
0
    }
783
0
    *ip = (uchar) xx;
784
0
    return err;
785
0
}
786
787
static int
788
ncx_get_short_uint(const void *xp, uint *ip)
789
0
{
790
0
    int err=NC_NOERR;
791
0
    ix_short xx = 0;
792
0
    get_ix_short(xp, &xx);
793
794
#if IX_SHORT_MAX > UINT_MAX
795
    if (xx > UINT_MAX) {
796
#ifdef ERANGE_FILL
797
        *ip = NC_FILL_UINT;
798
        return NC_ERANGE;
799
#else
800
        err = NC_ERANGE;
801
#endif
802
    }
803
#endif
804
805
0
    if (xx < 0) {
806
#ifdef ERANGE_FILL
807
        *ip = NC_FILL_UINT;
808
        return NC_ERANGE;
809
#else
810
0
        err = NC_ERANGE; /* because ip is unsigned */
811
0
#endif
812
0
    }
813
0
    *ip = (uint) xx;
814
0
    return err;
815
0
}
816
817
static int
818
ncx_get_short_ulonglong(const void *xp, ulonglong *ip)
819
0
{
820
0
    int err=NC_NOERR;
821
0
    ix_short xx = 0;
822
0
    get_ix_short(xp, &xx);
823
824
#if IX_SHORT_MAX > ULONGLONG_MAX
825
    if (xx > ULONGLONG_MAX) {
826
#ifdef ERANGE_FILL
827
        *ip = NC_FILL_UINT64;
828
        return NC_ERANGE;
829
#else
830
        err = NC_ERANGE;
831
#endif
832
    }
833
#endif
834
835
0
    if (xx < 0) {
836
#ifdef ERANGE_FILL
837
        *ip = NC_FILL_UINT64;
838
        return NC_ERANGE;
839
#else
840
0
        err = NC_ERANGE; /* because ip is unsigned */
841
0
#endif
842
0
    }
843
0
    *ip = (ulonglong) xx;
844
0
    return err;
845
0
}
846
847
static int
848
ncx_get_short_float(const void *xp, float *ip)
849
0
{
850
0
  ix_short xx = 0;
851
0
  get_ix_short(xp, &xx);
852
0
  *ip = (float)xx;
853
0
  return NC_NOERR;
854
0
}
855
856
static int
857
ncx_get_short_double(const void *xp, double *ip)
858
0
{
859
0
  ix_short xx = 0;
860
0
  get_ix_short(xp, &xx);
861
0
  *ip = (double)xx;
862
0
  return NC_NOERR;
863
0
}
864
865
866
static int
867
ncx_put_short_schar(void *xp, const schar *ip, void *fillp)
868
0
{
869
0
  uchar *cp = (uchar *) xp;
870
0
  if (*ip & 0x80)
871
0
    *cp++ = 0xff;
872
0
  else
873
0
    *cp++ = 0;
874
0
  *cp = (uchar)*ip;
875
0
  return NC_NOERR;
876
0
}
877
878
static int
879
ncx_put_short_uchar(void *xp, const uchar *ip, void *fillp)
880
0
{
881
0
  uchar *cp = (uchar *) xp;
882
0
  *cp++ = 0;
883
0
  *cp = *ip;
884
0
  return NC_NOERR;
885
0
}
886
887
static int
888
ncx_put_short_short(void *xp, const short *ip, void *fillp)
889
0
{
890
0
    int err=NC_NOERR;
891
0
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
892
0
    put_ix_short(xp, (const ix_short *)ip);
893
#else
894
    ix_short xx = NC_FILL_SHORT;
895
896
#if IX_SHORT_MAX < SHORT_MAX
897
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
898
        
899
#ifdef ERANGE_FILL
900
            if (fillp != NULL) memcpy(&xx, fillp, 2);
901
#endif
902
        err = NC_ERANGE;
903
    }
904
#ifdef ERANGE_FILL
905
    else
906
#endif
907
#endif
908
        xx = (ix_short)*ip;
909
910
    put_ix_short(xp, &xx);
911
#endif
912
0
    return err;
913
0
}
914
915
static int
916
ncx_put_short_int(void *xp, const int *ip, void *fillp)
917
0
{
918
0
    int err=NC_NOERR;
919
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
920
    put_ix_short(xp, (const ix_short *)ip);
921
#else
922
0
    ix_short xx = NC_FILL_SHORT;
923
924
0
#if IX_SHORT_MAX < INT_MAX
925
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
926
        
927
#ifdef ERANGE_FILL
928
            if (fillp != NULL) memcpy(&xx, fillp, 2);
929
#endif
930
0
        err = NC_ERANGE;
931
0
    }
932
#ifdef ERANGE_FILL
933
    else
934
#endif
935
0
#endif
936
0
        xx = (ix_short)*ip;
937
938
0
    put_ix_short(xp, &xx);
939
0
#endif
940
0
    return err;
941
0
}
942
943
static int
944
ncx_put_short_long(void *xp, const long *ip, void *fillp)
945
0
{
946
0
    int err=NC_NOERR;
947
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
948
    put_ix_short(xp, (const ix_short *)ip);
949
#else
950
0
    ix_short xx = NC_FILL_SHORT;
951
952
0
#if IX_SHORT_MAX < LONG_MAX
953
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
954
        
955
#ifdef ERANGE_FILL
956
            if (fillp != NULL) memcpy(&xx, fillp, 2);
957
#endif
958
0
        err = NC_ERANGE;
959
0
    }
960
#ifdef ERANGE_FILL
961
    else
962
#endif
963
0
#endif
964
0
        xx = (ix_short)*ip;
965
966
0
    put_ix_short(xp, &xx);
967
0
#endif
968
0
    return err;
969
0
}
970
971
static int
972
ncx_put_short_longlong(void *xp, const longlong *ip, void *fillp)
973
0
{
974
0
    int err=NC_NOERR;
975
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
976
    put_ix_short(xp, (const ix_short *)ip);
977
#else
978
0
    ix_short xx = NC_FILL_SHORT;
979
980
0
#if IX_SHORT_MAX < LONGLONG_MAX
981
0
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
982
        
983
#ifdef ERANGE_FILL
984
            if (fillp != NULL) memcpy(&xx, fillp, 2);
985
#endif
986
0
        err = NC_ERANGE;
987
0
    }
988
#ifdef ERANGE_FILL
989
    else
990
#endif
991
0
#endif
992
0
        xx = (ix_short)*ip;
993
994
0
    put_ix_short(xp, &xx);
995
0
#endif
996
0
    return err;
997
0
}
998
999
static int
1000
ncx_put_short_ushort(void *xp, const ushort *ip, void *fillp)
1001
0
{
1002
0
    int err=NC_NOERR;
1003
0
    ix_short xx = NC_FILL_SHORT;
1004
1005
0
#if IX_SHORT_MAX < USHORT_MAX
1006
0
    if (*ip > IX_SHORT_MAX) {
1007
        
1008
#ifdef ERANGE_FILL
1009
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1010
#endif
1011
0
        err = NC_ERANGE;
1012
0
    }
1013
#ifdef ERANGE_FILL
1014
    else
1015
#endif
1016
0
#endif
1017
0
        xx = (ix_short)*ip;
1018
1019
0
    put_ix_short(xp, &xx);
1020
0
    return err;
1021
0
}
1022
1023
static int
1024
ncx_put_short_uint(void *xp, const uint *ip, void *fillp)
1025
0
{
1026
0
    int err=NC_NOERR;
1027
0
    ix_short xx = NC_FILL_SHORT;
1028
1029
0
#if IX_SHORT_MAX < UINT_MAX
1030
0
    if (*ip > IX_SHORT_MAX) {
1031
        
1032
#ifdef ERANGE_FILL
1033
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1034
#endif
1035
0
        err = NC_ERANGE;
1036
0
    }
1037
#ifdef ERANGE_FILL
1038
    else
1039
#endif
1040
0
#endif
1041
0
        xx = (ix_short)*ip;
1042
1043
0
    put_ix_short(xp, &xx);
1044
0
    return err;
1045
0
}
1046
1047
static int
1048
ncx_put_short_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1049
0
{
1050
0
    int err=NC_NOERR;
1051
0
    ix_short xx = NC_FILL_SHORT;
1052
1053
0
#if IX_SHORT_MAX < ULONGLONG_MAX
1054
0
    if (*ip > IX_SHORT_MAX) {
1055
        
1056
#ifdef ERANGE_FILL
1057
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1058
#endif
1059
0
        err = NC_ERANGE;
1060
0
    }
1061
#ifdef ERANGE_FILL
1062
    else
1063
#endif
1064
0
#endif
1065
0
        xx = (ix_short)*ip;
1066
1067
0
    put_ix_short(xp, &xx);
1068
0
    return err;
1069
0
}
1070
1071
static int
1072
ncx_put_short_float(void *xp, const float *ip, void *fillp)
1073
0
{
1074
0
    int err=NC_NOERR;
1075
0
    ix_short xx = NC_FILL_SHORT;
1076
1077
0
    if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
1078
        
1079
#ifdef ERANGE_FILL
1080
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1081
#endif
1082
0
        err = NC_ERANGE;
1083
0
    }
1084
#ifdef ERANGE_FILL
1085
    else
1086
#endif
1087
0
        xx = (ix_short)*ip;
1088
1089
0
    put_ix_short(xp, &xx);
1090
0
    return err;
1091
0
}
1092
1093
static int
1094
ncx_put_short_double(void *xp, const double *ip, void *fillp)
1095
0
{
1096
0
    int err=NC_NOERR;
1097
0
    ix_short xx = NC_FILL_SHORT;
1098
1099
0
    if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) {
1100
        
1101
#ifdef ERANGE_FILL
1102
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1103
#endif
1104
0
        err = NC_ERANGE;
1105
0
    }
1106
#ifdef ERANGE_FILL
1107
    else
1108
#endif
1109
0
        xx = (ix_short)*ip;
1110
1111
0
    put_ix_short(xp, &xx);
1112
0
    return err;
1113
0
}
1114
1115
1116
/* external NC_USHORT -------------------------------------------------------*/
1117
1118
#if USHORT_MAX == X_USHORT_MAX
1119
typedef unsigned short ix_ushort;
1120
#define SIZEOF_IX_USHORT SIZEOF_USHORT
1121
0
#define IX_USHORT_MAX USHORT_MAX
1122
#elif UINT_MAX >= X_USHORT_MAX
1123
typedef unsigned int ix_ushort;
1124
#define SIZEOF_IX_USHORT SIZEOF_UINT
1125
#define IX_USHORT_MAX UINT_MAX
1126
#elif ULONG_MAX >= X_USHORT_MAX
1127
typedef unsigned long ix_ushort;
1128
#define SIZEOF_IX_USHORT SIZEOF_ULONG
1129
#define IX_USHORT_MAX ULONG_MAX
1130
#elif ULLONG_MAX >= X_USHORT_MAX
1131
typedef unsigned long long ix_ushort;
1132
#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
1133
#define IX_USHORT_MAX ULLONG_MAX
1134
#else
1135
#error "ix_ushort implementation"
1136
#endif
1137
1138
static void
1139
get_ix_ushort(const void *xp, ix_ushort *ip)
1140
0
{
1141
0
  const uchar *cp = (const uchar *) xp;
1142
0
  *ip = (ix_ushort)(*cp++ << 8);
1143
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
1144
  if (*ip & 0x8000)
1145
  {
1146
    /* extern is negative */
1147
    *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
1148
  }
1149
#endif
1150
0
  *ip = (ix_ushort)(*ip | *cp);
1151
0
}
1152
1153
static void
1154
put_ix_ushort(void *xp, const ix_ushort *ip)
1155
0
{
1156
0
  uchar *cp = (uchar *) xp;
1157
0
  *cp++ = (uchar)((*ip) >> 8);
1158
0
  *cp   = (uchar)((*ip) & 0xff);
1159
0
}
1160
1161
static int
1162
ncx_get_ushort_schar(const void *xp, schar *ip)
1163
0
{
1164
0
    int err=NC_NOERR;
1165
0
    ix_ushort xx = 0;
1166
0
    get_ix_ushort(xp, &xx);
1167
1168
0
#if IX_USHORT_MAX > SCHAR_MAX
1169
0
    if (xx > SCHAR_MAX) {
1170
#ifdef ERANGE_FILL
1171
        *ip = NC_FILL_BYTE;
1172
        return NC_ERANGE;
1173
#else
1174
0
        err = NC_ERANGE;
1175
0
#endif
1176
0
    }
1177
0
#endif
1178
1179
1180
0
    *ip = (schar) xx;
1181
0
    return err;
1182
0
}
1183
1184
static int
1185
ncx_get_ushort_short(const void *xp, short *ip)
1186
0
{
1187
0
    int err=NC_NOERR;
1188
0
    ix_ushort xx = 0;
1189
0
    get_ix_ushort(xp, &xx);
1190
1191
0
#if IX_USHORT_MAX > SHORT_MAX
1192
0
    if (xx > SHORT_MAX) {
1193
#ifdef ERANGE_FILL
1194
        *ip = NC_FILL_SHORT;
1195
        return NC_ERANGE;
1196
#else
1197
0
        err = NC_ERANGE;
1198
0
#endif
1199
0
    }
1200
0
#endif
1201
1202
1203
0
    *ip = (short) xx;
1204
0
    return err;
1205
0
}
1206
1207
static int
1208
ncx_get_ushort_int(const void *xp, int *ip)
1209
0
{
1210
0
    int err=NC_NOERR;
1211
0
    ix_ushort xx = 0;
1212
0
    get_ix_ushort(xp, &xx);
1213
1214
#if IX_USHORT_MAX > INT_MAX
1215
    if (xx > INT_MAX) {
1216
#ifdef ERANGE_FILL
1217
        *ip = NC_FILL_INT;
1218
        return NC_ERANGE;
1219
#else
1220
        err = NC_ERANGE;
1221
#endif
1222
    }
1223
#endif
1224
1225
1226
0
    *ip = (int) xx;
1227
0
    return err;
1228
0
}
1229
1230
static int
1231
ncx_get_ushort_long(const void *xp, long *ip)
1232
0
{
1233
0
    int err=NC_NOERR;
1234
0
    ix_ushort xx = 0;
1235
0
    get_ix_ushort(xp, &xx);
1236
1237
#if IX_USHORT_MAX > LONG_MAX
1238
    if (xx > LONG_MAX) {
1239
#ifdef ERANGE_FILL
1240
        *ip = NC_FILL_INT;
1241
        return NC_ERANGE;
1242
#else
1243
        err = NC_ERANGE;
1244
#endif
1245
    }
1246
#endif
1247
1248
1249
0
    *ip = (long) xx;
1250
0
    return err;
1251
0
}
1252
1253
static int
1254
ncx_get_ushort_longlong(const void *xp, longlong *ip)
1255
0
{
1256
0
    int err=NC_NOERR;
1257
0
    ix_ushort xx = 0;
1258
0
    get_ix_ushort(xp, &xx);
1259
1260
#if IX_USHORT_MAX > LONGLONG_MAX
1261
    if (xx > LONGLONG_MAX) {
1262
#ifdef ERANGE_FILL
1263
        *ip = NC_FILL_INT64;
1264
        return NC_ERANGE;
1265
#else
1266
        err = NC_ERANGE;
1267
#endif
1268
    }
1269
#endif
1270
1271
1272
0
    *ip = (longlong) xx;
1273
0
    return err;
1274
0
}
1275
1276
static int
1277
ncx_get_ushort_ushort(const void *xp, ushort *ip)
1278
0
{
1279
0
    int err=NC_NOERR;
1280
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1281
0
    get_ix_ushort(xp, (ix_ushort *)ip);
1282
#else
1283
    ix_ushort xx = 0;
1284
    get_ix_ushort(xp, &xx);
1285
1286
#if IX_USHORT_MAX > USHORT_MAX
1287
    if (xx > USHORT_MAX) {
1288
#ifdef ERANGE_FILL
1289
        *ip = NC_FILL_USHORT;
1290
        return NC_ERANGE;
1291
#else
1292
        err = NC_ERANGE;
1293
#endif
1294
    }
1295
#endif
1296
1297
1298
    *ip = (ushort) xx;
1299
#endif
1300
0
    return err;
1301
0
}
1302
1303
static int
1304
ncx_get_ushort_uchar(const void *xp, uchar *ip)
1305
0
{
1306
0
    int err=NC_NOERR;
1307
#if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
1308
    get_ix_ushort(xp, (ix_ushort *)ip);
1309
#else
1310
0
    ix_ushort xx = 0;
1311
0
    get_ix_ushort(xp, &xx);
1312
1313
0
#if IX_USHORT_MAX > UCHAR_MAX
1314
0
    if (xx > UCHAR_MAX) {
1315
#ifdef ERANGE_FILL
1316
        *ip = NC_FILL_UBYTE;
1317
        return NC_ERANGE;
1318
#else
1319
0
        err = NC_ERANGE;
1320
0
#endif
1321
0
    }
1322
0
#endif
1323
1324
1325
0
    *ip = (uchar) xx;
1326
0
#endif
1327
0
    return err;
1328
0
}
1329
1330
static int
1331
ncx_get_ushort_uint(const void *xp, uint *ip)
1332
0
{
1333
0
    int err=NC_NOERR;
1334
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1335
    get_ix_ushort(xp, (ix_ushort *)ip);
1336
#else
1337
0
    ix_ushort xx = 0;
1338
0
    get_ix_ushort(xp, &xx);
1339
1340
#if IX_USHORT_MAX > UINT_MAX
1341
    if (xx > UINT_MAX) {
1342
#ifdef ERANGE_FILL
1343
        *ip = NC_FILL_UINT;
1344
        return NC_ERANGE;
1345
#else
1346
        err = NC_ERANGE;
1347
#endif
1348
    }
1349
#endif
1350
1351
1352
0
    *ip = (uint) xx;
1353
0
#endif
1354
0
    return err;
1355
0
}
1356
1357
static int
1358
ncx_get_ushort_ulonglong(const void *xp, ulonglong *ip)
1359
0
{
1360
0
    int err=NC_NOERR;
1361
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1362
    get_ix_ushort(xp, (ix_ushort *)ip);
1363
#else
1364
0
    ix_ushort xx = 0;
1365
0
    get_ix_ushort(xp, &xx);
1366
1367
#if IX_USHORT_MAX > ULONGLONG_MAX
1368
    if (xx > ULONGLONG_MAX) {
1369
#ifdef ERANGE_FILL
1370
        *ip = NC_FILL_UINT64;
1371
        return NC_ERANGE;
1372
#else
1373
        err = NC_ERANGE;
1374
#endif
1375
    }
1376
#endif
1377
1378
1379
0
    *ip = (ulonglong) xx;
1380
0
#endif
1381
0
    return err;
1382
0
}
1383
1384
static int
1385
ncx_get_ushort_float(const void *xp, float *ip)
1386
0
{
1387
0
  ix_ushort xx = 0;
1388
0
  get_ix_ushort(xp, &xx);
1389
0
  *ip = (float)xx;
1390
0
  return NC_NOERR;
1391
0
}
1392
1393
static int
1394
ncx_get_ushort_double(const void *xp, double *ip)
1395
0
{
1396
0
  ix_ushort xx = 0;
1397
0
  get_ix_ushort(xp, &xx);
1398
0
  *ip = (double)xx;
1399
0
  return NC_NOERR;
1400
0
}
1401
1402
1403
static int
1404
ncx_put_ushort_schar(void *xp, const schar *ip, void *fillp)
1405
0
{
1406
0
    int err=NC_NOERR;
1407
0
    uchar *cp;
1408
0
    if (*ip < 0) {
1409
#ifdef ERANGE_FILL
1410
        if (fillp != NULL) memcpy(xp, fillp, 2);
1411
#ifndef WORDS_BIGENDIAN
1412
        swapn2b(xp, xp, 1);
1413
#endif
1414
        return NC_ERANGE;
1415
#else
1416
0
        err = NC_ERANGE;
1417
0
#endif
1418
0
    }
1419
1420
0
    cp = (uchar *) xp;
1421
0
    if (*ip & 0x80)
1422
0
        *cp++ = 0xff;
1423
0
    else
1424
0
        *cp++ = 0;
1425
0
    *cp = (uchar)*ip;
1426
1427
0
    return err;
1428
0
}
1429
1430
static int
1431
ncx_put_ushort_uchar(void *xp, const uchar *ip, void *fillp)
1432
0
{
1433
0
  uchar *cp = (uchar *) xp;
1434
0
  *cp++ = 0;
1435
0
  *cp = *ip;
1436
0
  return NC_NOERR;
1437
0
}
1438
1439
static int
1440
ncx_put_ushort_short(void *xp, const short *ip, void *fillp)
1441
0
{
1442
0
    int err=NC_NOERR;
1443
0
    ix_ushort xx = NC_FILL_USHORT;
1444
1445
#if IX_USHORT_MAX < SHORT_MAX
1446
    if (*ip > IX_USHORT_MAX) {
1447
        
1448
#ifdef ERANGE_FILL
1449
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1450
#endif
1451
        err = NC_ERANGE;
1452
    }
1453
#ifdef ERANGE_FILL
1454
    else
1455
#endif
1456
#endif
1457
0
    if (*ip < 0) {
1458
        
1459
#ifdef ERANGE_FILL
1460
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1461
#endif
1462
0
        err = NC_ERANGE; /* because xp is unsigned */
1463
0
    }
1464
#ifdef ERANGE_FILL
1465
    else
1466
#endif
1467
0
        xx = (ix_ushort)*ip;
1468
1469
0
    put_ix_ushort(xp, &xx);
1470
0
    return err;
1471
0
}
1472
1473
static int
1474
ncx_put_ushort_int(void *xp, const int *ip, void *fillp)
1475
0
{
1476
0
    int err=NC_NOERR;
1477
0
    ix_ushort xx = NC_FILL_USHORT;
1478
1479
0
#if IX_USHORT_MAX < INT_MAX
1480
0
    if (*ip > IX_USHORT_MAX) {
1481
        
1482
#ifdef ERANGE_FILL
1483
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1484
#endif
1485
0
        err = NC_ERANGE;
1486
0
    }
1487
#ifdef ERANGE_FILL
1488
    else
1489
#endif
1490
0
#endif
1491
0
    if (*ip < 0) {
1492
        
1493
#ifdef ERANGE_FILL
1494
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1495
#endif
1496
0
        err = NC_ERANGE; /* because xp is unsigned */
1497
0
    }
1498
#ifdef ERANGE_FILL
1499
    else
1500
#endif
1501
0
        xx = (ix_ushort)*ip;
1502
1503
0
    put_ix_ushort(xp, &xx);
1504
0
    return err;
1505
0
}
1506
1507
static int
1508
ncx_put_ushort_long(void *xp, const long *ip, void *fillp)
1509
0
{
1510
0
    int err=NC_NOERR;
1511
0
    ix_ushort xx = NC_FILL_USHORT;
1512
1513
0
#if IX_USHORT_MAX < LONG_MAX
1514
0
    if (*ip > IX_USHORT_MAX) {
1515
        
1516
#ifdef ERANGE_FILL
1517
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1518
#endif
1519
0
        err = NC_ERANGE;
1520
0
    }
1521
#ifdef ERANGE_FILL
1522
    else
1523
#endif
1524
0
#endif
1525
0
    if (*ip < 0) {
1526
        
1527
#ifdef ERANGE_FILL
1528
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1529
#endif
1530
0
        err = NC_ERANGE; /* because xp is unsigned */
1531
0
    }
1532
#ifdef ERANGE_FILL
1533
    else
1534
#endif
1535
0
        xx = (ix_ushort)*ip;
1536
1537
0
    put_ix_ushort(xp, &xx);
1538
0
    return err;
1539
0
}
1540
1541
static int
1542
ncx_put_ushort_longlong(void *xp, const longlong *ip, void *fillp)
1543
0
{
1544
0
    int err=NC_NOERR;
1545
0
    ix_ushort xx = NC_FILL_USHORT;
1546
1547
0
#if IX_USHORT_MAX < LONGLONG_MAX
1548
0
    if (*ip > IX_USHORT_MAX) {
1549
        
1550
#ifdef ERANGE_FILL
1551
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1552
#endif
1553
0
        err = NC_ERANGE;
1554
0
    }
1555
#ifdef ERANGE_FILL
1556
    else
1557
#endif
1558
0
#endif
1559
0
    if (*ip < 0) {
1560
        
1561
#ifdef ERANGE_FILL
1562
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1563
#endif
1564
0
        err = NC_ERANGE; /* because xp is unsigned */
1565
0
    }
1566
#ifdef ERANGE_FILL
1567
    else
1568
#endif
1569
0
        xx = (ix_ushort)*ip;
1570
1571
0
    put_ix_ushort(xp, &xx);
1572
0
    return err;
1573
0
}
1574
1575
static int
1576
ncx_put_ushort_ushort(void *xp, const ushort *ip, void *fillp)
1577
0
{
1578
0
    int err=NC_NOERR;
1579
0
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1580
0
    put_ix_ushort(xp, (const ix_ushort *)ip);
1581
#else
1582
    ix_ushort xx = NC_FILL_USHORT;
1583
1584
#if IX_USHORT_MAX < USHORT_MAX
1585
    if (*ip > IX_USHORT_MAX) {
1586
        
1587
#ifdef ERANGE_FILL
1588
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1589
#endif
1590
        err = NC_ERANGE;
1591
    }
1592
#ifdef ERANGE_FILL
1593
    else
1594
#endif
1595
#endif
1596
        xx = (ix_ushort)*ip;
1597
1598
    put_ix_ushort(xp, &xx);
1599
#endif
1600
0
    return err;
1601
0
}
1602
1603
static int
1604
ncx_put_ushort_uint(void *xp, const uint *ip, void *fillp)
1605
0
{
1606
0
    int err=NC_NOERR;
1607
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1608
    put_ix_ushort(xp, (const ix_ushort *)ip);
1609
#else
1610
0
    ix_ushort xx = NC_FILL_USHORT;
1611
1612
0
#if IX_USHORT_MAX < UINT_MAX
1613
0
    if (*ip > IX_USHORT_MAX) {
1614
        
1615
#ifdef ERANGE_FILL
1616
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1617
#endif
1618
0
        err = NC_ERANGE;
1619
0
    }
1620
#ifdef ERANGE_FILL
1621
    else
1622
#endif
1623
0
#endif
1624
0
        xx = (ix_ushort)*ip;
1625
1626
0
    put_ix_ushort(xp, &xx);
1627
0
#endif
1628
0
    return err;
1629
0
}
1630
1631
static int
1632
ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1633
0
{
1634
0
    int err=NC_NOERR;
1635
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1636
    put_ix_ushort(xp, (const ix_ushort *)ip);
1637
#else
1638
0
    ix_ushort xx = NC_FILL_USHORT;
1639
1640
0
#if IX_USHORT_MAX < ULONGLONG_MAX
1641
0
    if (*ip > IX_USHORT_MAX) {
1642
        
1643
#ifdef ERANGE_FILL
1644
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1645
#endif
1646
0
        err = NC_ERANGE;
1647
0
    }
1648
#ifdef ERANGE_FILL
1649
    else
1650
#endif
1651
0
#endif
1652
0
        xx = (ix_ushort)*ip;
1653
1654
0
    put_ix_ushort(xp, &xx);
1655
0
#endif
1656
0
    return err;
1657
0
}
1658
1659
static int
1660
ncx_put_ushort_float(void *xp, const float *ip, void *fillp)
1661
0
{
1662
0
    int err=NC_NOERR;
1663
0
    ix_ushort xx = NC_FILL_USHORT;
1664
1665
0
    if (*ip > (double)X_USHORT_MAX || *ip < 0) {
1666
        
1667
#ifdef ERANGE_FILL
1668
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1669
#endif
1670
0
        err = NC_ERANGE;
1671
0
    }
1672
#ifdef ERANGE_FILL
1673
    else
1674
#endif
1675
0
        xx = (ix_ushort)*ip;
1676
1677
0
    put_ix_ushort(xp, &xx);
1678
0
    return err;
1679
0
}
1680
1681
static int
1682
ncx_put_ushort_double(void *xp, const double *ip, void *fillp)
1683
0
{
1684
0
    int err=NC_NOERR;
1685
0
    ix_ushort xx = NC_FILL_USHORT;
1686
1687
0
    if (*ip > X_USHORT_MAX || *ip < 0) {
1688
        
1689
#ifdef ERANGE_FILL
1690
            if (fillp != NULL) memcpy(&xx, fillp, 2);
1691
#endif
1692
0
        err = NC_ERANGE;
1693
0
    }
1694
#ifdef ERANGE_FILL
1695
    else
1696
#endif
1697
0
        xx = (ix_ushort)*ip;
1698
1699
0
    put_ix_ushort(xp, &xx);
1700
0
    return err;
1701
0
}
1702
1703
1704
/* external NC_INT ----------------------------------------------------------*/
1705
1706
#if SHORT_MAX == X_INT_MAX
1707
typedef short ix_int;
1708
#define SIZEOF_IX_INT SIZEOF_SHORT
1709
#define IX_INT_MAX SHORT_MAX
1710
#elif INT_MAX  >= X_INT_MAX
1711
typedef int ix_int;
1712
#define SIZEOF_IX_INT SIZEOF_INT
1713
0
#define IX_INT_MAX INT_MAX
1714
#elif LONG_MAX  >= X_INT_MAX
1715
typedef long ix_int;
1716
#define SIZEOF_IX_INT SIZEOF_LONG
1717
#define IX_INT_MAX LONG_MAX
1718
#else
1719
#error "ix_int implementation"
1720
#endif
1721
1722
1723
static void
1724
get_ix_int(const void *xp, ix_int *ip)
1725
0
{
1726
0
  const uchar *cp = (const uchar *) xp;
1727
1728
0
#if INT_MAX  >= X_INT_MAX
1729
0
  *ip = (ix_int)((unsigned)(*cp++) << 24);
1730
#else
1731
  *ip = *cp++ << 24;
1732
#endif
1733
#if SIZEOF_IX_INT > X_SIZEOF_INT
1734
  if (*ip & 0x80000000)
1735
  {
1736
    /* extern is negative */
1737
    *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
1738
  }
1739
#endif
1740
0
  *ip |= (*cp++ << 16);
1741
0
  *ip |= (*cp++ << 8);
1742
0
  *ip |= *cp;
1743
0
}
1744
1745
static void
1746
put_ix_int(void *xp, const ix_int *ip)
1747
0
{
1748
0
  uchar *cp = (uchar *) xp;
1749
1750
0
  *cp++ = (uchar)( (*ip) >> 24);
1751
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
1752
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
1753
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
1754
0
}
1755
1756
#if X_SIZEOF_INT != SIZEOF_INT
1757
static int
1758
ncx_get_int_int(const void *xp, int *ip)
1759
{
1760
    int err=NC_NOERR;
1761
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1762
    get_ix_int(xp, (ix_int *)ip);
1763
#else
1764
    ix_int xx = 0;
1765
    get_ix_int(xp, &xx);
1766
1767
#if IX_INT_MAX > INT_MAX
1768
    if (xx > INT_MAX || xx < INT_MIN) {
1769
#ifdef ERANGE_FILL
1770
        *ip = NC_FILL_INT;
1771
        return NC_ERANGE;
1772
#else
1773
        err = NC_ERANGE;
1774
#endif
1775
    }
1776
#endif
1777
1778
1779
    *ip = (int) xx;
1780
#endif
1781
    return err;
1782
}
1783
1784
#endif
1785
static int
1786
ncx_get_int_schar(const void *xp, schar *ip)
1787
0
{
1788
0
    int err=NC_NOERR;
1789
0
    ix_int xx = 0;
1790
0
    get_ix_int(xp, &xx);
1791
1792
0
#if IX_INT_MAX > SCHAR_MAX
1793
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
1794
#ifdef ERANGE_FILL
1795
        *ip = NC_FILL_BYTE;
1796
        return NC_ERANGE;
1797
#else
1798
0
        err = NC_ERANGE;
1799
0
#endif
1800
0
    }
1801
0
#endif
1802
1803
1804
0
    *ip = (schar) xx;
1805
0
    return err;
1806
0
}
1807
1808
static int
1809
ncx_get_int_short(const void *xp, short *ip)
1810
0
{
1811
0
    int err=NC_NOERR;
1812
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1813
    get_ix_int(xp, (ix_int *)ip);
1814
#else
1815
0
    ix_int xx = 0;
1816
0
    get_ix_int(xp, &xx);
1817
1818
0
#if IX_INT_MAX > SHORT_MAX
1819
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
1820
#ifdef ERANGE_FILL
1821
        *ip = NC_FILL_SHORT;
1822
        return NC_ERANGE;
1823
#else
1824
0
        err = NC_ERANGE;
1825
0
#endif
1826
0
    }
1827
0
#endif
1828
1829
1830
0
    *ip = (short) xx;
1831
0
#endif
1832
0
    return err;
1833
0
}
1834
1835
static int
1836
ncx_get_int_long(const void *xp, long *ip)
1837
0
{
1838
0
    int err=NC_NOERR;
1839
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1840
    get_ix_int(xp, (ix_int *)ip);
1841
#else
1842
0
    ix_int xx = 0;
1843
0
    get_ix_int(xp, &xx);
1844
1845
#if IX_INT_MAX > LONG_MAX
1846
    if (xx > LONG_MAX || xx < LONG_MIN) {
1847
#ifdef ERANGE_FILL
1848
        *ip = NC_FILL_INT;
1849
        return NC_ERANGE;
1850
#else
1851
        err = NC_ERANGE;
1852
#endif
1853
    }
1854
#endif
1855
1856
1857
0
    *ip = (long) xx;
1858
0
#endif
1859
0
    return err;
1860
0
}
1861
1862
static int
1863
ncx_get_int_longlong(const void *xp, longlong *ip)
1864
0
{
1865
0
    int err=NC_NOERR;
1866
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1867
    get_ix_int(xp, (ix_int *)ip);
1868
#else
1869
0
    ix_int xx = 0;
1870
0
    get_ix_int(xp, &xx);
1871
1872
#if IX_INT_MAX > LONGLONG_MAX
1873
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
1874
#ifdef ERANGE_FILL
1875
        *ip = NC_FILL_INT64;
1876
        return NC_ERANGE;
1877
#else
1878
        err = NC_ERANGE;
1879
#endif
1880
    }
1881
#endif
1882
1883
1884
0
    *ip = (longlong) xx;
1885
0
#endif
1886
0
    return err;
1887
0
}
1888
1889
static int
1890
ncx_get_int_ushort(const void *xp, ushort *ip)
1891
0
{
1892
0
    int err=NC_NOERR;
1893
0
    ix_int xx = 0;
1894
0
    get_ix_int(xp, &xx);
1895
1896
0
#if IX_INT_MAX > USHORT_MAX
1897
0
    if (xx > USHORT_MAX) {
1898
#ifdef ERANGE_FILL
1899
        *ip = NC_FILL_USHORT;
1900
        return NC_ERANGE;
1901
#else
1902
0
        err = NC_ERANGE;
1903
0
#endif
1904
0
    }
1905
0
#endif
1906
1907
0
    if (xx < 0) {
1908
#ifdef ERANGE_FILL
1909
        *ip = NC_FILL_USHORT;
1910
        return NC_ERANGE;
1911
#else
1912
0
        err = NC_ERANGE; /* because ip is unsigned */
1913
0
#endif
1914
0
    }
1915
0
    *ip = (ushort) xx;
1916
0
    return err;
1917
0
}
1918
1919
static int
1920
ncx_get_int_uchar(const void *xp, uchar *ip)
1921
0
{
1922
0
    int err=NC_NOERR;
1923
0
    ix_int xx = 0;
1924
0
    get_ix_int(xp, &xx);
1925
1926
0
#if IX_INT_MAX > UCHAR_MAX
1927
0
    if (xx > UCHAR_MAX) {
1928
#ifdef ERANGE_FILL
1929
        *ip = NC_FILL_UBYTE;
1930
        return NC_ERANGE;
1931
#else
1932
0
        err = NC_ERANGE;
1933
0
#endif
1934
0
    }
1935
0
#endif
1936
1937
0
    if (xx < 0) {
1938
#ifdef ERANGE_FILL
1939
        *ip = NC_FILL_UBYTE;
1940
        return NC_ERANGE;
1941
#else
1942
0
        err = NC_ERANGE; /* because ip is unsigned */
1943
0
#endif
1944
0
    }
1945
0
    *ip = (uchar) xx;
1946
0
    return err;
1947
0
}
1948
1949
static int
1950
ncx_get_int_uint(const void *xp, uint *ip)
1951
0
{
1952
0
    int err=NC_NOERR;
1953
0
    ix_int xx = 0;
1954
0
    get_ix_int(xp, &xx);
1955
1956
#if IX_INT_MAX > UINT_MAX
1957
    if (xx > UINT_MAX) {
1958
#ifdef ERANGE_FILL
1959
        *ip = NC_FILL_UINT;
1960
        return NC_ERANGE;
1961
#else
1962
        err = NC_ERANGE;
1963
#endif
1964
    }
1965
#endif
1966
1967
0
    if (xx < 0) {
1968
#ifdef ERANGE_FILL
1969
        *ip = NC_FILL_UINT;
1970
        return NC_ERANGE;
1971
#else
1972
0
        err = NC_ERANGE; /* because ip is unsigned */
1973
0
#endif
1974
0
    }
1975
0
    *ip = (uint) xx;
1976
0
    return err;
1977
0
}
1978
1979
static int
1980
ncx_get_int_ulonglong(const void *xp, ulonglong *ip)
1981
0
{
1982
0
    int err=NC_NOERR;
1983
0
    ix_int xx = 0;
1984
0
    get_ix_int(xp, &xx);
1985
1986
#if IX_INT_MAX > ULONGLONG_MAX
1987
    if (xx > ULONGLONG_MAX) {
1988
#ifdef ERANGE_FILL
1989
        *ip = NC_FILL_UINT64;
1990
        return NC_ERANGE;
1991
#else
1992
        err = NC_ERANGE;
1993
#endif
1994
    }
1995
#endif
1996
1997
0
    if (xx < 0) {
1998
#ifdef ERANGE_FILL
1999
        *ip = NC_FILL_UINT64;
2000
        return NC_ERANGE;
2001
#else
2002
0
        err = NC_ERANGE; /* because ip is unsigned */
2003
0
#endif
2004
0
    }
2005
0
    *ip = (ulonglong) xx;
2006
0
    return err;
2007
0
}
2008
2009
static int
2010
ncx_get_int_float(const void *xp, float *ip)
2011
0
{
2012
0
  ix_int xx = 0;
2013
0
  get_ix_int(xp, &xx);
2014
0
  *ip = (float)xx;
2015
0
  return NC_NOERR;
2016
0
}
2017
2018
static int
2019
ncx_get_int_double(const void *xp, double *ip)
2020
0
{
2021
0
  ix_int xx = 0;
2022
0
  get_ix_int(xp, &xx);
2023
0
  *ip = (double)xx;
2024
0
  return NC_NOERR;
2025
0
}
2026
2027
2028
static int
2029
ncx_put_int_schar(void *xp, const schar *ip, void *fillp)
2030
0
{
2031
0
  uchar *cp = (uchar *) xp;
2032
0
  if (*ip & 0x80)
2033
0
  {
2034
0
    *cp++ = 0xff;
2035
0
    *cp++ = 0xff;
2036
0
    *cp++ = 0xff;
2037
0
  }
2038
0
  else
2039
0
  {
2040
0
    *cp++ = 0x00;
2041
0
    *cp++ = 0x00;
2042
0
    *cp++ = 0x00;
2043
0
  }
2044
0
  *cp = (uchar)*ip;
2045
0
  return NC_NOERR;
2046
0
}
2047
2048
static int
2049
ncx_put_int_uchar(void *xp, const uchar *ip, void *fillp)
2050
0
{
2051
0
  uchar *cp = (uchar *) xp;
2052
0
  *cp++ = 0x00;
2053
0
  *cp++ = 0x00;
2054
0
  *cp++ = 0x00;
2055
0
  *cp   = *ip;
2056
0
  return NC_NOERR;
2057
0
}
2058
2059
#if X_SIZEOF_INT != SIZEOF_INT
2060
static int
2061
ncx_put_int_int(void *xp, const int *ip, void *fillp)
2062
{
2063
    int err=NC_NOERR;
2064
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
2065
    put_ix_int(xp, (const ix_int *)ip);
2066
#else
2067
    ix_int xx = NC_FILL_INT;
2068
2069
#if IX_INT_MAX < INT_MAX
2070
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2071
        
2072
#ifdef ERANGE_FILL
2073
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2074
#endif
2075
        err = NC_ERANGE;
2076
    }
2077
#ifdef ERANGE_FILL
2078
    else
2079
#endif
2080
#endif
2081
        xx = (ix_int)*ip;
2082
2083
    put_ix_int(xp, &xx);
2084
#endif
2085
    return err;
2086
}
2087
2088
#endif
2089
static int
2090
ncx_put_int_short(void *xp, const short *ip, void *fillp)
2091
0
{
2092
0
    int err=NC_NOERR;
2093
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
2094
    put_ix_int(xp, (const ix_int *)ip);
2095
#else
2096
0
    ix_int xx = NC_FILL_INT;
2097
2098
#if IX_INT_MAX < SHORT_MAX
2099
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2100
        
2101
#ifdef ERANGE_FILL
2102
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2103
#endif
2104
        err = NC_ERANGE;
2105
    }
2106
#ifdef ERANGE_FILL
2107
    else
2108
#endif
2109
#endif
2110
0
        xx = (ix_int)*ip;
2111
2112
0
    put_ix_int(xp, &xx);
2113
0
#endif
2114
0
    return err;
2115
0
}
2116
2117
static int
2118
ncx_put_int_long(void *xp, const long *ip, void *fillp)
2119
0
{
2120
0
    int err=NC_NOERR;
2121
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
2122
    put_ix_int(xp, (const ix_int *)ip);
2123
#else
2124
0
    ix_int xx = NC_FILL_INT;
2125
2126
0
#if IX_INT_MAX < LONG_MAX
2127
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2128
        
2129
#ifdef ERANGE_FILL
2130
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2131
#endif
2132
0
        err = NC_ERANGE;
2133
0
    }
2134
#ifdef ERANGE_FILL
2135
    else
2136
#endif
2137
0
#endif
2138
0
        xx = (ix_int)*ip;
2139
2140
0
    put_ix_int(xp, &xx);
2141
0
#endif
2142
0
    return err;
2143
0
}
2144
2145
static int
2146
ncx_put_int_longlong(void *xp, const longlong *ip, void *fillp)
2147
0
{
2148
0
    int err=NC_NOERR;
2149
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
2150
    put_ix_int(xp, (const ix_int *)ip);
2151
#else
2152
0
    ix_int xx = NC_FILL_INT;
2153
2154
0
#if IX_INT_MAX < LONGLONG_MAX
2155
0
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2156
        
2157
#ifdef ERANGE_FILL
2158
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2159
#endif
2160
0
        err = NC_ERANGE;
2161
0
    }
2162
#ifdef ERANGE_FILL
2163
    else
2164
#endif
2165
0
#endif
2166
0
        xx = (ix_int)*ip;
2167
2168
0
    put_ix_int(xp, &xx);
2169
0
#endif
2170
0
    return err;
2171
0
}
2172
2173
static int
2174
ncx_put_int_ushort(void *xp, const ushort *ip, void *fillp)
2175
0
{
2176
0
    int err=NC_NOERR;
2177
0
    ix_int xx = NC_FILL_INT;
2178
2179
#if IX_INT_MAX < USHORT_MAX
2180
    if (*ip > IX_INT_MAX) {
2181
        
2182
#ifdef ERANGE_FILL
2183
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2184
#endif
2185
        err = NC_ERANGE;
2186
    }
2187
#ifdef ERANGE_FILL
2188
    else
2189
#endif
2190
#endif
2191
0
        xx = (ix_int)*ip;
2192
2193
0
    put_ix_int(xp, &xx);
2194
0
    return err;
2195
0
}
2196
2197
static int
2198
ncx_put_int_uint(void *xp, const uint *ip, void *fillp)
2199
0
{
2200
0
    int err=NC_NOERR;
2201
0
    ix_int xx = NC_FILL_INT;
2202
2203
0
#if IX_INT_MAX < UINT_MAX
2204
0
    if (*ip > IX_INT_MAX) {
2205
        
2206
#ifdef ERANGE_FILL
2207
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2208
#endif
2209
0
        err = NC_ERANGE;
2210
0
    }
2211
#ifdef ERANGE_FILL
2212
    else
2213
#endif
2214
0
#endif
2215
0
        xx = (ix_int)*ip;
2216
2217
0
    put_ix_int(xp, &xx);
2218
0
    return err;
2219
0
}
2220
2221
static int
2222
ncx_put_int_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2223
0
{
2224
0
    int err=NC_NOERR;
2225
0
    ix_int xx = NC_FILL_INT;
2226
2227
0
#if IX_INT_MAX < ULONGLONG_MAX
2228
0
    if (*ip > IX_INT_MAX) {
2229
        
2230
#ifdef ERANGE_FILL
2231
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2232
#endif
2233
0
        err = NC_ERANGE;
2234
0
    }
2235
#ifdef ERANGE_FILL
2236
    else
2237
#endif
2238
0
#endif
2239
0
        xx = (ix_int)*ip;
2240
2241
0
    put_ix_int(xp, &xx);
2242
0
    return err;
2243
0
}
2244
2245
static int
2246
ncx_put_int_float(void *xp, const float *ip, void *fillp)
2247
0
{
2248
0
    int err=NC_NOERR;
2249
0
    ix_int xx = NC_FILL_INT;
2250
2251
0
    if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
2252
        
2253
#ifdef ERANGE_FILL
2254
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2255
#endif
2256
0
        err = NC_ERANGE;
2257
0
    }
2258
#ifdef ERANGE_FILL
2259
    else
2260
#endif
2261
0
        xx = (ix_int)*ip;
2262
2263
0
    put_ix_int(xp, &xx);
2264
0
    return err;
2265
0
}
2266
2267
static int
2268
ncx_put_int_double(void *xp, const double *ip, void *fillp)
2269
0
{
2270
0
    int err=NC_NOERR;
2271
0
    ix_int xx = NC_FILL_INT;
2272
2273
0
    if (*ip > X_INT_MAX || *ip < X_INT_MIN) {
2274
        
2275
#ifdef ERANGE_FILL
2276
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2277
#endif
2278
0
        err = NC_ERANGE;
2279
0
    }
2280
#ifdef ERANGE_FILL
2281
    else
2282
#endif
2283
0
        xx = (ix_int)*ip;
2284
2285
0
    put_ix_int(xp, &xx);
2286
0
    return err;
2287
0
}
2288
2289
2290
2291
/* external NC_UINT ---------------------------------------------------------*/
2292
2293
#if USHORT_MAX == X_UINT_MAX
2294
typedef ushort ix_uint;
2295
#define SIZEOF_IX_UINT SIZEOF_USHORT
2296
#define IX_UINT_MAX USHORT_MAX
2297
#elif UINT_MAX  >= X_UINT_MAX
2298
typedef uint ix_uint;
2299
#define SIZEOF_IX_UINT SIZEOF_UINT
2300
0
#define IX_UINT_MAX UINT_MAX
2301
#elif ULONG_MAX  >= X_UINT_MAX
2302
typedef ulong ix_uint;
2303
#define SIZEOF_IX_UINT SIZEOF_ULONG
2304
#define IX_UINT_MAX ULONG_MAX
2305
#else
2306
#error "ix_uint implementation"
2307
#endif
2308
2309
2310
static void
2311
get_ix_uint(const void *xp, ix_uint *ip)
2312
0
{
2313
0
  const uchar *cp = (const uchar *) xp;
2314
2315
0
  *ip = (ix_uint)(*cp++ << 24);
2316
0
  *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 16));
2317
0
  *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 8));
2318
0
  *ip = (ix_uint)(*ip | *cp);
2319
0
}
2320
2321
static void
2322
put_ix_uint(void *xp, const ix_uint *ip)
2323
0
{
2324
0
  uchar *cp = (uchar *) xp;
2325
2326
0
  *cp++ = (uchar)((*ip) >> 24);
2327
0
  *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
2328
0
  *cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
2329
0
  *cp   = (uchar)( (*ip) & 0x000000ff);
2330
0
}
2331
2332
#if X_SIZEOF_UINT != SIZEOF_UINT
2333
static int
2334
ncx_get_uint_uint(const void *xp, uint *ip)
2335
{
2336
    int err=NC_NOERR;
2337
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2338
    get_ix_uint(xp, (ix_uint *)ip);
2339
#else
2340
    ix_uint xx = 0;
2341
    get_ix_uint(xp, &xx);
2342
2343
#if IX_UINT_MAX > UINT_MAX
2344
    if (xx > UINT_MAX) {
2345
#ifdef ERANGE_FILL
2346
        *ip = NC_FILL_UINT;
2347
        return NC_ERANGE;
2348
#else
2349
        err = NC_ERANGE;
2350
#endif
2351
    }
2352
#endif
2353
2354
2355
    *ip = (uint) xx;
2356
#endif
2357
    return err;
2358
}
2359
2360
#endif
2361
2362
static int
2363
ncx_get_uint_schar(const void *xp, schar *ip)
2364
0
{
2365
0
    int err=NC_NOERR;
2366
0
    ix_uint xx = 0;
2367
0
    get_ix_uint(xp, &xx);
2368
2369
0
#if IX_UINT_MAX > SCHAR_MAX
2370
0
    if (xx > SCHAR_MAX) {
2371
#ifdef ERANGE_FILL
2372
        *ip = NC_FILL_BYTE;
2373
        return NC_ERANGE;
2374
#else
2375
0
        err = NC_ERANGE;
2376
0
#endif
2377
0
    }
2378
0
#endif
2379
2380
2381
0
    *ip = (schar) xx;
2382
0
    return err;
2383
0
}
2384
2385
static int
2386
ncx_get_uint_short(const void *xp, short *ip)
2387
0
{
2388
0
    int err=NC_NOERR;
2389
0
    ix_uint xx = 0;
2390
0
    get_ix_uint(xp, &xx);
2391
2392
0
#if IX_UINT_MAX > SHORT_MAX
2393
0
    if (xx > SHORT_MAX) {
2394
#ifdef ERANGE_FILL
2395
        *ip = NC_FILL_SHORT;
2396
        return NC_ERANGE;
2397
#else
2398
0
        err = NC_ERANGE;
2399
0
#endif
2400
0
    }
2401
0
#endif
2402
2403
2404
0
    *ip = (short) xx;
2405
0
    return err;
2406
0
}
2407
2408
static int
2409
ncx_get_uint_int(const void *xp, int *ip)
2410
0
{
2411
0
    int err=NC_NOERR;
2412
0
    ix_uint xx = 0;
2413
0
    get_ix_uint(xp, &xx);
2414
2415
0
#if IX_UINT_MAX > INT_MAX
2416
0
    if (xx > INT_MAX) {
2417
#ifdef ERANGE_FILL
2418
        *ip = NC_FILL_INT;
2419
        return NC_ERANGE;
2420
#else
2421
0
        err = NC_ERANGE;
2422
0
#endif
2423
0
    }
2424
0
#endif
2425
2426
2427
0
    *ip = (int) xx;
2428
0
    return err;
2429
0
}
2430
2431
static int
2432
ncx_get_uint_long(const void *xp, long *ip)
2433
0
{
2434
0
    int err=NC_NOERR;
2435
0
    ix_uint xx = 0;
2436
0
    get_ix_uint(xp, &xx);
2437
2438
#if IX_UINT_MAX > LONG_MAX
2439
    if (xx > LONG_MAX) {
2440
#ifdef ERANGE_FILL
2441
        *ip = NC_FILL_INT;
2442
        return NC_ERANGE;
2443
#else
2444
        err = NC_ERANGE;
2445
#endif
2446
    }
2447
#endif
2448
2449
2450
0
    *ip = (long) xx;
2451
0
    return err;
2452
0
}
2453
2454
static int
2455
ncx_get_uint_longlong(const void *xp, longlong *ip)
2456
0
{
2457
0
    int err=NC_NOERR;
2458
0
    ix_uint xx = 0;
2459
0
    get_ix_uint(xp, &xx);
2460
2461
#if IX_UINT_MAX > LONGLONG_MAX
2462
    if (xx > LONGLONG_MAX) {
2463
#ifdef ERANGE_FILL
2464
        *ip = NC_FILL_INT64;
2465
        return NC_ERANGE;
2466
#else
2467
        err = NC_ERANGE;
2468
#endif
2469
    }
2470
#endif
2471
2472
2473
0
    *ip = (longlong) xx;
2474
0
    return err;
2475
0
}
2476
2477
static int
2478
ncx_get_uint_ushort(const void *xp, ushort *ip)
2479
0
{
2480
0
    int err=NC_NOERR;
2481
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2482
    get_ix_uint(xp, (ix_uint *)ip);
2483
#else
2484
0
    ix_uint xx = 0;
2485
0
    get_ix_uint(xp, &xx);
2486
2487
0
#if IX_UINT_MAX > USHORT_MAX
2488
0
    if (xx > USHORT_MAX) {
2489
#ifdef ERANGE_FILL
2490
        *ip = NC_FILL_USHORT;
2491
        return NC_ERANGE;
2492
#else
2493
0
        err = NC_ERANGE;
2494
0
#endif
2495
0
    }
2496
0
#endif
2497
2498
2499
0
    *ip = (ushort) xx;
2500
0
#endif
2501
0
    return err;
2502
0
}
2503
2504
static int
2505
ncx_get_uint_uchar(const void *xp, uchar *ip)
2506
0
{
2507
0
    int err=NC_NOERR;
2508
#if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
2509
    get_ix_uint(xp, (ix_uint *)ip);
2510
#else
2511
0
    ix_uint xx = 0;
2512
0
    get_ix_uint(xp, &xx);
2513
2514
0
#if IX_UINT_MAX > UCHAR_MAX
2515
0
    if (xx > UCHAR_MAX) {
2516
#ifdef ERANGE_FILL
2517
        *ip = NC_FILL_UBYTE;
2518
        return NC_ERANGE;
2519
#else
2520
0
        err = NC_ERANGE;
2521
0
#endif
2522
0
    }
2523
0
#endif
2524
2525
2526
0
    *ip = (uchar) xx;
2527
0
#endif
2528
0
    return err;
2529
0
}
2530
2531
static int
2532
ncx_get_uint_ulonglong(const void *xp, ulonglong *ip)
2533
0
{
2534
0
    int err=NC_NOERR;
2535
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2536
    get_ix_uint(xp, (ix_uint *)ip);
2537
#else
2538
0
    ix_uint xx = 0;
2539
0
    get_ix_uint(xp, &xx);
2540
2541
#if IX_UINT_MAX > ULONGLONG_MAX
2542
    if (xx > ULONGLONG_MAX) {
2543
#ifdef ERANGE_FILL
2544
        *ip = NC_FILL_UINT64;
2545
        return NC_ERANGE;
2546
#else
2547
        err = NC_ERANGE;
2548
#endif
2549
    }
2550
#endif
2551
2552
2553
0
    *ip = (ulonglong) xx;
2554
0
#endif
2555
0
    return err;
2556
0
}
2557
2558
static int
2559
ncx_get_uint_float(const void *xp, float *ip)
2560
0
{
2561
0
  ix_uint xx = 0;
2562
0
  get_ix_uint(xp, &xx);
2563
0
  *ip = (float)xx;
2564
0
  return NC_NOERR;
2565
0
}
2566
2567
static int
2568
ncx_get_uint_double(const void *xp, double *ip)
2569
0
{
2570
0
  ix_uint xx = 0;
2571
0
  get_ix_uint(xp, &xx);
2572
0
  *ip = (double)xx;
2573
0
  return NC_NOERR;
2574
0
}
2575
2576
2577
static int
2578
ncx_put_uint_schar(void *xp, const schar *ip, void *fillp)
2579
0
{
2580
0
    uchar *cp;
2581
0
    if (*ip < 0) {
2582
#ifdef ERANGE_FILL
2583
        if (fillp != NULL) memcpy(xp, fillp, 4);
2584
#ifndef WORDS_BIGENDIAN
2585
        swapn4b(xp, xp, 1);
2586
#endif
2587
#endif
2588
0
        return NC_ERANGE;
2589
0
    }
2590
2591
0
    cp = (uchar *) xp;
2592
0
    *cp++ = 0x00;
2593
0
    *cp++ = 0x00;
2594
0
    *cp++ = 0x00;
2595
0
    *cp = (uchar)*ip;
2596
2597
0
    return NC_NOERR;
2598
0
}
2599
2600
static int
2601
ncx_put_uint_uchar(void *xp, const uchar *ip, void *fillp)
2602
0
{
2603
0
  uchar *cp = (uchar *) xp;
2604
0
  *cp++ = 0x00;
2605
0
  *cp++ = 0x00;
2606
0
  *cp++ = 0x00;
2607
0
  *cp   = *ip;
2608
0
  return NC_NOERR;
2609
0
}
2610
2611
#if X_SIZEOF_UINT != SIZEOF_UINT
2612
static int
2613
ncx_put_uint_uint(void *xp, const uint *ip, void *fillp)
2614
{
2615
    int err=NC_NOERR;
2616
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2617
    put_ix_uint(xp, (const ix_uint *)ip);
2618
#else
2619
    ix_uint xx = NC_FILL_UINT;
2620
2621
#if IX_UINT_MAX < UINT_MAX
2622
    if (*ip > IX_UINT_MAX) {
2623
        
2624
#ifdef ERANGE_FILL
2625
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2626
#endif
2627
        err = NC_ERANGE;
2628
    }
2629
#ifdef ERANGE_FILL
2630
    else
2631
#endif
2632
#endif
2633
        xx = (ix_uint)*ip;
2634
2635
    put_ix_uint(xp, &xx);
2636
#endif
2637
    return err;
2638
}
2639
2640
#endif
2641
2642
static int
2643
ncx_put_uint_short(void *xp, const short *ip, void *fillp)
2644
0
{
2645
0
    int err=NC_NOERR;
2646
0
    ix_uint xx = NC_FILL_UINT;
2647
2648
#if IX_UINT_MAX < SHORT_MAX
2649
    if (*ip > IX_UINT_MAX) {
2650
        
2651
#ifdef ERANGE_FILL
2652
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2653
#endif
2654
        err = NC_ERANGE;
2655
    }
2656
#ifdef ERANGE_FILL
2657
    else
2658
#endif
2659
#endif
2660
0
    if (*ip < 0) {
2661
        
2662
#ifdef ERANGE_FILL
2663
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2664
#endif
2665
0
        err = NC_ERANGE; /* because xp is unsigned */
2666
0
    }
2667
#ifdef ERANGE_FILL
2668
    else
2669
#endif
2670
0
        xx = (ix_uint)*ip;
2671
2672
0
    put_ix_uint(xp, &xx);
2673
0
    return err;
2674
0
}
2675
2676
static int
2677
ncx_put_uint_int(void *xp, const int *ip, void *fillp)
2678
0
{
2679
0
    int err=NC_NOERR;
2680
0
    ix_uint xx = NC_FILL_UINT;
2681
2682
#if IX_UINT_MAX < INT_MAX
2683
    if (*ip > IX_UINT_MAX) {
2684
        
2685
#ifdef ERANGE_FILL
2686
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2687
#endif
2688
        err = NC_ERANGE;
2689
    }
2690
#ifdef ERANGE_FILL
2691
    else
2692
#endif
2693
#endif
2694
0
    if (*ip < 0) {
2695
        
2696
#ifdef ERANGE_FILL
2697
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2698
#endif
2699
0
        err = NC_ERANGE; /* because xp is unsigned */
2700
0
    }
2701
#ifdef ERANGE_FILL
2702
    else
2703
#endif
2704
0
        xx = (ix_uint)*ip;
2705
2706
0
    put_ix_uint(xp, &xx);
2707
0
    return err;
2708
0
}
2709
2710
static int
2711
ncx_put_uint_long(void *xp, const long *ip, void *fillp)
2712
0
{
2713
0
    int err=NC_NOERR;
2714
0
    ix_uint xx = NC_FILL_UINT;
2715
2716
0
#if IX_UINT_MAX < LONG_MAX
2717
0
    if (*ip > IX_UINT_MAX) {
2718
        
2719
#ifdef ERANGE_FILL
2720
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2721
#endif
2722
0
        err = NC_ERANGE;
2723
0
    }
2724
#ifdef ERANGE_FILL
2725
    else
2726
#endif
2727
0
#endif
2728
0
    if (*ip < 0) {
2729
        
2730
#ifdef ERANGE_FILL
2731
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2732
#endif
2733
0
        err = NC_ERANGE; /* because xp is unsigned */
2734
0
    }
2735
#ifdef ERANGE_FILL
2736
    else
2737
#endif
2738
0
        xx = (ix_uint)*ip;
2739
2740
0
    put_ix_uint(xp, &xx);
2741
0
    return err;
2742
0
}
2743
2744
static int
2745
ncx_put_uint_longlong(void *xp, const longlong *ip, void *fillp)
2746
0
{
2747
0
    int err=NC_NOERR;
2748
0
    ix_uint xx = NC_FILL_UINT;
2749
2750
0
#if IX_UINT_MAX < LONGLONG_MAX
2751
0
    if (*ip > IX_UINT_MAX) {
2752
        
2753
#ifdef ERANGE_FILL
2754
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2755
#endif
2756
0
        err = NC_ERANGE;
2757
0
    }
2758
#ifdef ERANGE_FILL
2759
    else
2760
#endif
2761
0
#endif
2762
0
    if (*ip < 0) {
2763
        
2764
#ifdef ERANGE_FILL
2765
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2766
#endif
2767
0
        err = NC_ERANGE; /* because xp is unsigned */
2768
0
    }
2769
#ifdef ERANGE_FILL
2770
    else
2771
#endif
2772
0
        xx = (ix_uint)*ip;
2773
2774
0
    put_ix_uint(xp, &xx);
2775
0
    return err;
2776
0
}
2777
2778
static int
2779
ncx_put_uint_ushort(void *xp, const ushort *ip, void *fillp)
2780
0
{
2781
0
    int err=NC_NOERR;
2782
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2783
    put_ix_uint(xp, (const ix_uint *)ip);
2784
#else
2785
0
    ix_uint xx = NC_FILL_UINT;
2786
2787
#if IX_UINT_MAX < USHORT_MAX
2788
    if (*ip > IX_UINT_MAX) {
2789
        
2790
#ifdef ERANGE_FILL
2791
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2792
#endif
2793
        err = NC_ERANGE;
2794
    }
2795
#ifdef ERANGE_FILL
2796
    else
2797
#endif
2798
#endif
2799
0
        xx = (ix_uint)*ip;
2800
2801
0
    put_ix_uint(xp, &xx);
2802
0
#endif
2803
0
    return err;
2804
0
}
2805
2806
static int
2807
ncx_put_uint_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2808
0
{
2809
0
    int err=NC_NOERR;
2810
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2811
    put_ix_uint(xp, (const ix_uint *)ip);
2812
#else
2813
0
    ix_uint xx = NC_FILL_UINT;
2814
2815
0
#if IX_UINT_MAX < ULONGLONG_MAX
2816
0
    if (*ip > IX_UINT_MAX) {
2817
        
2818
#ifdef ERANGE_FILL
2819
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2820
#endif
2821
0
        err = NC_ERANGE;
2822
0
    }
2823
#ifdef ERANGE_FILL
2824
    else
2825
#endif
2826
0
#endif
2827
0
        xx = (ix_uint)*ip;
2828
2829
0
    put_ix_uint(xp, &xx);
2830
0
#endif
2831
0
    return err;
2832
0
}
2833
2834
static int
2835
ncx_put_uint_float(void *xp, const float *ip, void *fillp)
2836
0
{
2837
0
    int err=NC_NOERR;
2838
0
    ix_uint xx = NC_FILL_UINT;
2839
2840
0
    if (*ip > (double)X_UINT_MAX || *ip < 0) {
2841
        
2842
#ifdef ERANGE_FILL
2843
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2844
#endif
2845
0
        err = NC_ERANGE;
2846
0
    }
2847
#ifdef ERANGE_FILL
2848
    else
2849
#endif
2850
0
        xx = (ix_uint)*ip;
2851
2852
0
    put_ix_uint(xp, &xx);
2853
0
    return err;
2854
0
}
2855
2856
static int
2857
ncx_put_uint_double(void *xp, const double *ip, void *fillp)
2858
0
{
2859
0
    int err=NC_NOERR;
2860
0
    ix_uint xx = NC_FILL_UINT;
2861
2862
0
    if (*ip > X_UINT_MAX || *ip < 0) {
2863
        
2864
#ifdef ERANGE_FILL
2865
            if (fillp != NULL) memcpy(&xx, fillp, 4);
2866
#endif
2867
0
        err = NC_ERANGE;
2868
0
    }
2869
#ifdef ERANGE_FILL
2870
    else
2871
#endif
2872
0
        xx = (ix_uint)*ip;
2873
2874
0
    put_ix_uint(xp, &xx);
2875
0
    return err;
2876
0
}
2877
2878
2879
2880
/* external NC_FLOAT --------------------------------------------------------*/
2881
2882
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
2883
2884
inline static void
2885
get_ix_float(const void *xp, float *ip)
2886
0
{
2887
#ifdef WORDS_BIGENDIAN
2888
  (void) memcpy(ip, xp, SIZEOF_FLOAT);
2889
#else
2890
0
  swap4b(ip, xp);
2891
0
#endif
2892
0
}
2893
2894
inline static void
2895
put_ix_float(void *xp, const float *ip)
2896
0
{
2897
#ifdef WORDS_BIGENDIAN
2898
  (void) memcpy(xp, ip, X_SIZEOF_FLOAT);
2899
#else
2900
0
  swap4b(xp, ip);
2901
0
#endif
2902
0
}
2903
2904
#elif defined(vax) && vax != 0
2905
2906
/* What IEEE single precision floating point looks like on a Vax */
2907
struct  ieee_single {
2908
  unsigned int  exp_hi       : 7;
2909
  unsigned int  sign         : 1;
2910
  unsigned int  mant_hi      : 7;
2911
  unsigned int  exp_lo       : 1;
2912
  unsigned int  mant_lo_hi   : 8;
2913
  unsigned int  mant_lo_lo   : 8;
2914
};
2915
2916
/* Vax single precision floating point */
2917
struct  vax_single {
2918
  unsigned int  mantissa1 : 7;
2919
  unsigned int  exp       : 8;
2920
  unsigned int  sign      : 1;
2921
  unsigned int  mantissa2 : 16;
2922
};
2923
2924
#define VAX_SNG_BIAS  0x81
2925
#define IEEE_SNG_BIAS 0x7f
2926
2927
static struct sgl_limits {
2928
  struct vax_single s;
2929
  struct ieee_single ieee;
2930
} max = {
2931
  { 0x7f, 0xff, 0x0, 0xffff },  /* Max Vax */
2932
  { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }   /* Max IEEE */
2933
};
2934
static struct sgl_limits min = {
2935
  { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
2936
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }    /* Min IEEE */
2937
};
2938
2939
static void
2940
get_ix_float(const void *xp, float *ip)
2941
{
2942
    struct vax_single *const vsp = (struct vax_single *) ip;
2943
    const struct ieee_single *const isp =
2944
       (const struct ieee_single *) xp;
2945
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
2946
2947
    switch(exp) {
2948
    case 0 :
2949
      /* ieee subnormal */
2950
      if (isp->mant_hi == min.ieee.mant_hi
2951
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
2952
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
2953
      {
2954
        *vsp = min.s;
2955
      }
2956
      else
2957
      {
2958
        unsigned mantissa = (isp->mant_hi << 16)
2959
           | isp->mant_lo_hi << 8
2960
           | isp->mant_lo_lo;
2961
        unsigned tmp = mantissa >> 20;
2962
        if (tmp >= 4) {
2963
          vsp->exp = 2;
2964
        } else if (tmp >= 2) {
2965
          vsp->exp = 1;
2966
        } else {
2967
          *vsp = min.s;
2968
          break;
2969
        } /* else */
2970
        tmp = mantissa - (1 << (20 + vsp->exp ));
2971
        tmp <<= 3 - vsp->exp;
2972
        vsp->mantissa2 = tmp;
2973
        vsp->mantissa1 = (tmp >> 16);
2974
      }
2975
      break;
2976
    case 0xfe :
2977
    case 0xff :
2978
      *vsp = max.s;
2979
      break;
2980
    default :
2981
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
2982
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
2983
      vsp->mantissa1 = isp->mant_hi;
2984
    }
2985
2986
    vsp->sign = isp->sign;
2987
2988
}
2989
2990
2991
static void
2992
put_ix_float(void *xp, const float *ip)
2993
{
2994
    const struct vax_single *const vsp =
2995
       (const struct vax_single *)ip;
2996
    struct ieee_single *const isp = (struct ieee_single *) xp;
2997
2998
    switch(vsp->exp){
2999
    case 0 :
3000
      /* all vax float with zero exponent map to zero */
3001
      *isp = min.ieee;
3002
      break;
3003
    case 2 :
3004
    case 1 :
3005
    {
3006
      /* These will map to subnormals */
3007
      unsigned mantissa = (vsp->mantissa1 << 16)
3008
           | vsp->mantissa2;
3009
      mantissa >>= 3 - vsp->exp;
3010
      mantissa += (1 << (20 + vsp->exp));
3011
      isp->mant_lo_lo = mantissa;
3012
      isp->mant_lo_hi = mantissa >> 8;
3013
      isp->mant_hi = mantissa >> 16;
3014
      isp->exp_lo = 0;
3015
      isp->exp_hi = 0;
3016
    }
3017
      break;
3018
    case 0xff : /* max.s.exp */
3019
      if (vsp->mantissa2 == max.s.mantissa2 &&
3020
          vsp->mantissa1 == max.s.mantissa1)
3021
      {
3022
        /* map largest vax float to ieee infinity */
3023
        *isp = max.ieee;
3024
        break;
3025
      } /* else, fall thru */
3026
    default :
3027
    {
3028
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
3029
      isp->exp_hi = exp >> 1;
3030
      isp->exp_lo = exp;
3031
      isp->mant_lo_lo = vsp->mantissa2;
3032
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
3033
      isp->mant_hi = vsp->mantissa1;
3034
    }
3035
    }
3036
3037
    isp->sign = vsp->sign;
3038
3039
}
3040
3041
  /* vax */
3042
#elif defined(_CRAY) && !defined(__crayx1)
3043
3044
/*
3045
 * Return the number of bytes until the next "word" boundary
3046
 * N.B. This is based on the very weird YMP address structure,
3047
 * which puts the address within a word in the leftmost 3 bits
3048
 * of the address.
3049
 */
3050
static size_t
3051
word_align(const void *vp)
3052
{
3053
  const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
3054
  return (rem != 0);
3055
}
3056
3057
struct ieee_single_hi {
3058
  unsigned int  sign  : 1;
3059
  unsigned int   exp  : 8;
3060
  unsigned int  mant  :23;
3061
  unsigned int  pad :32;
3062
};
3063
typedef struct ieee_single_hi ieee_single_hi;
3064
3065
struct ieee_single_lo {
3066
  unsigned int  pad :32;
3067
  unsigned int  sign  : 1;
3068
  unsigned int   exp  : 8;
3069
  unsigned int  mant  :23;
3070
};
3071
typedef struct ieee_single_lo ieee_single_lo;
3072
3073
static const int ieee_single_bias = 0x7f;
3074
3075
struct ieee_double {
3076
  unsigned int  sign  : 1;
3077
  unsigned int   exp  :11;
3078
  unsigned int  mant  :52;
3079
};
3080
typedef struct ieee_double ieee_double;
3081
3082
static const int ieee_double_bias = 0x3ff;
3083
3084
#if defined(NO_IEEE_FLOAT)
3085
3086
struct cray_single {
3087
  unsigned int  sign  : 1;
3088
  unsigned int   exp  :15;
3089
  unsigned int  mant  :48;
3090
};
3091
typedef struct cray_single cray_single;
3092
3093
static const int cs_ieis_bias = 0x4000 - 0x7f;
3094
3095
static const int cs_id_bias = 0x4000 - 0x3ff;
3096
3097
3098
static void
3099
get_ix_float(const void *xp, float *ip)
3100
{
3101
3102
  if (word_align(xp) == 0)
3103
  {
3104
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3105
    cray_single *csp = (cray_single *) ip;
3106
3107
    if (isp->exp == 0)
3108
    {
3109
      /* ieee subnormal */
3110
      *ip = (double)isp->mant;
3111
      if (isp->mant != 0)
3112
      {
3113
        csp->exp -= (ieee_single_bias + 22);
3114
      }
3115
    }
3116
    else
3117
    {
3118
      csp->exp  = isp->exp + cs_ieis_bias + 1;
3119
      csp->mant = isp->mant << (48 - 1 - 23);
3120
      csp->mant |= (1 << (48 - 1));
3121
    }
3122
    csp->sign = isp->sign;
3123
3124
3125
  }
3126
  else
3127
  {
3128
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3129
    cray_single *csp = (cray_single *) ip;
3130
3131
    if (isp->exp == 0)
3132
    {
3133
      /* ieee subnormal */
3134
      *ip = (double)isp->mant;
3135
      if (isp->mant != 0)
3136
      {
3137
        csp->exp -= (ieee_single_bias + 22);
3138
      }
3139
    }
3140
    else
3141
    {
3142
      csp->exp  = isp->exp + cs_ieis_bias + 1;
3143
      csp->mant = isp->mant << (48 - 1 - 23);
3144
      csp->mant |= (1 << (48 - 1));
3145
    }
3146
    csp->sign = isp->sign;
3147
3148
3149
  }
3150
}
3151
3152
static void
3153
put_ix_float(void *xp, const float *ip)
3154
{
3155
  if (word_align(xp) == 0)
3156
  {
3157
    ieee_single_hi *isp = (ieee_single_hi*)xp;
3158
  const cray_single *csp = (const cray_single *) ip;
3159
  int ieee_exp = csp->exp - cs_ieis_bias -1;
3160
3161
  isp->sign = csp->sign;
3162
3163
  if (ieee_exp >= 0xff)
3164
  {
3165
    /* NC_ERANGE => ieee Inf */
3166
    isp->exp = 0xff;
3167
    isp->mant = 0x0;
3168
  }
3169
  else if (ieee_exp > 0)
3170
  {
3171
    /* normal ieee representation */
3172
    isp->exp  = ieee_exp;
3173
    /* assumes cray rep is in normal form */
3174
    assert(csp->mant & 0x800000000000);
3175
    isp->mant = (((csp->mant << 1) &
3176
        0xffffffffffff) >> (48 - 23));
3177
  }
3178
  else if (ieee_exp > -23)
3179
  {
3180
    /* ieee subnormal, right shift */
3181
    const int rshift = (48 - 23 - ieee_exp);
3182
3183
    isp->mant = csp->mant >> rshift;
3184
3185
#if 0
3186
    if (csp->mant & (1 << (rshift -1)))
3187
    {
3188
      /* round up */
3189
      isp->mant++;
3190
    }
3191
#endif
3192
3193
    isp->exp  = 0;
3194
  }
3195
  else
3196
  {
3197
    /* smaller than ieee can represent */
3198
    isp->exp = 0;
3199
    isp->mant = 0;
3200
  }
3201
3202
  }
3203
  else
3204
  {
3205
    ieee_single_lo *isp = (ieee_single_lo*)xp;
3206
  const cray_single *csp = (const cray_single *) ip;
3207
  int ieee_exp = csp->exp - cs_ieis_bias -1;
3208
3209
  isp->sign = csp->sign;
3210
3211
  if (ieee_exp >= 0xff)
3212
  {
3213
    /* NC_ERANGE => ieee Inf */
3214
    isp->exp = 0xff;
3215
    isp->mant = 0x0;
3216
  }
3217
  else if (ieee_exp > 0)
3218
  {
3219
    /* normal ieee representation */
3220
    isp->exp  = ieee_exp;
3221
    /* assumes cray rep is in normal form */
3222
    assert(csp->mant & 0x800000000000);
3223
    isp->mant = (((csp->mant << 1) &
3224
        0xffffffffffff) >> (48 - 23));
3225
  }
3226
  else if (ieee_exp > -23)
3227
  {
3228
    /* ieee subnormal, right shift */
3229
    const int rshift = (48 - 23 - ieee_exp);
3230
3231
    isp->mant = csp->mant >> rshift;
3232
3233
#if 0
3234
    if (csp->mant & (1 << (rshift -1)))
3235
    {
3236
      /* round up */
3237
      isp->mant++;
3238
    }
3239
#endif
3240
3241
    isp->exp  = 0;
3242
  }
3243
  else
3244
  {
3245
    /* smaller than ieee can represent */
3246
    isp->exp = 0;
3247
    isp->mant = 0;
3248
  }
3249
3250
  }
3251
}
3252
3253
#else
3254
  /* IEEE Cray with only doubles */
3255
static void
3256
get_ix_float(const void *xp, float *ip)
3257
{
3258
3259
  ieee_double *idp = (ieee_double *) ip;
3260
3261
  if (word_align(xp) == 0)
3262
  {
3263
    const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3264
    if (isp->exp == 0 && isp->mant == 0)
3265
    {
3266
      idp->exp = 0;
3267
      idp->mant = 0;
3268
    }
3269
    else
3270
    {
3271
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3272
      idp->mant = isp->mant << (52 - 23);
3273
    }
3274
    idp->sign = isp->sign;
3275
  }
3276
  else
3277
  {
3278
    const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3279
    if (isp->exp == 0 && isp->mant == 0)
3280
    {
3281
      idp->exp = 0;
3282
      idp->mant = 0;
3283
    }
3284
    else
3285
    {
3286
      idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3287
      idp->mant = isp->mant << (52 - 23);
3288
    }
3289
    idp->sign = isp->sign;
3290
  }
3291
}
3292
3293
static void
3294
put_ix_float(void *xp, const float *ip)
3295
{
3296
  const ieee_double *idp = (const ieee_double *) ip;
3297
  if (word_align(xp) == 0)
3298
  {
3299
    ieee_single_hi *isp = (ieee_single_hi*)xp;
3300
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3301
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3302
    else
3303
      isp->exp = 0;
3304
    isp->mant = idp->mant >> (52 - 23);
3305
    isp->sign = idp->sign;
3306
  }
3307
  else
3308
  {
3309
    ieee_single_lo *isp = (ieee_single_lo*)xp;
3310
    if (idp->exp > (ieee_double_bias - ieee_single_bias))
3311
      isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3312
    else
3313
      isp->exp = 0;
3314
    isp->mant = idp->mant >> (52 - 23);
3315
    isp->sign = idp->sign;
3316
  }
3317
}
3318
#endif
3319
3320
#else
3321
#error "ix_float implementation"
3322
#endif
3323
3324
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3325
static int
3326
ncx_get_float_float(const void *xp, float *ip, void *fillp)
3327
{
3328
  /* TODO */
3329
  get_ix_float(xp, ip);
3330
  return NC_NOERR;
3331
}
3332
#endif
3333
3334
0
#define ix_float float
3335
3336
static int
3337
ncx_get_float_schar(const void *xp, schar *ip)
3338
0
{
3339
0
  ix_float xx = 0;
3340
0
  get_ix_float(xp, &xx);
3341
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3342
#ifdef ERANGE_FILL
3343
            *ip = NC_FILL_BYTE;
3344
#endif
3345
0
            return NC_ERANGE;
3346
0
        }
3347
0
  *ip = (schar)xx;
3348
0
  return NC_NOERR;
3349
0
}
3350
3351
static int
3352
ncx_get_float_short(const void *xp, short *ip)
3353
0
{
3354
0
  ix_float xx = 0;
3355
0
  get_ix_float(xp, &xx);
3356
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3357
#ifdef ERANGE_FILL
3358
            *ip = NC_FILL_SHORT;
3359
#endif
3360
0
            return NC_ERANGE;
3361
0
        }
3362
0
  *ip = (short)xx;
3363
0
  return NC_NOERR;
3364
0
}
3365
3366
static int
3367
ncx_get_float_int(const void *xp, int *ip)
3368
0
{
3369
0
  ix_float xx = 0;
3370
0
  get_ix_float(xp, &xx);
3371
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3372
#ifdef ERANGE_FILL
3373
            *ip = NC_FILL_INT;
3374
#endif
3375
0
            return NC_ERANGE;
3376
0
        }
3377
0
  *ip = (int)xx;
3378
0
  return NC_NOERR;
3379
0
}
3380
3381
static int
3382
ncx_get_float_long(const void *xp, long *ip)
3383
0
{
3384
0
  ix_float xx = 0;
3385
0
  get_ix_float(xp, &xx);
3386
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3387
#ifdef ERANGE_FILL
3388
            *ip = NC_FILL_INT;
3389
#endif
3390
0
            return NC_ERANGE;
3391
0
        }
3392
0
  *ip = (long)xx;
3393
0
  return NC_NOERR;
3394
0
}
3395
3396
static int
3397
ncx_get_float_double(const void *xp, double *ip)
3398
0
{
3399
0
  ix_float xx = 0;
3400
0
  get_ix_float(xp, &xx);
3401
0
  *ip = (double)xx;
3402
0
  return NC_NOERR;
3403
0
}
3404
3405
static int
3406
ncx_get_float_longlong(const void *xp, longlong *ip)
3407
0
{
3408
0
  ix_float xx = 0;
3409
0
  get_ix_float(xp, &xx);
3410
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3411
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3412
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3413
#ifdef ERANGE_FILL
3414
            *ip = NC_FILL_INT64;
3415
#endif
3416
0
            return NC_ERANGE;
3417
0
        }
3418
0
  else *ip = (longlong)xx;
3419
0
  return NC_NOERR;
3420
0
}
3421
3422
static int
3423
ncx_get_float_uchar(const void *xp, uchar *ip)
3424
0
{
3425
0
  ix_float xx = 0;
3426
0
  get_ix_float(xp, &xx);
3427
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3428
#ifdef ERANGE_FILL
3429
            *ip = NC_FILL_UBYTE;
3430
#endif
3431
0
            return NC_ERANGE;
3432
0
        }
3433
0
  *ip = (uchar)xx;
3434
0
  return NC_NOERR;
3435
0
}
3436
3437
static int
3438
ncx_get_float_ushort(const void *xp, ushort *ip)
3439
0
{
3440
0
  ix_float xx = 0;
3441
0
  get_ix_float(xp, &xx);
3442
0
  if (xx > (double)USHORT_MAX || xx < 0) {
3443
#ifdef ERANGE_FILL
3444
            *ip = NC_FILL_USHORT;
3445
#endif
3446
0
            return NC_ERANGE;
3447
0
        }
3448
0
  *ip = (ushort)xx;
3449
0
  return NC_NOERR;
3450
0
}
3451
3452
static int
3453
ncx_get_float_uint(const void *xp, uint *ip)
3454
0
{
3455
0
  ix_float xx = 0;
3456
0
  get_ix_float(xp, &xx);
3457
0
  if (xx > (double)UINT_MAX || xx < 0) {
3458
#ifdef ERANGE_FILL
3459
            *ip = NC_FILL_UINT;
3460
#endif
3461
0
            return NC_ERANGE;
3462
0
        }
3463
0
  *ip = (uint)xx;
3464
0
  return NC_NOERR;
3465
0
}
3466
3467
static int
3468
ncx_get_float_ulonglong(const void *xp, ulonglong *ip)
3469
0
{
3470
0
  ix_float xx = 0;
3471
0
  get_ix_float(xp, &xx);
3472
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3473
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3474
#ifdef ERANGE_FILL
3475
            *ip = NC_FILL_UINT64;
3476
#endif
3477
0
            return NC_ERANGE;
3478
0
        }
3479
0
  else *ip = (ulonglong)xx;
3480
0
  return NC_NOERR;
3481
0
}
3482
3483
3484
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3485
static int
3486
ncx_put_float_float(void *xp, const float *ip, void *fillp)
3487
{
3488
    int err=NC_NOERR;
3489
    float *_ip=ip;
3490
#ifdef NO_IEEE_FLOAT
3491
#ifdef ERANGE_FILL
3492
    float tmp;
3493
#endif
3494
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3495
        
3496
#ifdef ERANGE_FILL
3497
            if (fillp != NULL) memcpy(&tmp, fillp, 4);
3498
#endif
3499
#ifdef ERANGE_FILL
3500
        _ip = &tmp;
3501
#endif
3502
        err = NC_ERANGE;
3503
    }
3504
#endif
3505
    put_ix_float(xp, _ip);
3506
    return err;
3507
}
3508
#endif
3509
3510
static int
3511
ncx_put_float_schar(void *xp, const schar *ip, void *fillp)
3512
0
{
3513
0
    int err=NC_NOERR;
3514
0
    ix_float xx = NC_FILL_FLOAT;
3515
3516
    
3517
0
        xx = (ix_float)*ip;
3518
3519
0
    put_ix_float(xp, &xx);
3520
0
    return err;
3521
0
}
3522
3523
static int
3524
ncx_put_float_short(void *xp, const short *ip, void *fillp)
3525
0
{
3526
0
    int err=NC_NOERR;
3527
0
    ix_float xx = NC_FILL_FLOAT;
3528
3529
    
3530
0
        xx = (ix_float)*ip;
3531
3532
0
    put_ix_float(xp, &xx);
3533
0
    return err;
3534
0
}
3535
3536
static int
3537
ncx_put_float_int(void *xp, const int *ip, void *fillp)
3538
0
{
3539
0
    int err=NC_NOERR;
3540
0
    ix_float xx = NC_FILL_FLOAT;
3541
3542
    
3543
0
        xx = (ix_float)*ip;
3544
3545
0
    put_ix_float(xp, &xx);
3546
0
    return err;
3547
0
}
3548
3549
static int
3550
ncx_put_float_long(void *xp, const long *ip, void *fillp)
3551
0
{
3552
0
    int err=NC_NOERR;
3553
0
    ix_float xx = NC_FILL_FLOAT;
3554
3555
    
3556
0
        xx = (ix_float)*ip;
3557
3558
0
    put_ix_float(xp, &xx);
3559
0
    return err;
3560
0
}
3561
3562
static int
3563
ncx_put_float_double(void *xp, const double *ip, void *fillp)
3564
0
{
3565
0
    int err=NC_NOERR;
3566
0
    ix_float xx = NC_FILL_FLOAT;
3567
3568
0
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3569
        
3570
#ifdef ERANGE_FILL
3571
            if (fillp != NULL) memcpy(&xx, fillp, 4);
3572
#endif
3573
0
        err = NC_ERANGE;
3574
0
    }
3575
#ifdef ERANGE_FILL
3576
    else
3577
#endif
3578
0
        xx = (ix_float)*ip;
3579
3580
0
    put_ix_float(xp, &xx);
3581
0
    return err;
3582
0
}
3583
3584
static int
3585
ncx_put_float_longlong(void *xp, const longlong *ip, void *fillp)
3586
0
{
3587
0
    int err=NC_NOERR;
3588
0
    ix_float xx = NC_FILL_FLOAT;
3589
3590
    
3591
0
        xx = (ix_float)*ip;
3592
3593
0
    put_ix_float(xp, &xx);
3594
0
    return err;
3595
0
}
3596
3597
static int
3598
ncx_put_float_uchar(void *xp, const uchar *ip, void *fillp)
3599
0
{
3600
0
    int err=NC_NOERR;
3601
0
    ix_float xx = NC_FILL_FLOAT;
3602
3603
    
3604
0
        xx = (ix_float)*ip;
3605
3606
0
    put_ix_float(xp, &xx);
3607
0
    return err;
3608
0
}
3609
3610
static int
3611
ncx_put_float_ushort(void *xp, const ushort *ip, void *fillp)
3612
0
{
3613
0
    int err=NC_NOERR;
3614
0
    ix_float xx = NC_FILL_FLOAT;
3615
3616
    
3617
0
        xx = (ix_float)*ip;
3618
3619
0
    put_ix_float(xp, &xx);
3620
0
    return err;
3621
0
}
3622
3623
static int
3624
ncx_put_float_uint(void *xp, const uint *ip, void *fillp)
3625
0
{
3626
0
    int err=NC_NOERR;
3627
0
    ix_float xx = NC_FILL_FLOAT;
3628
3629
    
3630
0
        xx = (ix_float)*ip;
3631
3632
0
    put_ix_float(xp, &xx);
3633
0
    return err;
3634
0
}
3635
3636
static int
3637
ncx_put_float_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3638
0
{
3639
0
    int err=NC_NOERR;
3640
0
    ix_float xx = NC_FILL_FLOAT;
3641
3642
    
3643
0
        xx = (ix_float)*ip;
3644
3645
0
    put_ix_float(xp, &xx);
3646
0
    return err;
3647
0
}
3648
3649
3650
3651
/* external NC_DOUBLE -------------------------------------------------------*/
3652
3653
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
3654
3655
static void
3656
get_ix_double(const void *xp, double *ip)
3657
0
{
3658
#ifdef WORDS_BIGENDIAN
3659
  (void) memcpy(ip, xp, SIZEOF_DOUBLE);
3660
#else
3661
0
  swap8b(ip, xp);
3662
0
#endif
3663
0
}
3664
3665
static void
3666
put_ix_double(void *xp, const double *ip)
3667
0
{
3668
#ifdef WORDS_BIGENDIAN
3669
  (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
3670
#else
3671
0
  swap8b(xp, ip);
3672
0
#endif
3673
0
}
3674
3675
#elif defined(vax) && vax != 0
3676
3677
/* What IEEE double precision floating point looks like on a Vax */
3678
struct  ieee_double {
3679
  unsigned int  exp_hi   : 7;
3680
  unsigned int  sign     : 1;
3681
  unsigned int  mant_6   : 4;
3682
  unsigned int  exp_lo   : 4;
3683
  unsigned int  mant_5   : 8;
3684
  unsigned int  mant_4   : 8;
3685
3686
  unsigned int  mant_lo  : 32;
3687
};
3688
3689
/* Vax double precision floating point */
3690
struct  vax_double {
3691
  unsigned int  mantissa1 : 7;
3692
  unsigned int  exp       : 8;
3693
  unsigned int  sign      : 1;
3694
  unsigned int  mantissa2 : 16;
3695
  unsigned int  mantissa3 : 16;
3696
  unsigned int  mantissa4 : 16;
3697
};
3698
3699
#define VAX_DBL_BIAS  0x81
3700
#define IEEE_DBL_BIAS 0x3ff
3701
#define MASK(nbits) ((1 << nbits) - 1)
3702
3703
static const struct dbl_limits {
3704
  struct  vax_double d;
3705
  struct  ieee_double ieee;
3706
} dbl_limits[2] = {
3707
  {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
3708
  { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
3709
  {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},   /* Min Vax */
3710
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
3711
};
3712
3713
3714
static void
3715
get_ix_double(const void *xp, double *ip)
3716
{
3717
  struct vax_double *const vdp =
3718
       (struct vax_double *)ip;
3719
  const struct ieee_double *const idp =
3720
       (const struct ieee_double *) xp;
3721
  {
3722
    const struct dbl_limits *lim;
3723
    int ii;
3724
    for (ii = 0, lim = dbl_limits;
3725
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
3726
      ii++, lim++)
3727
    {
3728
      if ((idp->mant_lo == lim->ieee.mant_lo)
3729
        && (idp->mant_4 == lim->ieee.mant_4)
3730
        && (idp->mant_5 == lim->ieee.mant_5)
3731
        && (idp->mant_6 == lim->ieee.mant_6)
3732
        && (idp->exp_lo == lim->ieee.exp_lo)
3733
        && (idp->exp_hi == lim->ieee.exp_hi)
3734
        )
3735
      {
3736
        *vdp = lim->d;
3737
        goto doneit;
3738
      }
3739
    }
3740
  }
3741
  {
3742
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
3743
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
3744
  }
3745
  {
3746
    unsigned mant_hi = ((idp->mant_6 << 16)
3747
         | (idp->mant_5 << 8)
3748
         | idp->mant_4);
3749
    unsigned mant_lo = SWAP4(idp->mant_lo);
3750
    vdp->mantissa1 = (mant_hi >> 13);
3751
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
3752
        | (mant_lo >> 29);
3753
    vdp->mantissa3 = (mant_lo >> 13);
3754
    vdp->mantissa4 = (mant_lo << 3);
3755
  }
3756
  doneit:
3757
    vdp->sign = idp->sign;
3758
3759
}
3760
3761
3762
static void
3763
put_ix_double(void *xp, const double *ip)
3764
{
3765
  const struct vax_double *const vdp =
3766
      (const struct vax_double *)ip;
3767
  struct ieee_double *const idp =
3768
       (struct ieee_double *) xp;
3769
3770
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
3771
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
3772
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
3773
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
3774
    (vdp->exp == dbl_limits[0].d.exp))
3775
  {
3776
    *idp = dbl_limits[0].ieee;
3777
    goto shipit;
3778
  }
3779
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
3780
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
3781
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
3782
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
3783
    (vdp->exp == dbl_limits[1].d.exp))
3784
  {
3785
    *idp = dbl_limits[1].ieee;
3786
    goto shipit;
3787
  }
3788
3789
  {
3790
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
3791
3792
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
3793
      (vdp->mantissa3 << 13) |
3794
      ((vdp->mantissa4 >> 3) & MASK(13));
3795
3796
    unsigned mant_hi = (vdp->mantissa1 << 13)
3797
         | (vdp->mantissa2 >> 3);
3798
3799
    if ((vdp->mantissa4 & 7) > 4)
3800
    {
3801
      /* round up */
3802
      mant_lo++;
3803
      if (mant_lo == 0)
3804
      {
3805
        mant_hi++;
3806
        if (mant_hi > 0xffffff)
3807
        {
3808
          mant_hi = 0;
3809
          exp++;
3810
        }
3811
      }
3812
    }
3813
3814
    idp->mant_lo = SWAP4(mant_lo);
3815
    idp->mant_6 = mant_hi >> 16;
3816
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
3817
    idp->mant_4 = mant_hi;
3818
    idp->exp_hi = exp >> 4;
3819
    idp->exp_lo = exp;
3820
  }
3821
3822
  shipit:
3823
    idp->sign = vdp->sign;
3824
3825
}
3826
3827
  /* vax */
3828
#elif defined(_CRAY) && !defined(__crayx1)
3829
3830
static void
3831
get_ix_double(const void *xp, double *ip)
3832
{
3833
  const ieee_double *idp = (const ieee_double *) xp;
3834
  cray_single *csp = (cray_single *) ip;
3835
3836
  if (idp->exp == 0)
3837
  {
3838
    /* ieee subnormal */
3839
    *ip = (double)idp->mant;
3840
    if (idp->mant != 0)
3841
    {
3842
      csp->exp -= (ieee_double_bias + 51);
3843
    }
3844
  }
3845
  else
3846
  {
3847
    csp->exp  = idp->exp + cs_id_bias + 1;
3848
    csp->mant = idp->mant >> (52 - 48 + 1);
3849
    csp->mant |= (1 << (48 - 1));
3850
  }
3851
  csp->sign = idp->sign;
3852
}
3853
3854
static void
3855
put_ix_double(void *xp, const double *ip)
3856
{
3857
  ieee_double *idp = (ieee_double *) xp;
3858
  const cray_single *csp = (const cray_single *) ip;
3859
3860
  int ieee_exp = csp->exp - cs_id_bias -1;
3861
3862
  idp->sign = csp->sign;
3863
3864
  if (ieee_exp >= 0x7ff)
3865
  {
3866
    /* NC_ERANGE => ieee Inf */
3867
    idp->exp = 0x7ff;
3868
    idp->mant = 0x0;
3869
  }
3870
  else if (ieee_exp > 0)
3871
  {
3872
    /* normal ieee representation */
3873
    idp->exp  = ieee_exp;
3874
    /* assumes cray rep is in normal form */
3875
    assert(csp->mant & 0x800000000000);
3876
    idp->mant = (((csp->mant << 1) &
3877
        0xffffffffffff) << (52 - 48));
3878
  }
3879
  else if (ieee_exp >= (-(52 -48)))
3880
  {
3881
    /* ieee subnormal, left shift */
3882
    const int lshift = (52 - 48) + ieee_exp;
3883
    idp->mant = csp->mant << lshift;
3884
    idp->exp  = 0;
3885
  }
3886
  else if (ieee_exp >= -52)
3887
  {
3888
    /* ieee subnormal, right shift */
3889
    const int rshift = (- (52 - 48) - ieee_exp);
3890
3891
    idp->mant = csp->mant >> rshift;
3892
3893
#if 0
3894
    if (csp->mant & (1 << (rshift -1)))
3895
    {
3896
      /* round up */
3897
      idp->mant++;
3898
    }
3899
#endif
3900
3901
    idp->exp  = 0;
3902
  }
3903
  else
3904
  {
3905
    /* smaller than ieee can represent */
3906
    idp->exp = 0;
3907
    idp->mant = 0;
3908
  }
3909
}
3910
#else
3911
#error "ix_double implementation"
3912
#endif
3913
3914
0
#define ix_double double
3915
3916
static int
3917
ncx_get_double_schar(const void *xp, schar *ip)
3918
0
{
3919
0
  ix_double xx = 0;
3920
0
  get_ix_double(xp, &xx);
3921
0
  if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3922
#ifdef ERANGE_FILL
3923
            *ip = NC_FILL_BYTE;
3924
#endif
3925
0
            return NC_ERANGE;
3926
0
        }
3927
0
  *ip = (schar)xx;
3928
0
  return NC_NOERR;
3929
0
}
3930
3931
static int
3932
ncx_get_double_short(const void *xp, short *ip)
3933
0
{
3934
0
  ix_double xx = 0;
3935
0
  get_ix_double(xp, &xx);
3936
0
  if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3937
#ifdef ERANGE_FILL
3938
            *ip = NC_FILL_SHORT;
3939
#endif
3940
0
            return NC_ERANGE;
3941
0
        }
3942
0
  *ip = (short)xx;
3943
0
  return NC_NOERR;
3944
0
}
3945
3946
static int
3947
ncx_get_double_int(const void *xp, int *ip)
3948
0
{
3949
0
  ix_double xx = 0;
3950
0
  get_ix_double(xp, &xx);
3951
0
  if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3952
#ifdef ERANGE_FILL
3953
            *ip = NC_FILL_INT;
3954
#endif
3955
0
            return NC_ERANGE;
3956
0
        }
3957
0
  *ip = (int)xx;
3958
0
  return NC_NOERR;
3959
0
}
3960
3961
static int
3962
ncx_get_double_long(const void *xp, long *ip)
3963
0
{
3964
0
  ix_double xx = 0;
3965
0
  get_ix_double(xp, &xx);
3966
0
  if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3967
#ifdef ERANGE_FILL
3968
            *ip = NC_FILL_INT;
3969
#endif
3970
0
            return NC_ERANGE;
3971
0
        }
3972
0
  *ip = (long)xx;
3973
0
  return NC_NOERR;
3974
0
}
3975
3976
static int
3977
ncx_get_double_longlong(const void *xp, longlong *ip)
3978
0
{
3979
0
  ix_double xx = 0;
3980
0
  get_ix_double(xp, &xx);
3981
0
  if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3982
0
  else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3983
0
  else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3984
#ifdef ERANGE_FILL
3985
            *ip = NC_FILL_INT64;
3986
#endif
3987
0
            return NC_ERANGE;
3988
0
        }
3989
0
  else *ip = (longlong)xx;
3990
0
  return NC_NOERR;
3991
0
}
3992
3993
static int
3994
ncx_get_double_uchar(const void *xp, uchar *ip)
3995
0
{
3996
0
  ix_double xx = 0;
3997
0
  get_ix_double(xp, &xx);
3998
0
  if (xx > (double)UCHAR_MAX || xx < 0) {
3999
#ifdef ERANGE_FILL
4000
            *ip = NC_FILL_UBYTE;
4001
#endif
4002
0
            return NC_ERANGE;
4003
0
        }
4004
0
  *ip = (uchar)xx;
4005
0
  return NC_NOERR;
4006
0
}
4007
4008
static int
4009
ncx_get_double_ushort(const void *xp, ushort *ip)
4010
0
{
4011
0
  ix_double xx = 0;
4012
0
  get_ix_double(xp, &xx);
4013
0
  if (xx > (double)USHORT_MAX || xx < 0) {
4014
#ifdef ERANGE_FILL
4015
            *ip = NC_FILL_USHORT;
4016
#endif
4017
0
            return NC_ERANGE;
4018
0
        }
4019
0
  *ip = (ushort)xx;
4020
0
  return NC_NOERR;
4021
0
}
4022
4023
static int
4024
ncx_get_double_uint(const void *xp, uint *ip)
4025
0
{
4026
0
  ix_double xx = 0;
4027
0
  get_ix_double(xp, &xx);
4028
0
  if (xx > (double)UINT_MAX || xx < 0) {
4029
#ifdef ERANGE_FILL
4030
            *ip = NC_FILL_UINT;
4031
#endif
4032
0
            return NC_ERANGE;
4033
0
        }
4034
0
  *ip = (uint)xx;
4035
0
  return NC_NOERR;
4036
0
}
4037
4038
static int
4039
ncx_get_double_ulonglong(const void *xp, ulonglong *ip)
4040
0
{
4041
0
  ix_double xx = 0;
4042
0
  get_ix_double(xp, &xx);
4043
0
  if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
4044
0
  else if (xx > (double)ULONGLONG_MAX || xx < 0) {
4045
#ifdef ERANGE_FILL
4046
            *ip = NC_FILL_UINT64;
4047
#endif
4048
0
            return NC_ERANGE;
4049
0
        }
4050
0
  else *ip = (ulonglong)xx;
4051
0
  return NC_NOERR;
4052
0
}
4053
4054
4055
static int
4056
ncx_get_double_float(const void *xp, float *ip)
4057
0
{
4058
0
    double xx = 0.0;
4059
0
    get_ix_double(xp, &xx);
4060
0
    if (xx > FLT_MAX) {
4061
#ifdef ERANGE_FILL
4062
        *ip = NC_FILL_FLOAT;
4063
#else
4064
0
        *ip = FLT_MAX;
4065
0
#endif
4066
0
        return NC_ERANGE;
4067
0
    }
4068
0
    if (xx < (-FLT_MAX)) {
4069
#ifdef ERANGE_FILL
4070
        *ip = NC_FILL_FLOAT;
4071
#else
4072
0
        *ip = (-FLT_MAX);
4073
0
#endif
4074
0
        return NC_ERANGE;
4075
0
    }
4076
0
    *ip = (float) xx;
4077
0
    return NC_NOERR;
4078
0
}
4079
4080
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4081
static int
4082
ncx_get_double_double(const void *xp, double *ip, void *fillp)
4083
{
4084
  /* TODO */
4085
  get_ix_double(xp, ip);
4086
  return NC_NOERR;
4087
}
4088
#endif
4089
4090
static int
4091
ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
4092
0
{
4093
0
    int err=NC_NOERR;
4094
0
    ix_double xx = NC_FILL_DOUBLE;
4095
4096
    
4097
0
        xx = (ix_double)*ip;
4098
4099
0
    put_ix_double(xp, &xx);
4100
0
    return err;
4101
0
}
4102
4103
static int
4104
ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
4105
0
{
4106
0
    int err=NC_NOERR;
4107
0
    ix_double xx = NC_FILL_DOUBLE;
4108
4109
    
4110
0
        xx = (ix_double)*ip;
4111
4112
0
    put_ix_double(xp, &xx);
4113
0
    return err;
4114
0
}
4115
4116
static int
4117
ncx_put_double_short(void *xp, const short *ip, void *fillp)
4118
0
{
4119
0
    int err=NC_NOERR;
4120
0
    ix_double xx = NC_FILL_DOUBLE;
4121
4122
    
4123
0
        xx = (ix_double)*ip;
4124
4125
0
    put_ix_double(xp, &xx);
4126
0
    return err;
4127
0
}
4128
4129
static int
4130
ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
4131
0
{
4132
0
    int err=NC_NOERR;
4133
0
    ix_double xx = NC_FILL_DOUBLE;
4134
4135
    
4136
0
        xx = (ix_double)*ip;
4137
4138
0
    put_ix_double(xp, &xx);
4139
0
    return err;
4140
0
}
4141
4142
static int
4143
ncx_put_double_int(void *xp, const int *ip, void *fillp)
4144
0
{
4145
0
    int err=NC_NOERR;
4146
0
    ix_double xx = NC_FILL_DOUBLE;
4147
4148
    
4149
0
        xx = (ix_double)*ip;
4150
4151
0
    put_ix_double(xp, &xx);
4152
0
    return err;
4153
0
}
4154
4155
static int
4156
ncx_put_double_long(void *xp, const long *ip, void *fillp)
4157
0
{
4158
0
    int err=NC_NOERR;
4159
0
    ix_double xx = NC_FILL_DOUBLE;
4160
4161
    
4162
0
        xx = (ix_double)*ip;
4163
4164
0
    put_ix_double(xp, &xx);
4165
0
    return err;
4166
0
}
4167
4168
static int
4169
ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
4170
0
{
4171
0
    int err=NC_NOERR;
4172
0
    ix_double xx = NC_FILL_DOUBLE;
4173
4174
    
4175
0
        xx = (ix_double)*ip;
4176
4177
0
    put_ix_double(xp, &xx);
4178
0
    return err;
4179
0
}
4180
4181
static int
4182
ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
4183
0
{
4184
0
    int err=NC_NOERR;
4185
0
    ix_double xx = NC_FILL_DOUBLE;
4186
4187
    
4188
0
        xx = (ix_double)*ip;
4189
4190
0
    put_ix_double(xp, &xx);
4191
0
    return err;
4192
0
}
4193
4194
static int
4195
ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4196
0
{
4197
0
    int err=NC_NOERR;
4198
0
    ix_double xx = NC_FILL_DOUBLE;
4199
4200
    
4201
0
        xx = (ix_double)*ip;
4202
4203
0
    put_ix_double(xp, &xx);
4204
0
    return err;
4205
0
}
4206
4207
4208
static int
4209
ncx_put_double_float(void *xp, const float *ip, void *fillp)
4210
0
{
4211
0
    int err=NC_NOERR;
4212
0
    double xx = NC_FILL_DOUBLE;
4213
0
#if 1 /* TODO: figure this out (if condition below will never be true)*/
4214
0
    if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
4215
        
4216
#ifdef ERANGE_FILL
4217
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4218
#endif
4219
0
        err = NC_ERANGE;
4220
0
    }
4221
#ifdef ERANGE_FILL
4222
    else
4223
#endif
4224
0
#endif
4225
0
        xx = (double) *ip;
4226
4227
0
    put_ix_double(xp, &xx);
4228
0
    return err;
4229
0
}
4230
4231
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4232
static int
4233
ncx_put_double_double(void *xp, const double *ip, void *fillp)
4234
{
4235
    int err=NC_NOERR;
4236
    double *_ip = ip;
4237
#ifdef NO_IEEE_FLOAT
4238
#ifdef ERANGE_FILL
4239
    double tmp=NC_FILL_DOUBLE;
4240
#endif
4241
    if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
4242
        
4243
#ifdef ERANGE_FILL
4244
            if (fillp != NULL) memcpy(&tmp, fillp, 8);
4245
#endif
4246
#ifdef ERANGE_FILL
4247
        _ip = &tmp;
4248
#endif
4249
        err = NC_ERANGE;
4250
    }
4251
#endif
4252
    put_ix_double(xp, _ip);
4253
    return err;
4254
}
4255
#endif
4256
4257
4258
/* external NC_INT64 --------------------------------------------------------*/
4259
4260
#if SHORT_MAX == X_INT64_MAX
4261
typedef short ix_int64;
4262
#define SIZEOF_IX_INT64 SIZEOF_SHORT
4263
#define IX_INT64_MAX SHORT_MAX
4264
#elif LONG_LONG_MAX  >= X_INT64_MAX
4265
typedef longlong ix_int64;
4266
#define SIZEOF_IX_INT64 SIZEOF_LONGLONG
4267
0
#define IX_INT64_MAX LONG_LONG_MAX
4268
#elif LONG_MAX  >= X_INT64_MAX
4269
typedef long ix_int64;
4270
#define SIZEOF_IX_INT64 SIZEOF_LONG
4271
#define IX_INT64_MAX LONG_MAX
4272
#else
4273
#error "ix_int64 implementation"
4274
#endif
4275
4276
4277
static void
4278
get_ix_int64(const void *xp, ix_int64 *ip)
4279
79.1k
{
4280
79.1k
    const uchar *cp = (const uchar *) xp;
4281
4282
79.1k
    *ip  = ((ix_int64)(*cp++) << 56);
4283
79.1k
    *ip |= ((ix_int64)(*cp++) << 48);
4284
79.1k
    *ip |= ((ix_int64)(*cp++) << 40);
4285
79.1k
    *ip |= ((ix_int64)(*cp++) << 32);
4286
79.1k
    *ip |= ((ix_int64)(*cp++) << 24);
4287
79.1k
    *ip |= ((ix_int64)(*cp++) << 16);
4288
79.1k
    *ip |= ((ix_int64)(*cp++) <<  8);
4289
79.1k
    *ip |=  (ix_int64)*cp;
4290
79.1k
}
4291
4292
static void
4293
put_ix_int64(void *xp, const ix_int64 *ip)
4294
0
{
4295
0
    uchar *cp = (uchar *) xp;
4296
4297
0
    *cp++ = (uchar)((*ip) >> 56);
4298
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48);
4299
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40);
4300
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32);
4301
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24);
4302
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16);
4303
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >>  8);
4304
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffLL);
4305
0
}
4306
4307
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4308
static int
4309
ncx_get_longlong_longlong(const void *xp, longlong *ip)
4310
{
4311
    int err=NC_NOERR;
4312
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4313
    get_ix_int64(xp, (ix_int64 *)ip);
4314
#else
4315
    ix_int64 xx = 0;
4316
    get_ix_int64(xp, &xx);
4317
4318
#if IX_INT64_MAX > LONGLONG_MAX
4319
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
4320
#ifdef ERANGE_FILL
4321
        *ip = NC_FILL_INT64;
4322
        return NC_ERANGE;
4323
#else
4324
        err = NC_ERANGE;
4325
#endif
4326
    }
4327
#endif
4328
4329
4330
    *ip = (longlong) xx;
4331
#endif
4332
    return err;
4333
}
4334
4335
#endif
4336
static int
4337
ncx_get_longlong_schar(const void *xp, schar *ip)
4338
0
{
4339
0
    int err=NC_NOERR;
4340
0
    ix_int64 xx = 0;
4341
0
    get_ix_int64(xp, &xx);
4342
4343
0
#if IX_INT64_MAX > SCHAR_MAX
4344
0
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
4345
#ifdef ERANGE_FILL
4346
        *ip = NC_FILL_BYTE;
4347
        return NC_ERANGE;
4348
#else
4349
0
        err = NC_ERANGE;
4350
0
#endif
4351
0
    }
4352
0
#endif
4353
4354
4355
0
    *ip = (schar) xx;
4356
0
    return err;
4357
0
}
4358
4359
static int
4360
ncx_get_longlong_short(const void *xp, short *ip)
4361
0
{
4362
0
    int err=NC_NOERR;
4363
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4364
    get_ix_int64(xp, (ix_int64 *)ip);
4365
#else
4366
0
    ix_int64 xx = 0;
4367
0
    get_ix_int64(xp, &xx);
4368
4369
0
#if IX_INT64_MAX > SHORT_MAX
4370
0
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
4371
#ifdef ERANGE_FILL
4372
        *ip = NC_FILL_SHORT;
4373
        return NC_ERANGE;
4374
#else
4375
0
        err = NC_ERANGE;
4376
0
#endif
4377
0
    }
4378
0
#endif
4379
4380
4381
0
    *ip = (short) xx;
4382
0
#endif
4383
0
    return err;
4384
0
}
4385
4386
static int
4387
ncx_get_longlong_int(const void *xp, int *ip)
4388
79.1k
{
4389
79.1k
    int err=NC_NOERR;
4390
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4391
    get_ix_int64(xp, (ix_int64 *)ip);
4392
#else
4393
79.1k
    ix_int64 xx = 0;
4394
79.1k
    get_ix_int64(xp, &xx);
4395
4396
79.1k
#if IX_INT64_MAX > INT_MAX
4397
79.1k
    if (xx > INT_MAX || xx < INT_MIN) {
4398
#ifdef ERANGE_FILL
4399
        *ip = NC_FILL_INT;
4400
        return NC_ERANGE;
4401
#else
4402
35.9k
        err = NC_ERANGE;
4403
35.9k
#endif
4404
35.9k
    }
4405
79.1k
#endif
4406
4407
4408
79.1k
    *ip = (int) xx;
4409
79.1k
#endif
4410
79.1k
    return err;
4411
79.1k
}
4412
4413
static int
4414
ncx_get_longlong_long(const void *xp, long *ip)
4415
0
{
4416
0
    int err=NC_NOERR;
4417
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4418
0
    get_ix_int64(xp, (ix_int64 *)ip);
4419
#else
4420
    ix_int64 xx = 0;
4421
    get_ix_int64(xp, &xx);
4422
4423
#if IX_INT64_MAX > LONG_MAX
4424
    if (xx > LONG_MAX || xx < LONG_MIN) {
4425
#ifdef ERANGE_FILL
4426
        *ip = NC_FILL_INT;
4427
        return NC_ERANGE;
4428
#else
4429
        err = NC_ERANGE;
4430
#endif
4431
    }
4432
#endif
4433
4434
4435
    *ip = (long) xx;
4436
#endif
4437
0
    return err;
4438
0
}
4439
4440
static int
4441
ncx_get_longlong_ushort(const void *xp, ushort *ip)
4442
0
{
4443
0
    int err=NC_NOERR;
4444
0
    ix_int64 xx = 0;
4445
0
    get_ix_int64(xp, &xx);
4446
4447
0
#if IX_INT64_MAX > USHORT_MAX
4448
0
    if (xx > USHORT_MAX) {
4449
#ifdef ERANGE_FILL
4450
        *ip = NC_FILL_USHORT;
4451
        return NC_ERANGE;
4452
#else
4453
0
        err = NC_ERANGE;
4454
0
#endif
4455
0
    }
4456
0
#endif
4457
4458
0
    if (xx < 0) {
4459
#ifdef ERANGE_FILL
4460
        *ip = NC_FILL_USHORT;
4461
        return NC_ERANGE;
4462
#else
4463
0
        err = NC_ERANGE; /* because ip is unsigned */
4464
0
#endif
4465
0
    }
4466
0
    *ip = (ushort) xx;
4467
0
    return err;
4468
0
}
4469
4470
static int
4471
ncx_get_longlong_uchar(const void *xp, uchar *ip)
4472
0
{
4473
0
    int err=NC_NOERR;
4474
0
    ix_int64 xx = 0;
4475
0
    get_ix_int64(xp, &xx);
4476
4477
0
#if IX_INT64_MAX > UCHAR_MAX
4478
0
    if (xx > UCHAR_MAX) {
4479
#ifdef ERANGE_FILL
4480
        *ip = NC_FILL_UBYTE;
4481
        return NC_ERANGE;
4482
#else
4483
0
        err = NC_ERANGE;
4484
0
#endif
4485
0
    }
4486
0
#endif
4487
4488
0
    if (xx < 0) {
4489
#ifdef ERANGE_FILL
4490
        *ip = NC_FILL_UBYTE;
4491
        return NC_ERANGE;
4492
#else
4493
0
        err = NC_ERANGE; /* because ip is unsigned */
4494
0
#endif
4495
0
    }
4496
0
    *ip = (uchar) xx;
4497
0
    return err;
4498
0
}
4499
4500
static int
4501
ncx_get_longlong_uint(const void *xp, uint *ip)
4502
0
{
4503
0
    int err=NC_NOERR;
4504
0
    ix_int64 xx = 0;
4505
0
    get_ix_int64(xp, &xx);
4506
4507
0
#if IX_INT64_MAX > UINT_MAX
4508
0
    if (xx > UINT_MAX) {
4509
#ifdef ERANGE_FILL
4510
        *ip = NC_FILL_UINT;
4511
        return NC_ERANGE;
4512
#else
4513
0
        err = NC_ERANGE;
4514
0
#endif
4515
0
    }
4516
0
#endif
4517
4518
0
    if (xx < 0) {
4519
#ifdef ERANGE_FILL
4520
        *ip = NC_FILL_UINT;
4521
        return NC_ERANGE;
4522
#else
4523
0
        err = NC_ERANGE; /* because ip is unsigned */
4524
0
#endif
4525
0
    }
4526
0
    *ip = (uint) xx;
4527
0
    return err;
4528
0
}
4529
4530
static int
4531
ncx_get_longlong_ulonglong(const void *xp, ulonglong *ip)
4532
0
{
4533
0
    int err=NC_NOERR;
4534
0
    ix_int64 xx = 0;
4535
0
    get_ix_int64(xp, &xx);
4536
4537
#if IX_INT64_MAX > ULONGLONG_MAX
4538
    if (xx > ULONGLONG_MAX) {
4539
#ifdef ERANGE_FILL
4540
        *ip = NC_FILL_UINT64;
4541
        return NC_ERANGE;
4542
#else
4543
        err = NC_ERANGE;
4544
#endif
4545
    }
4546
#endif
4547
4548
0
    if (xx < 0) {
4549
#ifdef ERANGE_FILL
4550
        *ip = NC_FILL_UINT64;
4551
        return NC_ERANGE;
4552
#else
4553
0
        err = NC_ERANGE; /* because ip is unsigned */
4554
0
#endif
4555
0
    }
4556
0
    *ip = (ulonglong) xx;
4557
0
    return err;
4558
0
}
4559
4560
static int
4561
ncx_get_longlong_float(const void *xp, float *ip)
4562
0
{
4563
0
  ix_int64 xx = 0;
4564
0
  get_ix_int64(xp, &xx);
4565
0
  *ip = (float)xx;
4566
0
  return NC_NOERR;
4567
0
}
4568
4569
static int
4570
ncx_get_longlong_double(const void *xp, double *ip)
4571
0
{
4572
0
  ix_int64 xx = 0;
4573
0
  get_ix_int64(xp, &xx);
4574
0
  *ip = (double)xx;
4575
0
  return NC_NOERR;
4576
0
}
4577
4578
4579
#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4580
static int
4581
ncx_put_longlong_longlong(void *xp, const longlong *ip, void *fillp)
4582
{
4583
    int err=NC_NOERR;
4584
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4585
    put_ix_int64(xp, (const ix_int64 *)ip);
4586
#else
4587
    ix_int64 xx = NC_FILL_INT64;
4588
4589
#if IX_INT64_MAX < LONGLONG_MAX
4590
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4591
        
4592
#ifdef ERANGE_FILL
4593
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4594
#endif
4595
        err = NC_ERANGE;
4596
    }
4597
#ifdef ERANGE_FILL
4598
    else
4599
#endif
4600
#endif
4601
        xx = (ix_int64)*ip;
4602
4603
    put_ix_int64(xp, &xx);
4604
#endif
4605
    return err;
4606
}
4607
4608
#endif
4609
static int
4610
ncx_put_longlong_schar(void *xp, const schar *ip, void *fillp)
4611
0
{
4612
0
    int err=NC_NOERR;
4613
0
    ix_int64 xx = NC_FILL_INT64;
4614
4615
#if IX_INT64_MAX < SCHAR_MAX
4616
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4617
        
4618
#ifdef ERANGE_FILL
4619
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4620
#endif
4621
        err = NC_ERANGE;
4622
    }
4623
#ifdef ERANGE_FILL
4624
    else
4625
#endif
4626
#endif
4627
0
        xx = (ix_int64)*ip;
4628
4629
0
    put_ix_int64(xp, &xx);
4630
0
    return err;
4631
0
}
4632
4633
static int
4634
ncx_put_longlong_short(void *xp, const short *ip, void *fillp)
4635
0
{
4636
0
    int err=NC_NOERR;
4637
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4638
    put_ix_int64(xp, (const ix_int64 *)ip);
4639
#else
4640
0
    ix_int64 xx = NC_FILL_INT64;
4641
4642
#if IX_INT64_MAX < SHORT_MAX
4643
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4644
        
4645
#ifdef ERANGE_FILL
4646
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4647
#endif
4648
        err = NC_ERANGE;
4649
    }
4650
#ifdef ERANGE_FILL
4651
    else
4652
#endif
4653
#endif
4654
0
        xx = (ix_int64)*ip;
4655
4656
0
    put_ix_int64(xp, &xx);
4657
0
#endif
4658
0
    return err;
4659
0
}
4660
4661
static int
4662
ncx_put_longlong_int(void *xp, const int *ip, void *fillp)
4663
0
{
4664
0
    int err=NC_NOERR;
4665
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4666
    put_ix_int64(xp, (const ix_int64 *)ip);
4667
#else
4668
0
    ix_int64 xx = NC_FILL_INT64;
4669
4670
#if IX_INT64_MAX < INT_MAX
4671
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4672
        
4673
#ifdef ERANGE_FILL
4674
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4675
#endif
4676
        err = NC_ERANGE;
4677
    }
4678
#ifdef ERANGE_FILL
4679
    else
4680
#endif
4681
#endif
4682
0
        xx = (ix_int64)*ip;
4683
4684
0
    put_ix_int64(xp, &xx);
4685
0
#endif
4686
0
    return err;
4687
0
}
4688
4689
static int
4690
ncx_put_longlong_long(void *xp, const long *ip, void *fillp)
4691
0
{
4692
0
    int err=NC_NOERR;
4693
0
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4694
0
    put_ix_int64(xp, (const ix_int64 *)ip);
4695
#else
4696
    ix_int64 xx = NC_FILL_INT64;
4697
4698
#if IX_INT64_MAX < LONG_MAX
4699
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4700
        
4701
#ifdef ERANGE_FILL
4702
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4703
#endif
4704
        err = NC_ERANGE;
4705
    }
4706
#ifdef ERANGE_FILL
4707
    else
4708
#endif
4709
#endif
4710
        xx = (ix_int64)*ip;
4711
4712
    put_ix_int64(xp, &xx);
4713
#endif
4714
0
    return err;
4715
0
}
4716
4717
static int
4718
ncx_put_longlong_ushort(void *xp, const ushort *ip, void *fillp)
4719
0
{
4720
0
    int err=NC_NOERR;
4721
0
    ix_int64 xx = NC_FILL_INT64;
4722
4723
#if IX_INT64_MAX < USHORT_MAX
4724
    if (*ip > IX_INT64_MAX) {
4725
        
4726
#ifdef ERANGE_FILL
4727
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4728
#endif
4729
        err = NC_ERANGE;
4730
    }
4731
#ifdef ERANGE_FILL
4732
    else
4733
#endif
4734
#endif
4735
0
        xx = (ix_int64)*ip;
4736
4737
0
    put_ix_int64(xp, &xx);
4738
0
    return err;
4739
0
}
4740
4741
static int
4742
ncx_put_longlong_uchar(void *xp, const uchar *ip, void *fillp)
4743
0
{
4744
0
    int err=NC_NOERR;
4745
0
    ix_int64 xx = NC_FILL_INT64;
4746
4747
#if IX_INT64_MAX < UCHAR_MAX
4748
    if (*ip > IX_INT64_MAX) {
4749
        
4750
#ifdef ERANGE_FILL
4751
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4752
#endif
4753
        err = NC_ERANGE;
4754
    }
4755
#ifdef ERANGE_FILL
4756
    else
4757
#endif
4758
#endif
4759
0
        xx = (ix_int64)*ip;
4760
4761
0
    put_ix_int64(xp, &xx);
4762
0
    return err;
4763
0
}
4764
4765
static int
4766
ncx_put_longlong_uint(void *xp, const uint *ip, void *fillp)
4767
0
{
4768
0
    int err=NC_NOERR;
4769
0
    ix_int64 xx = NC_FILL_INT64;
4770
4771
#if IX_INT64_MAX < UINT_MAX
4772
    if (*ip > IX_INT64_MAX) {
4773
        
4774
#ifdef ERANGE_FILL
4775
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4776
#endif
4777
        err = NC_ERANGE;
4778
    }
4779
#ifdef ERANGE_FILL
4780
    else
4781
#endif
4782
#endif
4783
0
        xx = (ix_int64)*ip;
4784
4785
0
    put_ix_int64(xp, &xx);
4786
0
    return err;
4787
0
}
4788
4789
static int
4790
ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4791
0
{
4792
0
    int err=NC_NOERR;
4793
0
    ix_int64 xx = NC_FILL_INT64;
4794
4795
0
#if IX_INT64_MAX < ULONGLONG_MAX
4796
0
    if (*ip > IX_INT64_MAX) {
4797
        
4798
#ifdef ERANGE_FILL
4799
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4800
#endif
4801
0
        err = NC_ERANGE;
4802
0
    }
4803
#ifdef ERANGE_FILL
4804
    else
4805
#endif
4806
0
#endif
4807
0
        xx = (ix_int64)*ip;
4808
4809
0
    put_ix_int64(xp, &xx);
4810
0
    return err;
4811
0
}
4812
4813
static int
4814
ncx_put_longlong_float(void *xp, const float *ip, void *fillp)
4815
0
{
4816
0
    int err=NC_NOERR;
4817
0
    ix_int64 xx = NC_FILL_INT64;
4818
4819
0
    if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
4820
        
4821
#ifdef ERANGE_FILL
4822
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4823
#endif
4824
0
        err = NC_ERANGE;
4825
0
    }
4826
#ifdef ERANGE_FILL
4827
    else
4828
#endif
4829
0
        xx = (ix_int64)*ip;
4830
4831
0
    put_ix_int64(xp, &xx);
4832
0
    return err;
4833
0
}
4834
4835
static int
4836
ncx_put_longlong_double(void *xp, const double *ip, void *fillp)
4837
0
{
4838
0
    int err=NC_NOERR;
4839
0
    ix_int64 xx = NC_FILL_INT64;
4840
4841
0
    if (*ip > X_INT64_MAX || *ip < X_INT64_MIN) {
4842
        
4843
#ifdef ERANGE_FILL
4844
            if (fillp != NULL) memcpy(&xx, fillp, 8);
4845
#endif
4846
0
        err = NC_ERANGE;
4847
0
    }
4848
#ifdef ERANGE_FILL
4849
    else
4850
#endif
4851
0
        xx = (ix_int64)*ip;
4852
4853
0
    put_ix_int64(xp, &xx);
4854
0
    return err;
4855
0
}
4856
4857
4858
4859
/* external NC_UINT64 -------------------------------------------------------*/
4860
4861
#if USHORT_MAX == X_UINT64_MAX
4862
typedef ushort ix_uint64;
4863
#define SIZEOF_IX_UINT64 SIZEOF_USHORT
4864
#define IX_UINT64_MAX USHORT_MAX
4865
#elif ULONG_LONG_MAX  >= X_UINT64_MAX
4866
typedef ulonglong ix_uint64;
4867
#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
4868
#define IX_UINT64_MAX ULONG_LONG_MAX
4869
#elif ULONG_MAX  >= X_UINT64_MAX
4870
typedef ulong ix_uint64;
4871
#define SIZEOF_IX_UINT64 SIZEOF_ULONG
4872
#define IX_UINT64_MAX ULONG_MAX
4873
#else
4874
#error "ix_uint64 implementation"
4875
#endif
4876
4877
4878
static void
4879
get_ix_uint64(const void *xp, ix_uint64 *ip)
4880
0
{
4881
0
    const uchar *cp = (const uchar *) xp;
4882
4883
0
    *ip  = ((ix_uint64)(*cp++) << 56);
4884
0
    *ip |= ((ix_uint64)(*cp++) << 48);
4885
0
    *ip |= ((ix_uint64)(*cp++) << 40);
4886
0
    *ip |= ((ix_uint64)(*cp++) << 32);
4887
0
    *ip |= ((ix_uint64)(*cp++) << 24);
4888
0
    *ip |= ((ix_uint64)(*cp++) << 16);
4889
0
    *ip |= ((ix_uint64)(*cp++) <<  8);
4890
0
    *ip |=  (ix_uint64)*cp;
4891
0
}
4892
4893
static void
4894
put_ix_uint64(void *xp, const ix_uint64 *ip)
4895
0
{
4896
0
    uchar *cp = (uchar *) xp;
4897
4898
0
    *cp++ = (uchar)((*ip) >> 56);
4899
0
    *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48);
4900
0
    *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40);
4901
0
    *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32);
4902
0
    *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24);
4903
0
    *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16);
4904
0
    *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >>  8);
4905
0
    *cp   = (uchar)( (*ip) & 0x00000000000000ffULL);
4906
0
}
4907
4908
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4909
static int
4910
ncx_get_ulonglong_ulonglong(const void *xp, ulonglong *ip)
4911
{
4912
    int err=NC_NOERR;
4913
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4914
    get_ix_uint64(xp, (ix_uint64 *)ip);
4915
#else
4916
    ix_uint64 xx = 0;
4917
    get_ix_uint64(xp, &xx);
4918
4919
#if IX_UINT64_MAX > ULONGLONG_MAX
4920
    if (xx > ULONGLONG_MAX) {
4921
#ifdef ERANGE_FILL
4922
        *ip = NC_FILL_UINT64;
4923
        return NC_ERANGE;
4924
#else
4925
        err = NC_ERANGE;
4926
#endif
4927
    }
4928
#endif
4929
4930
4931
    *ip = (ulonglong) xx;
4932
#endif
4933
    return err;
4934
}
4935
4936
#endif
4937
static int
4938
ncx_get_ulonglong_schar(const void *xp, schar *ip)
4939
0
{
4940
0
    int err=NC_NOERR;
4941
0
    ix_uint64 xx = 0;
4942
0
    get_ix_uint64(xp, &xx);
4943
4944
0
#if IX_UINT64_MAX > SCHAR_MAX
4945
0
    if (xx > SCHAR_MAX) {
4946
#ifdef ERANGE_FILL
4947
        *ip = NC_FILL_BYTE;
4948
        return NC_ERANGE;
4949
#else
4950
0
        err = NC_ERANGE;
4951
0
#endif
4952
0
    }
4953
0
#endif
4954
4955
4956
0
    *ip = (schar) xx;
4957
0
    return err;
4958
0
}
4959
4960
static int
4961
ncx_get_ulonglong_short(const void *xp, short *ip)
4962
0
{
4963
0
    int err=NC_NOERR;
4964
0
    ix_uint64 xx = 0;
4965
0
    get_ix_uint64(xp, &xx);
4966
4967
0
#if IX_UINT64_MAX > SHORT_MAX
4968
0
    if (xx > SHORT_MAX) {
4969
#ifdef ERANGE_FILL
4970
        *ip = NC_FILL_SHORT;
4971
        return NC_ERANGE;
4972
#else
4973
0
        err = NC_ERANGE;
4974
0
#endif
4975
0
    }
4976
0
#endif
4977
4978
4979
0
    *ip = (short) xx;
4980
0
    return err;
4981
0
}
4982
4983
static int
4984
ncx_get_ulonglong_int(const void *xp, int *ip)
4985
0
{
4986
0
    int err=NC_NOERR;
4987
0
    ix_uint64 xx = 0;
4988
0
    get_ix_uint64(xp, &xx);
4989
4990
0
#if IX_UINT64_MAX > INT_MAX
4991
0
    if (xx > INT_MAX) {
4992
#ifdef ERANGE_FILL
4993
        *ip = NC_FILL_INT;
4994
        return NC_ERANGE;
4995
#else
4996
0
        err = NC_ERANGE;
4997
0
#endif
4998
0
    }
4999
0
#endif
5000
5001
5002
0
    *ip = (int) xx;
5003
0
    return err;
5004
0
}
5005
5006
static int
5007
ncx_get_ulonglong_long(const void *xp, long *ip)
5008
0
{
5009
0
    int err=NC_NOERR;
5010
0
    ix_uint64 xx = 0;
5011
0
    get_ix_uint64(xp, &xx);
5012
5013
0
#if IX_UINT64_MAX > LONG_MAX
5014
0
    if (xx > LONG_MAX) {
5015
#ifdef ERANGE_FILL
5016
        *ip = NC_FILL_INT;
5017
        return NC_ERANGE;
5018
#else
5019
0
        err = NC_ERANGE;
5020
0
#endif
5021
0
    }
5022
0
#endif
5023
5024
5025
0
    *ip = (long) xx;
5026
0
    return err;
5027
0
}
5028
5029
static int
5030
ncx_get_ulonglong_longlong(const void *xp, longlong *ip)
5031
0
{
5032
0
    int err=NC_NOERR;
5033
0
    ix_uint64 xx = 0;
5034
0
    get_ix_uint64(xp, &xx);
5035
5036
0
#if IX_UINT64_MAX > LONGLONG_MAX
5037
0
    if (xx > LONGLONG_MAX) {
5038
#ifdef ERANGE_FILL
5039
        *ip = NC_FILL_INT64;
5040
        return NC_ERANGE;
5041
#else
5042
0
        err = NC_ERANGE;
5043
0
#endif
5044
0
    }
5045
0
#endif
5046
5047
5048
0
    *ip = (longlong) xx;
5049
0
    return err;
5050
0
}
5051
5052
static int
5053
ncx_get_ulonglong_ushort(const void *xp, ushort *ip)
5054
0
{
5055
0
    int err=NC_NOERR;
5056
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5057
    get_ix_uint64(xp, (ix_uint64 *)ip);
5058
#else
5059
0
    ix_uint64 xx = 0;
5060
0
    get_ix_uint64(xp, &xx);
5061
5062
0
#if IX_UINT64_MAX > USHORT_MAX
5063
0
    if (xx > USHORT_MAX) {
5064
#ifdef ERANGE_FILL
5065
        *ip = NC_FILL_USHORT;
5066
        return NC_ERANGE;
5067
#else
5068
0
        err = NC_ERANGE;
5069
0
#endif
5070
0
    }
5071
0
#endif
5072
5073
5074
0
    *ip = (ushort) xx;
5075
0
#endif
5076
0
    return err;
5077
0
}
5078
5079
static int
5080
ncx_get_ulonglong_uchar(const void *xp, uchar *ip)
5081
0
{
5082
0
    int err=NC_NOERR;
5083
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5084
    get_ix_uint64(xp, (ix_uint64 *)ip);
5085
#else
5086
0
    ix_uint64 xx = 0;
5087
0
    get_ix_uint64(xp, &xx);
5088
5089
0
#if IX_UINT64_MAX > UCHAR_MAX
5090
0
    if (xx > UCHAR_MAX) {
5091
#ifdef ERANGE_FILL
5092
        *ip = NC_FILL_UBYTE;
5093
        return NC_ERANGE;
5094
#else
5095
0
        err = NC_ERANGE;
5096
0
#endif
5097
0
    }
5098
0
#endif
5099
5100
5101
0
    *ip = (uchar) xx;
5102
0
#endif
5103
0
    return err;
5104
0
}
5105
5106
static int
5107
ncx_get_ulonglong_uint(const void *xp, uint *ip)
5108
0
{
5109
0
    int err=NC_NOERR;
5110
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5111
    get_ix_uint64(xp, (ix_uint64 *)ip);
5112
#else
5113
0
    ix_uint64 xx = 0;
5114
0
    get_ix_uint64(xp, &xx);
5115
5116
0
#if IX_UINT64_MAX > UINT_MAX
5117
0
    if (xx > UINT_MAX) {
5118
#ifdef ERANGE_FILL
5119
        *ip = NC_FILL_UINT;
5120
        return NC_ERANGE;
5121
#else
5122
0
        err = NC_ERANGE;
5123
0
#endif
5124
0
    }
5125
0
#endif
5126
5127
5128
0
    *ip = (uint) xx;
5129
0
#endif
5130
0
    return err;
5131
0
}
5132
5133
static int
5134
ncx_get_ulonglong_float(const void *xp, float *ip)
5135
0
{
5136
0
  ix_uint64 xx = 0;
5137
0
  get_ix_uint64(xp, &xx);
5138
0
  *ip = (float)xx;
5139
0
  return NC_NOERR;
5140
0
}
5141
5142
static int
5143
ncx_get_ulonglong_double(const void *xp, double *ip)
5144
0
{
5145
0
  ix_uint64 xx = 0;
5146
0
  get_ix_uint64(xp, &xx);
5147
0
  *ip = (double)xx;
5148
0
  return NC_NOERR;
5149
0
}
5150
5151
5152
#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
5153
static int
5154
ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
5155
{
5156
    int err=NC_NOERR;
5157
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
5158
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5159
#else
5160
    ix_uint64 xx = NC_FILL_UINT64;
5161
5162
#if IX_UINT64_MAX < ULONGLONG_MAX
5163
    if (*ip > IX_UINT64_MAX) {
5164
        
5165
#ifdef ERANGE_FILL
5166
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5167
#endif
5168
        err = NC_ERANGE;
5169
    }
5170
#ifdef ERANGE_FILL
5171
    else
5172
#endif
5173
#endif
5174
        xx = (ix_uint64)*ip;
5175
5176
    put_ix_uint64(xp, &xx);
5177
#endif
5178
    return err;
5179
}
5180
5181
#endif
5182
static int
5183
ncx_put_ulonglong_schar(void *xp, const schar *ip, void *fillp)
5184
0
{
5185
0
    int err=NC_NOERR;
5186
0
    ix_uint64 xx = NC_FILL_UINT64;
5187
5188
#if IX_UINT64_MAX < SCHAR_MAX
5189
    if (*ip > IX_UINT64_MAX) {
5190
        
5191
#ifdef ERANGE_FILL
5192
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5193
#endif
5194
        err = NC_ERANGE;
5195
    }
5196
#ifdef ERANGE_FILL
5197
    else
5198
#endif
5199
#endif
5200
0
    if (*ip < 0) {
5201
        
5202
#ifdef ERANGE_FILL
5203
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5204
#endif
5205
0
        err = NC_ERANGE; /* because xp is unsigned */
5206
0
    }
5207
#ifdef ERANGE_FILL
5208
    else
5209
#endif
5210
0
        xx = (ix_uint64)*ip;
5211
5212
0
    put_ix_uint64(xp, &xx);
5213
0
    return err;
5214
0
}
5215
5216
static int
5217
ncx_put_ulonglong_short(void *xp, const short *ip, void *fillp)
5218
0
{
5219
0
    int err=NC_NOERR;
5220
0
    ix_uint64 xx = NC_FILL_UINT64;
5221
5222
#if IX_UINT64_MAX < SHORT_MAX
5223
    if (*ip > IX_UINT64_MAX) {
5224
        
5225
#ifdef ERANGE_FILL
5226
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5227
#endif
5228
        err = NC_ERANGE;
5229
    }
5230
#ifdef ERANGE_FILL
5231
    else
5232
#endif
5233
#endif
5234
0
    if (*ip < 0) {
5235
        
5236
#ifdef ERANGE_FILL
5237
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5238
#endif
5239
0
        err = NC_ERANGE; /* because xp is unsigned */
5240
0
    }
5241
#ifdef ERANGE_FILL
5242
    else
5243
#endif
5244
0
        xx = (ix_uint64)*ip;
5245
5246
0
    put_ix_uint64(xp, &xx);
5247
0
    return err;
5248
0
}
5249
5250
static int
5251
ncx_put_ulonglong_int(void *xp, const int *ip, void *fillp)
5252
0
{
5253
0
    int err=NC_NOERR;
5254
0
    ix_uint64 xx = NC_FILL_UINT64;
5255
5256
#if IX_UINT64_MAX < INT_MAX
5257
    if (*ip > IX_UINT64_MAX) {
5258
        
5259
#ifdef ERANGE_FILL
5260
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5261
#endif
5262
        err = NC_ERANGE;
5263
    }
5264
#ifdef ERANGE_FILL
5265
    else
5266
#endif
5267
#endif
5268
0
    if (*ip < 0) {
5269
        
5270
#ifdef ERANGE_FILL
5271
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5272
#endif
5273
0
        err = NC_ERANGE; /* because xp is unsigned */
5274
0
    }
5275
#ifdef ERANGE_FILL
5276
    else
5277
#endif
5278
0
        xx = (ix_uint64)*ip;
5279
5280
0
    put_ix_uint64(xp, &xx);
5281
0
    return err;
5282
0
}
5283
5284
static int
5285
ncx_put_ulonglong_long(void *xp, const long *ip, void *fillp)
5286
0
{
5287
0
    int err=NC_NOERR;
5288
0
    ix_uint64 xx = NC_FILL_UINT64;
5289
5290
#if IX_UINT64_MAX < LONG_MAX
5291
    if (*ip > IX_UINT64_MAX) {
5292
        
5293
#ifdef ERANGE_FILL
5294
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5295
#endif
5296
        err = NC_ERANGE;
5297
    }
5298
#ifdef ERANGE_FILL
5299
    else
5300
#endif
5301
#endif
5302
0
    if (*ip < 0) {
5303
        
5304
#ifdef ERANGE_FILL
5305
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5306
#endif
5307
0
        err = NC_ERANGE; /* because xp is unsigned */
5308
0
    }
5309
#ifdef ERANGE_FILL
5310
    else
5311
#endif
5312
0
        xx = (ix_uint64)*ip;
5313
5314
0
    put_ix_uint64(xp, &xx);
5315
0
    return err;
5316
0
}
5317
5318
static int
5319
ncx_put_ulonglong_longlong(void *xp, const longlong *ip, void *fillp)
5320
0
{
5321
0
    int err=NC_NOERR;
5322
0
    ix_uint64 xx = NC_FILL_UINT64;
5323
5324
#if IX_UINT64_MAX < LONGLONG_MAX
5325
    if (*ip > IX_UINT64_MAX) {
5326
        
5327
#ifdef ERANGE_FILL
5328
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5329
#endif
5330
        err = NC_ERANGE;
5331
    }
5332
#ifdef ERANGE_FILL
5333
    else
5334
#endif
5335
#endif
5336
0
    if (*ip < 0) {
5337
        
5338
#ifdef ERANGE_FILL
5339
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5340
#endif
5341
0
        err = NC_ERANGE; /* because xp is unsigned */
5342
0
    }
5343
#ifdef ERANGE_FILL
5344
    else
5345
#endif
5346
0
        xx = (ix_uint64)*ip;
5347
5348
0
    put_ix_uint64(xp, &xx);
5349
0
    return err;
5350
0
}
5351
5352
static int
5353
ncx_put_ulonglong_uchar(void *xp, const uchar *ip, void *fillp)
5354
0
{
5355
0
    int err=NC_NOERR;
5356
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5357
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5358
#else
5359
0
    ix_uint64 xx = NC_FILL_UINT64;
5360
5361
#if IX_UINT64_MAX < UCHAR_MAX
5362
    if (*ip > IX_UINT64_MAX) {
5363
        
5364
#ifdef ERANGE_FILL
5365
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5366
#endif
5367
        err = NC_ERANGE;
5368
    }
5369
#ifdef ERANGE_FILL
5370
    else
5371
#endif
5372
#endif
5373
0
        xx = (ix_uint64)*ip;
5374
5375
0
    put_ix_uint64(xp, &xx);
5376
0
#endif
5377
0
    return err;
5378
0
}
5379
5380
static int
5381
ncx_put_ulonglong_ushort(void *xp, const ushort *ip, void *fillp)
5382
0
{
5383
0
    int err=NC_NOERR;
5384
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5385
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5386
#else
5387
0
    ix_uint64 xx = NC_FILL_UINT64;
5388
5389
#if IX_UINT64_MAX < USHORT_MAX
5390
    if (*ip > IX_UINT64_MAX) {
5391
        
5392
#ifdef ERANGE_FILL
5393
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5394
#endif
5395
        err = NC_ERANGE;
5396
    }
5397
#ifdef ERANGE_FILL
5398
    else
5399
#endif
5400
#endif
5401
0
        xx = (ix_uint64)*ip;
5402
5403
0
    put_ix_uint64(xp, &xx);
5404
0
#endif
5405
0
    return err;
5406
0
}
5407
5408
static int
5409
ncx_put_ulonglong_uint(void *xp, const uint *ip, void *fillp)
5410
0
{
5411
0
    int err=NC_NOERR;
5412
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5413
    put_ix_uint64(xp, (const ix_uint64 *)ip);
5414
#else
5415
0
    ix_uint64 xx = NC_FILL_UINT64;
5416
5417
#if IX_UINT64_MAX < UINT_MAX
5418
    if (*ip > IX_UINT64_MAX) {
5419
        
5420
#ifdef ERANGE_FILL
5421
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5422
#endif
5423
        err = NC_ERANGE;
5424
    }
5425
#ifdef ERANGE_FILL
5426
    else
5427
#endif
5428
#endif
5429
0
        xx = (ix_uint64)*ip;
5430
5431
0
    put_ix_uint64(xp, &xx);
5432
0
#endif
5433
0
    return err;
5434
0
}
5435
5436
static int
5437
ncx_put_ulonglong_float(void *xp, const float *ip, void *fillp)
5438
0
{
5439
0
    int err=NC_NOERR;
5440
0
    ix_uint64 xx = NC_FILL_UINT64;
5441
5442
0
    if (*ip > (double)X_UINT64_MAX || *ip < 0) {
5443
        
5444
#ifdef ERANGE_FILL
5445
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5446
#endif
5447
0
        err = NC_ERANGE;
5448
0
    }
5449
#ifdef ERANGE_FILL
5450
    else
5451
#endif
5452
0
        xx = (ix_uint64)*ip;
5453
5454
0
    put_ix_uint64(xp, &xx);
5455
0
    return err;
5456
0
}
5457
5458
static int
5459
ncx_put_ulonglong_double(void *xp, const double *ip, void *fillp)
5460
0
{
5461
0
    int err=NC_NOERR;
5462
0
    ix_uint64 xx = NC_FILL_UINT64;
5463
5464
0
    if (*ip > X_UINT64_MAX || *ip < 0) {
5465
        
5466
#ifdef ERANGE_FILL
5467
            if (fillp != NULL) memcpy(&xx, fillp, 8);
5468
#endif
5469
0
        err = NC_ERANGE;
5470
0
    }
5471
#ifdef ERANGE_FILL
5472
    else
5473
#endif
5474
0
        xx = (ix_uint64)*ip;
5475
5476
0
    put_ix_uint64(xp, &xx);
5477
0
    return err;
5478
0
}
5479
5480
5481
5482
/* x_size_t */
5483
5484
#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
5485
#error "x_size_t implementation"
5486
/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
5487
#endif
5488
5489
int
5490
ncx_put_size_t(void **xpp, const size_t *ulp)
5491
0
{
5492
  /* similar to put_ix_int() */
5493
0
  uchar *cp = (uchar *) *xpp;
5494
0
  assert(*ulp <= X_SIZE_MAX);
5495
5496
0
  *cp++ = (uchar)((*ulp) >> 24);
5497
0
  *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
5498
0
  *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
5499
0
  *cp   = (uchar)((*ulp) & 0x000000ff);
5500
5501
0
  *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
5502
0
  return NC_NOERR;
5503
0
}
5504
5505
int
5506
ncx_get_size_t(const void **xpp,  size_t *ulp)
5507
595k
{
5508
  /* similar to get_ix_int */
5509
595k
  const uchar *cp = (const uchar *) *xpp;
5510
5511
595k
  *ulp  = (unsigned)(*cp++) << 24;
5512
595k
  *ulp |= (*cp++ << 16);
5513
595k
  *ulp |= (*cp++ << 8);
5514
595k
  *ulp |= *cp;
5515
5516
595k
  *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
5517
595k
  return NC_NOERR;
5518
595k
}
5519
5520
/* x_off_t */
5521
5522
int
5523
ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
5524
0
{
5525
  /* similar to put_ix_int() */
5526
0
  uchar *cp = (uchar *) *xpp;
5527
5528
  /* No negative offsets stored in netcdf */
5529
0
  if (*lp < 0) {
5530
    /* Assume this is an overflow of a 32-bit int... */
5531
0
    return NC_ERANGE;
5532
0
  }
5533
5534
0
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5535
5536
0
  if (sizeof_off_t == 4) {
5537
0
    *cp++ = (uchar) ((*lp)               >> 24);
5538
0
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5539
0
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5540
0
    *cp   = (uchar)( (*lp) & 0x000000ff);
5541
0
  } else {
5542
#if SIZEOF_OFF_T == 4
5543
/* Write a 64-bit offset on a system with only a 32-bit offset */
5544
    *cp++ = (uchar)0;
5545
    *cp++ = (uchar)0;
5546
    *cp++ = (uchar)0;
5547
    *cp++ = (uchar)0;
5548
5549
    *cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
5550
    *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5551
    *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5552
    *cp   = (uchar)( (*lp) & 0x000000ff);
5553
#else
5554
0
    *cp++ = (uchar) ((*lp)                          >> 56);
5555
0
    *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48);
5556
0
    *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40);
5557
0
    *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32);
5558
0
    *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24);
5559
0
    *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16);
5560
0
    *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >>  8);
5561
0
    *cp   = (uchar)( (*lp) & 0x00000000000000ffLL);
5562
0
#endif
5563
0
  }
5564
0
  *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
5565
0
  return NC_NOERR;
5566
0
}
5567
5568
int
5569
ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
5570
48.3k
{
5571
  /* similar to get_ix_int() */
5572
48.3k
  const uchar *cp = (const uchar *) *xpp;
5573
48.3k
  assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5574
5575
48.3k
  if (sizeof_off_t == 4) {
5576
0
    *lp =  (off_t)(*cp++ << 24);
5577
0
    *lp |= (off_t)(*cp++ << 16);
5578
0
    *lp |= (off_t)(*cp++ <<  8);
5579
0
    *lp |= (off_t)*cp;
5580
48.3k
  } else {
5581
#if SIZEOF_OFF_T == 4
5582
/* Read a 64-bit offset on a system with only a 32-bit offset */
5583
/* If the offset overflows, set an error code and return */
5584
    *lp =  ((off_t)(*cp++) << 24);
5585
    *lp |= ((off_t)(*cp++) << 16);
5586
    *lp |= ((off_t)(*cp++) <<  8);
5587
    *lp |= ((off_t)(*cp++));
5588
/*
5589
 * lp now contains the upper 32-bits of the 64-bit offset.  if lp is
5590
 * not zero, then the dataset is larger than can be represented
5591
 * on this system.  Set an error code and return.
5592
 */
5593
    if (*lp != 0) {
5594
      return NC_ERANGE;
5595
    }
5596
5597
    *lp  = ((off_t)(*cp++) << 24);
5598
    *lp |= ((off_t)(*cp++) << 16);
5599
    *lp |= ((off_t)(*cp++) <<  8);
5600
    *lp |=  (off_t)*cp;
5601
5602
    if (*lp < 0) {
5603
      /*
5604
       * If this fails, then the offset is >2^31, but less
5605
       * than 2^32 which is not allowed, but is not caught
5606
       * by the previous check
5607
       */
5608
      return NC_ERANGE;
5609
    }
5610
#else
5611
48.3k
    *lp =  ((off_t)(*cp++) << 56);
5612
48.3k
    *lp |= ((off_t)(*cp++) << 48);
5613
48.3k
    *lp |= ((off_t)(*cp++) << 40);
5614
48.3k
    *lp |= ((off_t)(*cp++) << 32);
5615
48.3k
    *lp |= ((off_t)(*cp++) << 24);
5616
48.3k
    *lp |= ((off_t)(*cp++) << 16);
5617
48.3k
    *lp |= ((off_t)(*cp++) <<  8);
5618
48.3k
    *lp |=  (off_t)*cp;
5619
48.3k
#endif
5620
48.3k
  }
5621
48.3k
  *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
5622
48.3k
  return NC_NOERR;
5623
48.3k
}
5624
5625
/*----< ncx_get_uint32() >------------------------------------------*/
5626
int
5627
ncx_get_uint32(const void **xpp, uint *ip)
5628
140k
{
5629
#ifdef WORDS_BIGENDIAN
5630
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5631
     * some system, such as HPUX */
5632
    (void) memcpy(ip, *xpp, SIZEOF_UINT);
5633
#else
5634
140k
    const uchar *cp = (const uchar *) *xpp;
5635
5636
140k
    *ip = (uint)(*cp++ << 24);
5637
140k
    *ip = (uint)(*ip | (uint)(*cp++ << 16));
5638
140k
    *ip = (uint)(*ip | (uint)(*cp++ <<  8));
5639
140k
    *ip = (uint)(*ip | *cp);
5640
140k
#endif
5641
    /* advance *xpp 4 bytes */
5642
140k
    *xpp = (void *)((const char *)(*xpp) + 4);
5643
5644
140k
    return NC_NOERR;
5645
140k
}
5646
5647
/*----< ncx_get_uint64() >------------------------------------------*/
5648
int
5649
ncx_get_uint64(const void **xpp, unsigned long long *ullp)
5650
217k
{
5651
#ifdef WORDS_BIGENDIAN
5652
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5653
     * some system, such as HPUX */
5654
    (void) memcpy(ullp, *xpp, SIZEOF_UINT64);
5655
#else
5656
217k
    const uchar *cp = (const uchar *) *xpp;
5657
5658
    /* below is the same as calling swap8b(ullp, *xpp) */
5659
217k
    *ullp = (unsigned long long)(*cp++) << 56;
5660
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48);
5661
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40);
5662
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32);
5663
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24);
5664
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16);
5665
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) <<  8);
5666
217k
    *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp));
5667
217k
#endif
5668
    /* advance *xpp 8 bytes */
5669
217k
    *xpp = (void *)((const char *)(*xpp) + 8);
5670
5671
217k
    return NC_NOERR;
5672
217k
}
5673
5674
/*---< ncx_put_uint32() >-------------------------------------------*/
5675
/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
5676
 * form and advance *xpp 4 bytes
5677
 */
5678
int
5679
ncx_put_uint32(void **xpp, const unsigned int ip)
5680
0
{
5681
#ifdef WORDS_BIGENDIAN
5682
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5683
     * some system, such as HPUX */
5684
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
5685
#else
5686
    /* bitwise shifts below are to produce an integer in Big Endian */
5687
0
    uchar *cp = (uchar *) *xpp;
5688
0
    *cp++ = (uchar)((ip & 0xff000000) >> 24);
5689
0
    *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
5690
0
    *cp++ = (uchar)((ip & 0x0000ff00) >>  8);
5691
0
    *cp   = (uchar)( ip & 0x000000ff);
5692
0
#endif
5693
    /* advance *xpp 4 bytes */
5694
0
    *xpp  = (void *)((char *)(*xpp) + 4);
5695
5696
0
    return NC_NOERR;
5697
0
}
5698
5699
/*---< ncx_put_uint64() >-------------------------------------------*/
5700
/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
5701
 * form and advance *xpp 8 bytes
5702
 */
5703
int
5704
ncx_put_uint64(void **xpp, const unsigned long long ip)
5705
0
{
5706
#ifdef WORDS_BIGENDIAN
5707
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5708
     * some system, such as HPUX */
5709
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
5710
#else
5711
0
    uchar *cp = (uchar *) *xpp;
5712
    /* below is the same as calling swap8b(*xpp, &ip) */
5713
0
    *cp++ = (uchar) (ip                         >> 56);
5714
0
    *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48);
5715
0
    *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40);
5716
0
    *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32);
5717
0
    *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24);
5718
0
    *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16);
5719
0
    *cp++ = (uchar)((ip & 0x000000000000ff00LL) >>  8);
5720
0
    *cp   = (uchar) (ip & 0x00000000000000ffLL);
5721
0
#endif
5722
    /* advance *xpp 8 bytes */
5723
0
    *xpp  = (void *)((char *)(*xpp) + 8);
5724
5725
0
    return NC_NOERR;
5726
0
}
5727
5728
5729
/*
5730
 * Aggregate numeric conversion functions.
5731
 */
5732
5733
5734
5735
/* schar ---------------------------------------------------------------------*/
5736
5737
int
5738
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5739
104
{
5740
104
    (void) memcpy(tp, *xpp, (size_t)nelems);
5741
104
  *xpp = (void *)((char *)(*xpp) + nelems);
5742
104
  return NC_NOERR;
5743
5744
104
}
5745
int
5746
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5747
0
{
5748
0
    int status = NC_NOERR;
5749
0
    schar *xp = (schar *)(*xpp);
5750
5751
0
    while (nelems-- != 0) {
5752
        
5753
0
        if (*xp < 0) {
5754
#ifdef ERANGE_FILL
5755
            *tp = NC_FILL_UBYTE;
5756
#endif
5757
0
            status = NC_ERANGE; /* because tp is unsigned */
5758
            
5759
#ifdef ERANGE_FILL
5760
            xp++; tp++; continue;
5761
#endif
5762
0
        }
5763
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5764
0
    }
5765
5766
0
    *xpp = (const void *)xp;
5767
0
    return status;
5768
0
}
5769
5770
int
5771
ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5772
0
{
5773
0
    int status = NC_NOERR;
5774
0
    schar *xp = (schar *)(*xpp);
5775
5776
0
    while (nelems-- != 0) {
5777
        
5778
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5779
0
    }
5780
5781
0
    *xpp = (const void *)xp;
5782
0
    return status;
5783
0
}
5784
5785
int
5786
ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5787
0
{
5788
0
    int status = NC_NOERR;
5789
0
    schar *xp = (schar *)(*xpp);
5790
5791
0
    while (nelems-- != 0) {
5792
        
5793
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5794
0
    }
5795
5796
0
    *xpp = (const void *)xp;
5797
0
    return status;
5798
0
}
5799
5800
int
5801
ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5802
0
{
5803
0
    int status = NC_NOERR;
5804
0
    schar *xp = (schar *)(*xpp);
5805
5806
0
    while (nelems-- != 0) {
5807
        
5808
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5809
0
    }
5810
5811
0
    *xpp = (const void *)xp;
5812
0
    return status;
5813
0
}
5814
5815
int
5816
ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5817
0
{
5818
0
    int status = NC_NOERR;
5819
0
    schar *xp = (schar *)(*xpp);
5820
5821
0
    while (nelems-- != 0) {
5822
        
5823
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5824
0
    }
5825
5826
0
    *xpp = (const void *)xp;
5827
0
    return status;
5828
0
}
5829
5830
int
5831
ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5832
0
{
5833
0
    int status = NC_NOERR;
5834
0
    schar *xp = (schar *)(*xpp);
5835
5836
0
    while (nelems-- != 0) {
5837
        
5838
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5839
0
    }
5840
5841
0
    *xpp = (const void *)xp;
5842
0
    return status;
5843
0
}
5844
5845
int
5846
ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5847
0
{
5848
0
    int status = NC_NOERR;
5849
0
    schar *xp = (schar *)(*xpp);
5850
5851
0
    while (nelems-- != 0) {
5852
        
5853
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5854
0
    }
5855
5856
0
    *xpp = (const void *)xp;
5857
0
    return status;
5858
0
}
5859
5860
int
5861
ncx_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5862
0
{
5863
0
    int status = NC_NOERR;
5864
0
    schar *xp = (schar *)(*xpp);
5865
5866
0
    while (nelems-- != 0) {
5867
        
5868
0
        if (*xp < 0) {
5869
#ifdef ERANGE_FILL
5870
            *tp = NC_FILL_USHORT;
5871
#endif
5872
0
            status = NC_ERANGE; /* because tp is unsigned */
5873
            
5874
#ifdef ERANGE_FILL
5875
            xp++; tp++; continue;
5876
#endif
5877
0
        }
5878
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5879
0
    }
5880
5881
0
    *xpp = (const void *)xp;
5882
0
    return status;
5883
0
}
5884
5885
int
5886
ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5887
0
{
5888
0
    int status = NC_NOERR;
5889
0
    schar *xp = (schar *)(*xpp);
5890
5891
0
    while (nelems-- != 0) {
5892
        
5893
0
        if (*xp < 0) {
5894
#ifdef ERANGE_FILL
5895
            *tp = NC_FILL_UINT;
5896
#endif
5897
0
            status = NC_ERANGE; /* because tp is unsigned */
5898
            
5899
#ifdef ERANGE_FILL
5900
            xp++; tp++; continue;
5901
#endif
5902
0
        }
5903
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5904
0
    }
5905
5906
0
    *xpp = (const void *)xp;
5907
0
    return status;
5908
0
}
5909
5910
int
5911
ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5912
0
{
5913
0
    int status = NC_NOERR;
5914
0
    schar *xp = (schar *)(*xpp);
5915
5916
0
    while (nelems-- != 0) {
5917
        
5918
0
        if (*xp < 0) {
5919
#ifdef ERANGE_FILL
5920
            *tp = NC_FILL_UINT64;
5921
#endif
5922
0
            status = NC_ERANGE; /* because tp is unsigned */
5923
            
5924
#ifdef ERANGE_FILL
5925
            xp++; tp++; continue;
5926
#endif
5927
0
        }
5928
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5929
0
    }
5930
5931
0
    *xpp = (const void *)xp;
5932
0
    return status;
5933
0
}
5934
5935
5936
int
5937
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5938
0
{
5939
0
    size_t rndup = nelems % X_ALIGN;
5940
5941
0
  if (rndup)
5942
0
    rndup = X_ALIGN - rndup;
5943
5944
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
5945
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
5946
5947
0
  return NC_NOERR;
5948
5949
0
}
5950
int
5951
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5952
0
{
5953
0
    int status = NC_NOERR;
5954
0
    size_t rndup = nelems % X_ALIGN;
5955
0
    schar *xp = (schar *) *xpp;
5956
5957
0
    if (rndup)
5958
0
        rndup = X_ALIGN - rndup;
5959
5960
0
    while (nelems-- != 0) {
5961
        
5962
0
        if (*xp < 0) {
5963
#ifdef ERANGE_FILL
5964
            *tp = NC_FILL_UBYTE;
5965
#endif
5966
0
            status = NC_ERANGE; /* because tp is unsigned */
5967
            
5968
#ifdef ERANGE_FILL
5969
            xp++; tp++; continue;
5970
#endif
5971
0
        }
5972
0
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5973
0
    }
5974
5975
0
    *xpp = (void *)(xp + rndup);
5976
0
    return status;
5977
0
}
5978
5979
int
5980
ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5981
0
{
5982
0
    int status = NC_NOERR;
5983
0
    size_t rndup = nelems % X_ALIGN;
5984
0
    schar *xp = (schar *) *xpp;
5985
5986
0
    if (rndup)
5987
0
        rndup = X_ALIGN - rndup;
5988
5989
0
    while (nelems-- != 0) {
5990
        
5991
0
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5992
0
    }
5993
5994
0
    *xpp = (void *)(xp + rndup);
5995
0
    return status;
5996
0
}
5997
5998
int
5999
ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
6000
0
{
6001
0
    int status = NC_NOERR;
6002
0
    size_t rndup = nelems % X_ALIGN;
6003
0
    schar *xp = (schar *) *xpp;
6004
6005
0
    if (rndup)
6006
0
        rndup = X_ALIGN - rndup;
6007
6008
0
    while (nelems-- != 0) {
6009
        
6010
0
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
6011
0
    }
6012
6013
0
    *xpp = (void *)(xp + rndup);
6014
0
    return status;
6015
0
}
6016
6017
int
6018
ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
6019
0
{
6020
0
    int status = NC_NOERR;
6021
0
    size_t rndup = nelems % X_ALIGN;
6022
0
    schar *xp = (schar *) *xpp;
6023
6024
0
    if (rndup)
6025
0
        rndup = X_ALIGN - rndup;
6026
6027
0
    while (nelems-- != 0) {
6028
        
6029
0
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
6030
0
    }
6031
6032
0
    *xpp = (void *)(xp + rndup);
6033
0
    return status;
6034
0
}
6035
6036
int
6037
ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
6038
0
{
6039
0
    int status = NC_NOERR;
6040
0
    size_t rndup = nelems % X_ALIGN;
6041
0
    schar *xp = (schar *) *xpp;
6042
6043
0
    if (rndup)
6044
0
        rndup = X_ALIGN - rndup;
6045
6046
0
    while (nelems-- != 0) {
6047
        
6048
0
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
6049
0
    }
6050
6051
0
    *xpp = (void *)(xp + rndup);
6052
0
    return status;
6053
0
}
6054
6055
int
6056
ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
6057
0
{
6058
0
    int status = NC_NOERR;
6059
0
    size_t rndup = nelems % X_ALIGN;
6060
0
    schar *xp = (schar *) *xpp;
6061
6062
0
    if (rndup)
6063
0
        rndup = X_ALIGN - rndup;
6064
6065
0
    while (nelems-- != 0) {
6066
        
6067
0
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
6068
0
    }
6069
6070
0
    *xpp = (void *)(xp + rndup);
6071
0
    return status;
6072
0
}
6073
6074
int
6075
ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
6076
0
{
6077
0
    int status = NC_NOERR;
6078
0
    size_t rndup = nelems % X_ALIGN;
6079
0
    schar *xp = (schar *) *xpp;
6080
6081
0
    if (rndup)
6082
0
        rndup = X_ALIGN - rndup;
6083
6084
0
    while (nelems-- != 0) {
6085
        
6086
0
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
6087
0
    }
6088
6089
0
    *xpp = (void *)(xp + rndup);
6090
0
    return status;
6091
0
}
6092
6093
int
6094
ncx_pad_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
6095
0
{
6096
0
    int status = NC_NOERR;
6097
0
    size_t rndup = nelems % X_ALIGN;
6098
0
    schar *xp = (schar *) *xpp;
6099
6100
0
    if (rndup)
6101
0
        rndup = X_ALIGN - rndup;
6102
6103
0
    while (nelems-- != 0) {
6104
        
6105
0
        if (*xp < 0) {
6106
#ifdef ERANGE_FILL
6107
            *tp = NC_FILL_USHORT;
6108
#endif
6109
0
            status = NC_ERANGE; /* because tp is unsigned */
6110
            
6111
#ifdef ERANGE_FILL
6112
            xp++; tp++; continue;
6113
#endif
6114
0
        }
6115
0
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
6116
0
    }
6117
6118
0
    *xpp = (void *)(xp + rndup);
6119
0
    return status;
6120
0
}
6121
6122
int
6123
ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
6124
0
{
6125
0
    int status = NC_NOERR;
6126
0
    size_t rndup = nelems % X_ALIGN;
6127
0
    schar *xp = (schar *) *xpp;
6128
6129
0
    if (rndup)
6130
0
        rndup = X_ALIGN - rndup;
6131
6132
0
    while (nelems-- != 0) {
6133
        
6134
0
        if (*xp < 0) {
6135
#ifdef ERANGE_FILL
6136
            *tp = NC_FILL_UINT;
6137
#endif
6138
0
            status = NC_ERANGE; /* because tp is unsigned */
6139
            
6140
#ifdef ERANGE_FILL
6141
            xp++; tp++; continue;
6142
#endif
6143
0
        }
6144
0
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
6145
0
    }
6146
6147
0
    *xpp = (void *)(xp + rndup);
6148
0
    return status;
6149
0
}
6150
6151
int
6152
ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6153
0
{
6154
0
    int status = NC_NOERR;
6155
0
    size_t rndup = nelems % X_ALIGN;
6156
0
    schar *xp = (schar *) *xpp;
6157
6158
0
    if (rndup)
6159
0
        rndup = X_ALIGN - rndup;
6160
6161
0
    while (nelems-- != 0) {
6162
        
6163
0
        if (*xp < 0) {
6164
#ifdef ERANGE_FILL
6165
            *tp = NC_FILL_UINT64;
6166
#endif
6167
0
            status = NC_ERANGE; /* because tp is unsigned */
6168
            
6169
#ifdef ERANGE_FILL
6170
            xp++; tp++; continue;
6171
#endif
6172
0
        }
6173
0
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
6174
0
    }
6175
6176
0
    *xpp = (void *)(xp + rndup);
6177
0
    return status;
6178
0
}
6179
6180
6181
int
6182
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6183
0
{
6184
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
6185
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6186
6187
0
  return NC_NOERR;
6188
6189
0
}
6190
int
6191
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6192
0
{
6193
0
    int status = NC_NOERR;
6194
0
    schar *xp = (schar *) *xpp;
6195
6196
0
    while (nelems-- != 0) {
6197
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
6198
            
6199
#ifdef ERANGE_FILL
6200
            if (fillp != NULL) memcpy(xp, fillp, 1);
6201
#endif
6202
0
            status = NC_ERANGE;
6203
            
6204
#ifdef ERANGE_FILL
6205
            xp++; tp++; continue;
6206
#endif
6207
0
        }
6208
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6209
0
    }
6210
6211
0
    *xpp = (void *)xp;
6212
0
    return status;
6213
0
}
6214
6215
int
6216
ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6217
0
{
6218
0
    int status = NC_NOERR;
6219
0
    schar *xp = (schar *) *xpp;
6220
6221
0
    while (nelems-- != 0) {
6222
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6223
            
6224
#ifdef ERANGE_FILL
6225
            if (fillp != NULL) memcpy(xp, fillp, 1);
6226
#endif
6227
0
            status = NC_ERANGE;
6228
            
6229
#ifdef ERANGE_FILL
6230
            xp++; tp++; continue;
6231
#endif
6232
0
        }
6233
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6234
0
    }
6235
6236
0
    *xpp = (void *)xp;
6237
0
    return status;
6238
0
}
6239
6240
int
6241
ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6242
0
{
6243
0
    int status = NC_NOERR;
6244
0
    schar *xp = (schar *) *xpp;
6245
6246
0
    while (nelems-- != 0) {
6247
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6248
            
6249
#ifdef ERANGE_FILL
6250
            if (fillp != NULL) memcpy(xp, fillp, 1);
6251
#endif
6252
0
            status = NC_ERANGE;
6253
            
6254
#ifdef ERANGE_FILL
6255
            xp++; tp++; continue;
6256
#endif
6257
0
        }
6258
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6259
0
    }
6260
6261
0
    *xpp = (void *)xp;
6262
0
    return status;
6263
0
}
6264
6265
int
6266
ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6267
0
{
6268
0
    int status = NC_NOERR;
6269
0
    schar *xp = (schar *) *xpp;
6270
6271
0
    while (nelems-- != 0) {
6272
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6273
            
6274
#ifdef ERANGE_FILL
6275
            if (fillp != NULL) memcpy(xp, fillp, 1);
6276
#endif
6277
0
            status = NC_ERANGE;
6278
            
6279
#ifdef ERANGE_FILL
6280
            xp++; tp++; continue;
6281
#endif
6282
0
        }
6283
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6284
0
    }
6285
6286
0
    *xpp = (void *)xp;
6287
0
    return status;
6288
0
}
6289
6290
int
6291
ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6292
0
{
6293
0
    int status = NC_NOERR;
6294
0
    schar *xp = (schar *) *xpp;
6295
6296
0
    while (nelems-- != 0) {
6297
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6298
            
6299
#ifdef ERANGE_FILL
6300
            if (fillp != NULL) memcpy(xp, fillp, 1);
6301
#endif
6302
0
            status = NC_ERANGE;
6303
            
6304
#ifdef ERANGE_FILL
6305
            xp++; tp++; continue;
6306
#endif
6307
0
        }
6308
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6309
0
    }
6310
6311
0
    *xpp = (void *)xp;
6312
0
    return status;
6313
0
}
6314
6315
int
6316
ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6317
0
{
6318
0
    int status = NC_NOERR;
6319
0
    schar *xp = (schar *) *xpp;
6320
6321
0
    while (nelems-- != 0) {
6322
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6323
            
6324
#ifdef ERANGE_FILL
6325
            if (fillp != NULL) memcpy(xp, fillp, 1);
6326
#endif
6327
0
            status = NC_ERANGE;
6328
            
6329
#ifdef ERANGE_FILL
6330
            xp++; tp++; continue;
6331
#endif
6332
0
        }
6333
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6334
0
    }
6335
6336
0
    *xpp = (void *)xp;
6337
0
    return status;
6338
0
}
6339
6340
int
6341
ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6342
0
{
6343
0
    int status = NC_NOERR;
6344
0
    schar *xp = (schar *) *xpp;
6345
6346
0
    while (nelems-- != 0) {
6347
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6348
            
6349
#ifdef ERANGE_FILL
6350
            if (fillp != NULL) memcpy(xp, fillp, 1);
6351
#endif
6352
0
            status = NC_ERANGE;
6353
            
6354
#ifdef ERANGE_FILL
6355
            xp++; tp++; continue;
6356
#endif
6357
0
        }
6358
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6359
0
    }
6360
6361
0
    *xpp = (void *)xp;
6362
0
    return status;
6363
0
}
6364
6365
int
6366
ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6367
0
{
6368
0
    int status = NC_NOERR;
6369
0
    schar *xp = (schar *) *xpp;
6370
6371
0
    while (nelems-- != 0) {
6372
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6373
            
6374
#ifdef ERANGE_FILL
6375
            if (fillp != NULL) memcpy(xp, fillp, 1);
6376
#endif
6377
0
            status = NC_ERANGE;
6378
            
6379
#ifdef ERANGE_FILL
6380
            xp++; tp++; continue;
6381
#endif
6382
0
        }
6383
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6384
0
    }
6385
6386
0
    *xpp = (void *)xp;
6387
0
    return status;
6388
0
}
6389
6390
int
6391
ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6392
0
{
6393
0
    int status = NC_NOERR;
6394
0
    schar *xp = (schar *) *xpp;
6395
6396
0
    while (nelems-- != 0) {
6397
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6398
            
6399
#ifdef ERANGE_FILL
6400
            if (fillp != NULL) memcpy(xp, fillp, 1);
6401
#endif
6402
0
            status = NC_ERANGE;
6403
            
6404
#ifdef ERANGE_FILL
6405
            xp++; tp++; continue;
6406
#endif
6407
0
        }
6408
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6409
0
    }
6410
6411
0
    *xpp = (void *)xp;
6412
0
    return status;
6413
0
}
6414
6415
int
6416
ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6417
0
{
6418
0
    int status = NC_NOERR;
6419
0
    schar *xp = (schar *) *xpp;
6420
6421
0
    while (nelems-- != 0) {
6422
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6423
            
6424
#ifdef ERANGE_FILL
6425
            if (fillp != NULL) memcpy(xp, fillp, 1);
6426
#endif
6427
0
            status = NC_ERANGE;
6428
            
6429
#ifdef ERANGE_FILL
6430
            xp++; tp++; continue;
6431
#endif
6432
0
        }
6433
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6434
0
    }
6435
6436
0
    *xpp = (void *)xp;
6437
0
    return status;
6438
0
}
6439
6440
6441
int
6442
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6443
0
{
6444
0
    size_t rndup = nelems % X_ALIGN;
6445
6446
0
  if (rndup)
6447
0
    rndup = X_ALIGN - rndup;
6448
6449
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
6450
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6451
6452
0
  if (rndup)
6453
0
  {
6454
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
6455
0
    *xpp = (void *)((char *)(*xpp) + rndup);
6456
0
  }
6457
6458
0
  return NC_NOERR;
6459
6460
0
}
6461
int
6462
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6463
0
{
6464
0
    int status = NC_NOERR;
6465
0
    size_t rndup = nelems % X_ALIGN;
6466
0
    schar *xp = (schar *) *xpp;
6467
6468
0
    if (rndup) rndup = X_ALIGN - rndup;
6469
6470
0
    while (nelems-- != 0) {
6471
0
        if (*tp > (uchar)X_SCHAR_MAX ) {
6472
            
6473
#ifdef ERANGE_FILL
6474
            if (fillp != NULL) memcpy(xp, fillp, 1);
6475
#endif
6476
0
            status = NC_ERANGE;
6477
            
6478
#ifdef ERANGE_FILL
6479
            xp++; tp++; continue;
6480
#endif
6481
0
        }
6482
0
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6483
0
    }
6484
6485
6486
0
    if (rndup) {
6487
0
        (void) memcpy(xp, nada, (size_t)rndup);
6488
0
        xp += rndup;
6489
0
    }
6490
6491
0
    *xpp = (void *)xp;
6492
0
    return status;
6493
0
}
6494
6495
int
6496
ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6497
0
{
6498
0
    int status = NC_NOERR;
6499
0
    size_t rndup = nelems % X_ALIGN;
6500
0
    schar *xp = (schar *) *xpp;
6501
6502
0
    if (rndup) rndup = X_ALIGN - rndup;
6503
6504
0
    while (nelems-- != 0) {
6505
0
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6506
            
6507
#ifdef ERANGE_FILL
6508
            if (fillp != NULL) memcpy(xp, fillp, 1);
6509
#endif
6510
0
            status = NC_ERANGE;
6511
            
6512
#ifdef ERANGE_FILL
6513
            xp++; tp++; continue;
6514
#endif
6515
0
        }
6516
0
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
6517
0
    }
6518
6519
6520
0
    if (rndup) {
6521
0
        (void) memcpy(xp, nada, (size_t)rndup);
6522
0
        xp += rndup;
6523
0
    }
6524
6525
0
    *xpp = (void *)xp;
6526
0
    return status;
6527
0
}
6528
6529
int
6530
ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6531
0
{
6532
0
    int status = NC_NOERR;
6533
0
    size_t rndup = nelems % X_ALIGN;
6534
0
    schar *xp = (schar *) *xpp;
6535
6536
0
    if (rndup) rndup = X_ALIGN - rndup;
6537
6538
0
    while (nelems-- != 0) {
6539
0
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6540
            
6541
#ifdef ERANGE_FILL
6542
            if (fillp != NULL) memcpy(xp, fillp, 1);
6543
#endif
6544
0
            status = NC_ERANGE;
6545
            
6546
#ifdef ERANGE_FILL
6547
            xp++; tp++; continue;
6548
#endif
6549
0
        }
6550
0
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
6551
0
    }
6552
6553
6554
0
    if (rndup) {
6555
0
        (void) memcpy(xp, nada, (size_t)rndup);
6556
0
        xp += rndup;
6557
0
    }
6558
6559
0
    *xpp = (void *)xp;
6560
0
    return status;
6561
0
}
6562
6563
int
6564
ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6565
0
{
6566
0
    int status = NC_NOERR;
6567
0
    size_t rndup = nelems % X_ALIGN;
6568
0
    schar *xp = (schar *) *xpp;
6569
6570
0
    if (rndup) rndup = X_ALIGN - rndup;
6571
6572
0
    while (nelems-- != 0) {
6573
0
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6574
            
6575
#ifdef ERANGE_FILL
6576
            if (fillp != NULL) memcpy(xp, fillp, 1);
6577
#endif
6578
0
            status = NC_ERANGE;
6579
            
6580
#ifdef ERANGE_FILL
6581
            xp++; tp++; continue;
6582
#endif
6583
0
        }
6584
0
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
6585
0
    }
6586
6587
6588
0
    if (rndup) {
6589
0
        (void) memcpy(xp, nada, (size_t)rndup);
6590
0
        xp += rndup;
6591
0
    }
6592
6593
0
    *xpp = (void *)xp;
6594
0
    return status;
6595
0
}
6596
6597
int
6598
ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6599
0
{
6600
0
    int status = NC_NOERR;
6601
0
    size_t rndup = nelems % X_ALIGN;
6602
0
    schar *xp = (schar *) *xpp;
6603
6604
0
    if (rndup) rndup = X_ALIGN - rndup;
6605
6606
0
    while (nelems-- != 0) {
6607
0
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6608
            
6609
#ifdef ERANGE_FILL
6610
            if (fillp != NULL) memcpy(xp, fillp, 1);
6611
#endif
6612
0
            status = NC_ERANGE;
6613
            
6614
#ifdef ERANGE_FILL
6615
            xp++; tp++; continue;
6616
#endif
6617
0
        }
6618
0
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
6619
0
    }
6620
6621
6622
0
    if (rndup) {
6623
0
        (void) memcpy(xp, nada, (size_t)rndup);
6624
0
        xp += rndup;
6625
0
    }
6626
6627
0
    *xpp = (void *)xp;
6628
0
    return status;
6629
0
}
6630
6631
int
6632
ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6633
0
{
6634
0
    int status = NC_NOERR;
6635
0
    size_t rndup = nelems % X_ALIGN;
6636
0
    schar *xp = (schar *) *xpp;
6637
6638
0
    if (rndup) rndup = X_ALIGN - rndup;
6639
6640
0
    while (nelems-- != 0) {
6641
0
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6642
            
6643
#ifdef ERANGE_FILL
6644
            if (fillp != NULL) memcpy(xp, fillp, 1);
6645
#endif
6646
0
            status = NC_ERANGE;
6647
            
6648
#ifdef ERANGE_FILL
6649
            xp++; tp++; continue;
6650
#endif
6651
0
        }
6652
0
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
6653
0
    }
6654
6655
6656
0
    if (rndup) {
6657
0
        (void) memcpy(xp, nada, (size_t)rndup);
6658
0
        xp += rndup;
6659
0
    }
6660
6661
0
    *xpp = (void *)xp;
6662
0
    return status;
6663
0
}
6664
6665
int
6666
ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6667
0
{
6668
0
    int status = NC_NOERR;
6669
0
    size_t rndup = nelems % X_ALIGN;
6670
0
    schar *xp = (schar *) *xpp;
6671
6672
0
    if (rndup) rndup = X_ALIGN - rndup;
6673
6674
0
    while (nelems-- != 0) {
6675
0
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6676
            
6677
#ifdef ERANGE_FILL
6678
            if (fillp != NULL) memcpy(xp, fillp, 1);
6679
#endif
6680
0
            status = NC_ERANGE;
6681
            
6682
#ifdef ERANGE_FILL
6683
            xp++; tp++; continue;
6684
#endif
6685
0
        }
6686
0
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6687
0
    }
6688
6689
6690
0
    if (rndup) {
6691
0
        (void) memcpy(xp, nada, (size_t)rndup);
6692
0
        xp += rndup;
6693
0
    }
6694
6695
0
    *xpp = (void *)xp;
6696
0
    return status;
6697
0
}
6698
6699
int
6700
ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6701
0
{
6702
0
    int status = NC_NOERR;
6703
0
    size_t rndup = nelems % X_ALIGN;
6704
0
    schar *xp = (schar *) *xpp;
6705
6706
0
    if (rndup) rndup = X_ALIGN - rndup;
6707
6708
0
    while (nelems-- != 0) {
6709
0
        if (*tp > (ushort)X_SCHAR_MAX ) {
6710
            
6711
#ifdef ERANGE_FILL
6712
            if (fillp != NULL) memcpy(xp, fillp, 1);
6713
#endif
6714
0
            status = NC_ERANGE;
6715
            
6716
#ifdef ERANGE_FILL
6717
            xp++; tp++; continue;
6718
#endif
6719
0
        }
6720
0
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6721
0
    }
6722
6723
6724
0
    if (rndup) {
6725
0
        (void) memcpy(xp, nada, (size_t)rndup);
6726
0
        xp += rndup;
6727
0
    }
6728
6729
0
    *xpp = (void *)xp;
6730
0
    return status;
6731
0
}
6732
6733
int
6734
ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6735
0
{
6736
0
    int status = NC_NOERR;
6737
0
    size_t rndup = nelems % X_ALIGN;
6738
0
    schar *xp = (schar *) *xpp;
6739
6740
0
    if (rndup) rndup = X_ALIGN - rndup;
6741
6742
0
    while (nelems-- != 0) {
6743
0
        if (*tp > (uint)X_SCHAR_MAX ) {
6744
            
6745
#ifdef ERANGE_FILL
6746
            if (fillp != NULL) memcpy(xp, fillp, 1);
6747
#endif
6748
0
            status = NC_ERANGE;
6749
            
6750
#ifdef ERANGE_FILL
6751
            xp++; tp++; continue;
6752
#endif
6753
0
        }
6754
0
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6755
0
    }
6756
6757
6758
0
    if (rndup) {
6759
0
        (void) memcpy(xp, nada, (size_t)rndup);
6760
0
        xp += rndup;
6761
0
    }
6762
6763
0
    *xpp = (void *)xp;
6764
0
    return status;
6765
0
}
6766
6767
int
6768
ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6769
0
{
6770
0
    int status = NC_NOERR;
6771
0
    size_t rndup = nelems % X_ALIGN;
6772
0
    schar *xp = (schar *) *xpp;
6773
6774
0
    if (rndup) rndup = X_ALIGN - rndup;
6775
6776
0
    while (nelems-- != 0) {
6777
0
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
6778
            
6779
#ifdef ERANGE_FILL
6780
            if (fillp != NULL) memcpy(xp, fillp, 1);
6781
#endif
6782
0
            status = NC_ERANGE;
6783
            
6784
#ifdef ERANGE_FILL
6785
            xp++; tp++; continue;
6786
#endif
6787
0
        }
6788
0
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6789
0
    }
6790
6791
6792
0
    if (rndup) {
6793
0
        (void) memcpy(xp, nada, (size_t)rndup);
6794
0
        xp += rndup;
6795
0
    }
6796
6797
0
    *xpp = (void *)xp;
6798
0
    return status;
6799
0
}
6800
6801
6802
6803
/* uchar ---------------------------------------------------------------------*/
6804
int
6805
ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6806
0
{
6807
0
    int status = NC_NOERR;
6808
0
    uchar *xp = (uchar *)(*xpp);
6809
6810
0
    while (nelems-- != 0) {
6811
0
        if (*xp > SCHAR_MAX) {
6812
0
            *tp = NC_FILL_BYTE;
6813
0
            status = NC_ERANGE;
6814
            
6815
#ifdef ERANGE_FILL
6816
            xp++; tp++; continue;
6817
#endif
6818
0
        }
6819
0
  *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6820
0
    }
6821
6822
0
    *xpp = (const void *)xp;
6823
0
    return status;
6824
0
}
6825
int
6826
ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6827
0
{
6828
0
    (void) memcpy(tp, *xpp, (size_t)nelems);
6829
0
  *xpp = (void *)((char *)(*xpp) + nelems);
6830
0
  return NC_NOERR;
6831
6832
0
}
6833
int
6834
ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6835
0
{
6836
0
    int status = NC_NOERR;
6837
0
    uchar *xp = (uchar *)(*xpp);
6838
6839
0
    while (nelems-- != 0) {
6840
        
6841
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6842
0
    }
6843
6844
0
    *xpp = (const void *)xp;
6845
0
    return status;
6846
0
}
6847
6848
int
6849
ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6850
0
{
6851
0
    int status = NC_NOERR;
6852
0
    uchar *xp = (uchar *)(*xpp);
6853
6854
0
    while (nelems-- != 0) {
6855
        
6856
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6857
0
    }
6858
6859
0
    *xpp = (const void *)xp;
6860
0
    return status;
6861
0
}
6862
6863
int
6864
ncx_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6865
0
{
6866
0
    int status = NC_NOERR;
6867
0
    uchar *xp = (uchar *)(*xpp);
6868
6869
0
    while (nelems-- != 0) {
6870
        
6871
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6872
0
    }
6873
6874
0
    *xpp = (const void *)xp;
6875
0
    return status;
6876
0
}
6877
6878
int
6879
ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6880
0
{
6881
0
    int status = NC_NOERR;
6882
0
    uchar *xp = (uchar *)(*xpp);
6883
6884
0
    while (nelems-- != 0) {
6885
        
6886
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6887
0
    }
6888
6889
0
    *xpp = (const void *)xp;
6890
0
    return status;
6891
0
}
6892
6893
int
6894
ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6895
0
{
6896
0
    int status = NC_NOERR;
6897
0
    uchar *xp = (uchar *)(*xpp);
6898
6899
0
    while (nelems-- != 0) {
6900
        
6901
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6902
0
    }
6903
6904
0
    *xpp = (const void *)xp;
6905
0
    return status;
6906
0
}
6907
6908
int
6909
ncx_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6910
0
{
6911
0
    int status = NC_NOERR;
6912
0
    uchar *xp = (uchar *)(*xpp);
6913
6914
0
    while (nelems-- != 0) {
6915
        
6916
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6917
0
    }
6918
6919
0
    *xpp = (const void *)xp;
6920
0
    return status;
6921
0
}
6922
6923
int
6924
ncx_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6925
0
{
6926
0
    int status = NC_NOERR;
6927
0
    uchar *xp = (uchar *)(*xpp);
6928
6929
0
    while (nelems-- != 0) {
6930
        
6931
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6932
0
    }
6933
6934
0
    *xpp = (const void *)xp;
6935
0
    return status;
6936
0
}
6937
6938
int
6939
ncx_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6940
0
{
6941
0
    int status = NC_NOERR;
6942
0
    uchar *xp = (uchar *)(*xpp);
6943
6944
0
    while (nelems-- != 0) {
6945
        
6946
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6947
0
    }
6948
6949
0
    *xpp = (const void *)xp;
6950
0
    return status;
6951
0
}
6952
6953
int
6954
ncx_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6955
0
{
6956
0
    int status = NC_NOERR;
6957
0
    uchar *xp = (uchar *)(*xpp);
6958
6959
0
    while (nelems-- != 0) {
6960
        
6961
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6962
0
    }
6963
6964
0
    *xpp = (const void *)xp;
6965
0
    return status;
6966
0
}
6967
6968
6969
int
6970
ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6971
0
{
6972
0
    int status = NC_NOERR;
6973
0
    size_t rndup = nelems % X_ALIGN;
6974
0
    uchar *xp = (uchar *) *xpp;
6975
6976
0
    if (rndup) rndup = X_ALIGN - rndup;
6977
6978
0
    while (nelems-- != 0) {
6979
0
        if (*xp > SCHAR_MAX) {
6980
0
            *tp = NC_FILL_BYTE;
6981
0
            status = NC_ERANGE;
6982
            
6983
#ifdef ERANGE_FILL
6984
            xp++; tp++; continue;
6985
#endif
6986
0
        }
6987
0
        *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6988
0
    }
6989
6990
0
    *xpp = (void *)(xp + rndup);
6991
0
    return status;
6992
0
}
6993
int
6994
ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6995
0
{
6996
0
    size_t rndup = nelems % X_ALIGN;
6997
6998
0
  if (rndup)
6999
0
    rndup = X_ALIGN - rndup;
7000
7001
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
7002
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
7003
7004
0
  return NC_NOERR;
7005
7006
0
}
7007
int
7008
ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
7009
0
{
7010
0
    int status = NC_NOERR;
7011
0
    size_t rndup = nelems % X_ALIGN;
7012
0
    uchar *xp = (uchar *) *xpp;
7013
7014
0
    if (rndup)
7015
0
        rndup = X_ALIGN - rndup;
7016
7017
0
    while (nelems-- != 0) {
7018
        
7019
0
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
7020
0
    }
7021
7022
0
    *xpp = (void *)(xp + rndup);
7023
0
    return status;
7024
0
}
7025
7026
int
7027
ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
7028
0
{
7029
0
    int status = NC_NOERR;
7030
0
    size_t rndup = nelems % X_ALIGN;
7031
0
    uchar *xp = (uchar *) *xpp;
7032
7033
0
    if (rndup)
7034
0
        rndup = X_ALIGN - rndup;
7035
7036
0
    while (nelems-- != 0) {
7037
        
7038
0
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
7039
0
    }
7040
7041
0
    *xpp = (void *)(xp + rndup);
7042
0
    return status;
7043
0
}
7044
7045
int
7046
ncx_pad_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
7047
0
{
7048
0
    int status = NC_NOERR;
7049
0
    size_t rndup = nelems % X_ALIGN;
7050
0
    uchar *xp = (uchar *) *xpp;
7051
7052
0
    if (rndup)
7053
0
        rndup = X_ALIGN - rndup;
7054
7055
0
    while (nelems-- != 0) {
7056
        
7057
0
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
7058
0
    }
7059
7060
0
    *xpp = (void *)(xp + rndup);
7061
0
    return status;
7062
0
}
7063
7064
int
7065
ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
7066
0
{
7067
0
    int status = NC_NOERR;
7068
0
    size_t rndup = nelems % X_ALIGN;
7069
0
    uchar *xp = (uchar *) *xpp;
7070
7071
0
    if (rndup)
7072
0
        rndup = X_ALIGN - rndup;
7073
7074
0
    while (nelems-- != 0) {
7075
        
7076
0
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
7077
0
    }
7078
7079
0
    *xpp = (void *)(xp + rndup);
7080
0
    return status;
7081
0
}
7082
7083
int
7084
ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
7085
0
{
7086
0
    int status = NC_NOERR;
7087
0
    size_t rndup = nelems % X_ALIGN;
7088
0
    uchar *xp = (uchar *) *xpp;
7089
7090
0
    if (rndup)
7091
0
        rndup = X_ALIGN - rndup;
7092
7093
0
    while (nelems-- != 0) {
7094
        
7095
0
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
7096
0
    }
7097
7098
0
    *xpp = (void *)(xp + rndup);
7099
0
    return status;
7100
0
}
7101
7102
int
7103
ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
7104
0
{
7105
0
    int status = NC_NOERR;
7106
0
    size_t rndup = nelems % X_ALIGN;
7107
0
    uchar *xp = (uchar *) *xpp;
7108
7109
0
    if (rndup)
7110
0
        rndup = X_ALIGN - rndup;
7111
7112
0
    while (nelems-- != 0) {
7113
        
7114
0
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
7115
0
    }
7116
7117
0
    *xpp = (void *)(xp + rndup);
7118
0
    return status;
7119
0
}
7120
7121
int
7122
ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
7123
0
{
7124
0
    int status = NC_NOERR;
7125
0
    size_t rndup = nelems % X_ALIGN;
7126
0
    uchar *xp = (uchar *) *xpp;
7127
7128
0
    if (rndup)
7129
0
        rndup = X_ALIGN - rndup;
7130
7131
0
    while (nelems-- != 0) {
7132
        
7133
0
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
7134
0
    }
7135
7136
0
    *xpp = (void *)(xp + rndup);
7137
0
    return status;
7138
0
}
7139
7140
int
7141
ncx_pad_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
7142
0
{
7143
0
    int status = NC_NOERR;
7144
0
    size_t rndup = nelems % X_ALIGN;
7145
0
    uchar *xp = (uchar *) *xpp;
7146
7147
0
    if (rndup)
7148
0
        rndup = X_ALIGN - rndup;
7149
7150
0
    while (nelems-- != 0) {
7151
        
7152
0
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
7153
0
    }
7154
7155
0
    *xpp = (void *)(xp + rndup);
7156
0
    return status;
7157
0
}
7158
7159
int
7160
ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
7161
0
{
7162
0
    int status = NC_NOERR;
7163
0
    size_t rndup = nelems % X_ALIGN;
7164
0
    uchar *xp = (uchar *) *xpp;
7165
7166
0
    if (rndup)
7167
0
        rndup = X_ALIGN - rndup;
7168
7169
0
    while (nelems-- != 0) {
7170
        
7171
0
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
7172
0
    }
7173
7174
0
    *xpp = (void *)(xp + rndup);
7175
0
    return status;
7176
0
}
7177
7178
7179
int
7180
ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7181
0
{
7182
0
    int status = NC_NOERR;
7183
0
    uchar *xp = (uchar *) *xpp;
7184
7185
0
    while (nelems-- != 0) {
7186
0
        if (*tp < 0) {
7187
            
7188
#ifdef ERANGE_FILL
7189
            if (fillp != NULL) memcpy(xp, fillp, 1);
7190
#endif
7191
0
            status = NC_ERANGE;
7192
            
7193
#ifdef ERANGE_FILL
7194
            xp++; tp++; continue;
7195
#endif
7196
0
        }
7197
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7198
0
    }
7199
7200
0
    *xpp = (void *)xp;
7201
0
    return status;
7202
0
}
7203
int
7204
ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7205
0
{
7206
0
    (void) memcpy(*xpp, tp, (size_t)nelems);
7207
0
  *xpp = (void *)((char *)(*xpp) + nelems);
7208
7209
0
  return NC_NOERR;
7210
7211
0
}
7212
int
7213
ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7214
0
{
7215
0
    int status = NC_NOERR;
7216
0
    uchar *xp = (uchar *) *xpp;
7217
7218
0
    while (nelems-- != 0) {
7219
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7220
            
7221
#ifdef ERANGE_FILL
7222
            if (fillp != NULL) memcpy(xp, fillp, 1);
7223
#endif
7224
0
            status = NC_ERANGE;
7225
            
7226
#ifdef ERANGE_FILL
7227
            xp++; tp++; continue;
7228
#endif
7229
0
        }
7230
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7231
0
    }
7232
7233
0
    *xpp = (void *)xp;
7234
0
    return status;
7235
0
}
7236
7237
int
7238
ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7239
0
{
7240
0
    int status = NC_NOERR;
7241
0
    uchar *xp = (uchar *) *xpp;
7242
7243
0
    while (nelems-- != 0) {
7244
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7245
            
7246
#ifdef ERANGE_FILL
7247
            if (fillp != NULL) memcpy(xp, fillp, 1);
7248
#endif
7249
0
            status = NC_ERANGE;
7250
            
7251
#ifdef ERANGE_FILL
7252
            xp++; tp++; continue;
7253
#endif
7254
0
        }
7255
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7256
0
    }
7257
7258
0
    *xpp = (void *)xp;
7259
0
    return status;
7260
0
}
7261
7262
int
7263
ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7264
0
{
7265
0
    int status = NC_NOERR;
7266
0
    uchar *xp = (uchar *) *xpp;
7267
7268
0
    while (nelems-- != 0) {
7269
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7270
            
7271
#ifdef ERANGE_FILL
7272
            if (fillp != NULL) memcpy(xp, fillp, 1);
7273
#endif
7274
0
            status = NC_ERANGE;
7275
            
7276
#ifdef ERANGE_FILL
7277
            xp++; tp++; continue;
7278
#endif
7279
0
        }
7280
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7281
0
    }
7282
7283
0
    *xpp = (void *)xp;
7284
0
    return status;
7285
0
}
7286
7287
int
7288
ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7289
0
{
7290
0
    int status = NC_NOERR;
7291
0
    uchar *xp = (uchar *) *xpp;
7292
7293
0
    while (nelems-- != 0) {
7294
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7295
            
7296
#ifdef ERANGE_FILL
7297
            if (fillp != NULL) memcpy(xp, fillp, 1);
7298
#endif
7299
0
            status = NC_ERANGE;
7300
            
7301
#ifdef ERANGE_FILL
7302
            xp++; tp++; continue;
7303
#endif
7304
0
        }
7305
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7306
0
    }
7307
7308
0
    *xpp = (void *)xp;
7309
0
    return status;
7310
0
}
7311
7312
int
7313
ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7314
0
{
7315
0
    int status = NC_NOERR;
7316
0
    uchar *xp = (uchar *) *xpp;
7317
7318
0
    while (nelems-- != 0) {
7319
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7320
            
7321
#ifdef ERANGE_FILL
7322
            if (fillp != NULL) memcpy(xp, fillp, 1);
7323
#endif
7324
0
            status = NC_ERANGE;
7325
            
7326
#ifdef ERANGE_FILL
7327
            xp++; tp++; continue;
7328
#endif
7329
0
        }
7330
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7331
0
    }
7332
7333
0
    *xpp = (void *)xp;
7334
0
    return status;
7335
0
}
7336
7337
int
7338
ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7339
0
{
7340
0
    int status = NC_NOERR;
7341
0
    uchar *xp = (uchar *) *xpp;
7342
7343
0
    while (nelems-- != 0) {
7344
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7345
            
7346
#ifdef ERANGE_FILL
7347
            if (fillp != NULL) memcpy(xp, fillp, 1);
7348
#endif
7349
0
            status = NC_ERANGE;
7350
            
7351
#ifdef ERANGE_FILL
7352
            xp++; tp++; continue;
7353
#endif
7354
0
        }
7355
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7356
0
    }
7357
7358
0
    *xpp = (void *)xp;
7359
0
    return status;
7360
0
}
7361
7362
int
7363
ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7364
0
{
7365
0
    int status = NC_NOERR;
7366
0
    uchar *xp = (uchar *) *xpp;
7367
7368
0
    while (nelems-- != 0) {
7369
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7370
            
7371
#ifdef ERANGE_FILL
7372
            if (fillp != NULL) memcpy(xp, fillp, 1);
7373
#endif
7374
0
            status = NC_ERANGE;
7375
            
7376
#ifdef ERANGE_FILL
7377
            xp++; tp++; continue;
7378
#endif
7379
0
        }
7380
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7381
0
    }
7382
7383
0
    *xpp = (void *)xp;
7384
0
    return status;
7385
0
}
7386
7387
int
7388
ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7389
0
{
7390
0
    int status = NC_NOERR;
7391
0
    uchar *xp = (uchar *) *xpp;
7392
7393
0
    while (nelems-- != 0) {
7394
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7395
            
7396
#ifdef ERANGE_FILL
7397
            if (fillp != NULL) memcpy(xp, fillp, 1);
7398
#endif
7399
0
            status = NC_ERANGE;
7400
            
7401
#ifdef ERANGE_FILL
7402
            xp++; tp++; continue;
7403
#endif
7404
0
        }
7405
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7406
0
    }
7407
7408
0
    *xpp = (void *)xp;
7409
0
    return status;
7410
0
}
7411
7412
int
7413
ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7414
0
{
7415
0
    int status = NC_NOERR;
7416
0
    uchar *xp = (uchar *) *xpp;
7417
7418
0
    while (nelems-- != 0) {
7419
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7420
            
7421
#ifdef ERANGE_FILL
7422
            if (fillp != NULL) memcpy(xp, fillp, 1);
7423
#endif
7424
0
            status = NC_ERANGE;
7425
            
7426
#ifdef ERANGE_FILL
7427
            xp++; tp++; continue;
7428
#endif
7429
0
        }
7430
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7431
0
    }
7432
7433
0
    *xpp = (void *)xp;
7434
0
    return status;
7435
0
}
7436
7437
7438
int
7439
ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7440
0
{
7441
0
    int status = NC_NOERR;
7442
0
    size_t rndup = nelems % X_ALIGN;
7443
0
    uchar *xp = (uchar *) *xpp;
7444
7445
0
    if (rndup) rndup = X_ALIGN - rndup;
7446
7447
0
    while (nelems-- != 0) {
7448
0
        if (*tp < 0) {
7449
            
7450
#ifdef ERANGE_FILL
7451
            if (fillp != NULL) memcpy(xp, fillp, 1);
7452
#endif
7453
0
            status = NC_ERANGE;
7454
            
7455
#ifdef ERANGE_FILL
7456
            xp++; tp++; continue;
7457
#endif
7458
0
        }
7459
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7460
0
    }
7461
7462
0
    if (rndup) {
7463
0
        (void) memcpy(xp, nada, (size_t)rndup);
7464
0
        xp += rndup;
7465
0
    }
7466
7467
0
    *xpp = (void *)xp;
7468
0
    return status;
7469
0
}
7470
int
7471
ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7472
0
{
7473
0
    size_t rndup = nelems % X_ALIGN;
7474
7475
0
  if (rndup)
7476
0
    rndup = X_ALIGN - rndup;
7477
7478
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
7479
0
  *xpp = (void *)((char *)(*xpp) + nelems);
7480
7481
0
  if (rndup)
7482
0
  {
7483
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
7484
0
    *xpp = (void *)((char *)(*xpp) + rndup);
7485
0
  }
7486
7487
0
  return NC_NOERR;
7488
7489
0
}
7490
int
7491
ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7492
0
{
7493
0
    int status = NC_NOERR;
7494
0
    size_t rndup = nelems % X_ALIGN;
7495
0
    uchar *xp = (uchar *) *xpp;
7496
7497
0
    if (rndup) rndup = X_ALIGN - rndup;
7498
7499
0
    while (nelems-- != 0) {
7500
0
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7501
            
7502
#ifdef ERANGE_FILL
7503
            if (fillp != NULL) memcpy(xp, fillp, 1);
7504
#endif
7505
0
            status = NC_ERANGE;
7506
            
7507
#ifdef ERANGE_FILL
7508
            xp++; tp++; continue;
7509
#endif
7510
0
        }
7511
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7512
0
    }
7513
7514
7515
0
    if (rndup) {
7516
0
        (void) memcpy(xp, nada, (size_t)rndup);
7517
0
        xp += rndup;
7518
0
    }
7519
7520
0
    *xpp = (void *)xp;
7521
0
    return status;
7522
0
}
7523
7524
int
7525
ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7526
0
{
7527
0
    int status = NC_NOERR;
7528
0
    size_t rndup = nelems % X_ALIGN;
7529
0
    uchar *xp = (uchar *) *xpp;
7530
7531
0
    if (rndup) rndup = X_ALIGN - rndup;
7532
7533
0
    while (nelems-- != 0) {
7534
0
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7535
            
7536
#ifdef ERANGE_FILL
7537
            if (fillp != NULL) memcpy(xp, fillp, 1);
7538
#endif
7539
0
            status = NC_ERANGE;
7540
            
7541
#ifdef ERANGE_FILL
7542
            xp++; tp++; continue;
7543
#endif
7544
0
        }
7545
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7546
0
    }
7547
7548
7549
0
    if (rndup) {
7550
0
        (void) memcpy(xp, nada, (size_t)rndup);
7551
0
        xp += rndup;
7552
0
    }
7553
7554
0
    *xpp = (void *)xp;
7555
0
    return status;
7556
0
}
7557
7558
int
7559
ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7560
0
{
7561
0
    int status = NC_NOERR;
7562
0
    size_t rndup = nelems % X_ALIGN;
7563
0
    uchar *xp = (uchar *) *xpp;
7564
7565
0
    if (rndup) rndup = X_ALIGN - rndup;
7566
7567
0
    while (nelems-- != 0) {
7568
0
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7569
            
7570
#ifdef ERANGE_FILL
7571
            if (fillp != NULL) memcpy(xp, fillp, 1);
7572
#endif
7573
0
            status = NC_ERANGE;
7574
            
7575
#ifdef ERANGE_FILL
7576
            xp++; tp++; continue;
7577
#endif
7578
0
        }
7579
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7580
0
    }
7581
7582
7583
0
    if (rndup) {
7584
0
        (void) memcpy(xp, nada, (size_t)rndup);
7585
0
        xp += rndup;
7586
0
    }
7587
7588
0
    *xpp = (void *)xp;
7589
0
    return status;
7590
0
}
7591
7592
int
7593
ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7594
0
{
7595
0
    int status = NC_NOERR;
7596
0
    size_t rndup = nelems % X_ALIGN;
7597
0
    uchar *xp = (uchar *) *xpp;
7598
7599
0
    if (rndup) rndup = X_ALIGN - rndup;
7600
7601
0
    while (nelems-- != 0) {
7602
0
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7603
            
7604
#ifdef ERANGE_FILL
7605
            if (fillp != NULL) memcpy(xp, fillp, 1);
7606
#endif
7607
0
            status = NC_ERANGE;
7608
            
7609
#ifdef ERANGE_FILL
7610
            xp++; tp++; continue;
7611
#endif
7612
0
        }
7613
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7614
0
    }
7615
7616
7617
0
    if (rndup) {
7618
0
        (void) memcpy(xp, nada, (size_t)rndup);
7619
0
        xp += rndup;
7620
0
    }
7621
7622
0
    *xpp = (void *)xp;
7623
0
    return status;
7624
0
}
7625
7626
int
7627
ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7628
0
{
7629
0
    int status = NC_NOERR;
7630
0
    size_t rndup = nelems % X_ALIGN;
7631
0
    uchar *xp = (uchar *) *xpp;
7632
7633
0
    if (rndup) rndup = X_ALIGN - rndup;
7634
7635
0
    while (nelems-- != 0) {
7636
0
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7637
            
7638
#ifdef ERANGE_FILL
7639
            if (fillp != NULL) memcpy(xp, fillp, 1);
7640
#endif
7641
0
            status = NC_ERANGE;
7642
            
7643
#ifdef ERANGE_FILL
7644
            xp++; tp++; continue;
7645
#endif
7646
0
        }
7647
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7648
0
    }
7649
7650
7651
0
    if (rndup) {
7652
0
        (void) memcpy(xp, nada, (size_t)rndup);
7653
0
        xp += rndup;
7654
0
    }
7655
7656
0
    *xpp = (void *)xp;
7657
0
    return status;
7658
0
}
7659
7660
int
7661
ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7662
0
{
7663
0
    int status = NC_NOERR;
7664
0
    size_t rndup = nelems % X_ALIGN;
7665
0
    uchar *xp = (uchar *) *xpp;
7666
7667
0
    if (rndup) rndup = X_ALIGN - rndup;
7668
7669
0
    while (nelems-- != 0) {
7670
0
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7671
            
7672
#ifdef ERANGE_FILL
7673
            if (fillp != NULL) memcpy(xp, fillp, 1);
7674
#endif
7675
0
            status = NC_ERANGE;
7676
            
7677
#ifdef ERANGE_FILL
7678
            xp++; tp++; continue;
7679
#endif
7680
0
        }
7681
0
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7682
0
    }
7683
7684
7685
0
    if (rndup) {
7686
0
        (void) memcpy(xp, nada, (size_t)rndup);
7687
0
        xp += rndup;
7688
0
    }
7689
7690
0
    *xpp = (void *)xp;
7691
0
    return status;
7692
0
}
7693
7694
int
7695
ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7696
0
{
7697
0
    int status = NC_NOERR;
7698
0
    size_t rndup = nelems % X_ALIGN;
7699
0
    uchar *xp = (uchar *) *xpp;
7700
7701
0
    if (rndup) rndup = X_ALIGN - rndup;
7702
7703
0
    while (nelems-- != 0) {
7704
0
        if (*tp > (ushort)X_UCHAR_MAX ) {
7705
            
7706
#ifdef ERANGE_FILL
7707
            if (fillp != NULL) memcpy(xp, fillp, 1);
7708
#endif
7709
0
            status = NC_ERANGE;
7710
            
7711
#ifdef ERANGE_FILL
7712
            xp++; tp++; continue;
7713
#endif
7714
0
        }
7715
0
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7716
0
    }
7717
7718
7719
0
    if (rndup) {
7720
0
        (void) memcpy(xp, nada, (size_t)rndup);
7721
0
        xp += rndup;
7722
0
    }
7723
7724
0
    *xpp = (void *)xp;
7725
0
    return status;
7726
0
}
7727
7728
int
7729
ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7730
0
{
7731
0
    int status = NC_NOERR;
7732
0
    size_t rndup = nelems % X_ALIGN;
7733
0
    uchar *xp = (uchar *) *xpp;
7734
7735
0
    if (rndup) rndup = X_ALIGN - rndup;
7736
7737
0
    while (nelems-- != 0) {
7738
0
        if (*tp > (uint)X_UCHAR_MAX ) {
7739
            
7740
#ifdef ERANGE_FILL
7741
            if (fillp != NULL) memcpy(xp, fillp, 1);
7742
#endif
7743
0
            status = NC_ERANGE;
7744
            
7745
#ifdef ERANGE_FILL
7746
            xp++; tp++; continue;
7747
#endif
7748
0
        }
7749
0
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7750
0
    }
7751
7752
7753
0
    if (rndup) {
7754
0
        (void) memcpy(xp, nada, (size_t)rndup);
7755
0
        xp += rndup;
7756
0
    }
7757
7758
0
    *xpp = (void *)xp;
7759
0
    return status;
7760
0
}
7761
7762
int
7763
ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7764
0
{
7765
0
    int status = NC_NOERR;
7766
0
    size_t rndup = nelems % X_ALIGN;
7767
0
    uchar *xp = (uchar *) *xpp;
7768
7769
0
    if (rndup) rndup = X_ALIGN - rndup;
7770
7771
0
    while (nelems-- != 0) {
7772
0
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
7773
            
7774
#ifdef ERANGE_FILL
7775
            if (fillp != NULL) memcpy(xp, fillp, 1);
7776
#endif
7777
0
            status = NC_ERANGE;
7778
            
7779
#ifdef ERANGE_FILL
7780
            xp++; tp++; continue;
7781
#endif
7782
0
        }
7783
0
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7784
0
    }
7785
7786
7787
0
    if (rndup) {
7788
0
        (void) memcpy(xp, nada, (size_t)rndup);
7789
0
        xp += rndup;
7790
0
    }
7791
7792
0
    *xpp = (void *)xp;
7793
0
    return status;
7794
0
}
7795
7796
7797
/* short ---------------------------------------------------------------------*/
7798
7799
#if X_SIZEOF_SHORT == SIZEOF_SHORT
7800
/* optimized version */
7801
int
7802
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7803
0
{
7804
#ifdef WORDS_BIGENDIAN
7805
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
7806
# else
7807
0
  swapn2b(tp, *xpp, nelems);
7808
0
# endif
7809
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
7810
0
  return NC_NOERR;
7811
0
}
7812
#else
7813
int
7814
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7815
{
7816
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7817
7818
 /* basic algorithm is:
7819
  *   - ensure sane alignment of input data
7820
  *   - copy (conversion happens automatically) input data
7821
  *     to output
7822
  *   - update xpp to point at next unconverted input, and tp to point
7823
  *     at next location for converted output
7824
  */
7825
  long i, j, ni;
7826
  short tmp[LOOPCNT];        /* in case input is misaligned */
7827
  short *xp;
7828
  int nrange = 0;         /* number of range errors */
7829
  int realign = 0;        /* "do we need to fix input data alignment?" */
7830
  long cxp = (long) *((char**)xpp);
7831
7832
  realign = (cxp & 7) % SIZEOF_SHORT;
7833
  /* sjl: manually stripmine so we can limit amount of
7834
   * vector work space reserved to LOOPCNT elements. Also
7835
   * makes vectorisation easy */
7836
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7837
    ni=Min(nelems-j,LOOPCNT);
7838
    if (realign) {
7839
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7840
      xp = tmp;
7841
    } else {
7842
      xp = (short *) *xpp;
7843
    }
7844
   /* copy the next block */
7845
#pragma cdir loopcnt=LOOPCNT
7846
#pragma cdir shortloop
7847
    for (i=0; i<ni; i++) {
7848
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
7849
     /* test for range errors (not always needed but do it anyway) */
7850
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7851
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7852
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
7853
    }
7854
   /* update xpp and tp */
7855
    if (realign) xp = (short *) *xpp;
7856
    xp += ni;
7857
    tp += ni;
7858
    *xpp = (void*)xp;
7859
  }
7860
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7861
7862
#else   /* not SX */
7863
  const char *xp = (const char *) *xpp;
7864
  int status = NC_NOERR;
7865
7866
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7867
  {
7868
    const int lstatus = ncx_get_short_short(xp, tp);
7869
    if (status == NC_NOERR) /* report the first encountered error */
7870
      status = lstatus;
7871
  }
7872
7873
  *xpp = (const void *)xp;
7874
  return status;
7875
#endif
7876
}
7877
7878
#endif
7879
int
7880
ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
7881
0
{
7882
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7883
7884
 /* basic algorithm is:
7885
  *   - ensure sane alignment of input data
7886
  *   - copy (conversion happens automatically) input data
7887
  *     to output
7888
  *   - update xpp to point at next unconverted input, and tp to point
7889
  *     at next location for converted output
7890
  */
7891
  long i, j, ni;
7892
  short tmp[LOOPCNT];        /* in case input is misaligned */
7893
  short *xp;
7894
  int nrange = 0;         /* number of range errors */
7895
  int realign = 0;        /* "do we need to fix input data alignment?" */
7896
  long cxp = (long) *((char**)xpp);
7897
7898
  realign = (cxp & 7) % SIZEOF_SHORT;
7899
  /* sjl: manually stripmine so we can limit amount of
7900
   * vector work space reserved to LOOPCNT elements. Also
7901
   * makes vectorisation easy */
7902
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7903
    ni=Min(nelems-j,LOOPCNT);
7904
    if (realign) {
7905
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7906
      xp = tmp;
7907
    } else {
7908
      xp = (short *) *xpp;
7909
    }
7910
   /* copy the next block */
7911
#pragma cdir loopcnt=LOOPCNT
7912
#pragma cdir shortloop
7913
    for (i=0; i<ni; i++) {
7914
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
7915
     /* test for range errors (not always needed but do it anyway) */
7916
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7917
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7918
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
7919
    }
7920
   /* update xpp and tp */
7921
    if (realign) xp = (short *) *xpp;
7922
    xp += ni;
7923
    tp += ni;
7924
    *xpp = (void*)xp;
7925
  }
7926
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7927
7928
#else   /* not SX */
7929
0
  const char *xp = (const char *) *xpp;
7930
0
  int status = NC_NOERR;
7931
7932
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7933
0
  {
7934
0
    const int lstatus = ncx_get_short_schar(xp, tp);
7935
0
    if (status == NC_NOERR) /* report the first encountered error */
7936
0
      status = lstatus;
7937
0
  }
7938
7939
0
  *xpp = (const void *)xp;
7940
0
  return status;
7941
0
#endif
7942
0
}
7943
7944
int
7945
ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
7946
0
{
7947
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7948
7949
 /* basic algorithm is:
7950
  *   - ensure sane alignment of input data
7951
  *   - copy (conversion happens automatically) input data
7952
  *     to output
7953
  *   - update xpp to point at next unconverted input, and tp to point
7954
  *     at next location for converted output
7955
  */
7956
  long i, j, ni;
7957
  short tmp[LOOPCNT];        /* in case input is misaligned */
7958
  short *xp;
7959
  int nrange = 0;         /* number of range errors */
7960
  int realign = 0;        /* "do we need to fix input data alignment?" */
7961
  long cxp = (long) *((char**)xpp);
7962
7963
  realign = (cxp & 7) % SIZEOF_SHORT;
7964
  /* sjl: manually stripmine so we can limit amount of
7965
   * vector work space reserved to LOOPCNT elements. Also
7966
   * makes vectorisation easy */
7967
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7968
    ni=Min(nelems-j,LOOPCNT);
7969
    if (realign) {
7970
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7971
      xp = tmp;
7972
    } else {
7973
      xp = (short *) *xpp;
7974
    }
7975
   /* copy the next block */
7976
#pragma cdir loopcnt=LOOPCNT
7977
#pragma cdir shortloop
7978
    for (i=0; i<ni; i++) {
7979
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
7980
     /* test for range errors (not always needed but do it anyway) */
7981
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7982
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7983
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
7984
    }
7985
   /* update xpp and tp */
7986
    if (realign) xp = (short *) *xpp;
7987
    xp += ni;
7988
    tp += ni;
7989
    *xpp = (void*)xp;
7990
  }
7991
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
7992
7993
#else   /* not SX */
7994
0
  const char *xp = (const char *) *xpp;
7995
0
  int status = NC_NOERR;
7996
7997
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7998
0
  {
7999
0
    const int lstatus = ncx_get_short_int(xp, tp);
8000
0
    if (status == NC_NOERR) /* report the first encountered error */
8001
0
      status = lstatus;
8002
0
  }
8003
8004
0
  *xpp = (const void *)xp;
8005
0
  return status;
8006
0
#endif
8007
0
}
8008
8009
int
8010
ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
8011
0
{
8012
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8013
8014
 /* basic algorithm is:
8015
  *   - ensure sane alignment of input data
8016
  *   - copy (conversion happens automatically) input data
8017
  *     to output
8018
  *   - update xpp to point at next unconverted input, and tp to point
8019
  *     at next location for converted output
8020
  */
8021
  long i, j, ni;
8022
  short tmp[LOOPCNT];        /* in case input is misaligned */
8023
  short *xp;
8024
  int nrange = 0;         /* number of range errors */
8025
  int realign = 0;        /* "do we need to fix input data alignment?" */
8026
  long cxp = (long) *((char**)xpp);
8027
8028
  realign = (cxp & 7) % SIZEOF_SHORT;
8029
  /* sjl: manually stripmine so we can limit amount of
8030
   * vector work space reserved to LOOPCNT elements. Also
8031
   * makes vectorisation easy */
8032
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8033
    ni=Min(nelems-j,LOOPCNT);
8034
    if (realign) {
8035
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8036
      xp = tmp;
8037
    } else {
8038
      xp = (short *) *xpp;
8039
    }
8040
   /* copy the next block */
8041
#pragma cdir loopcnt=LOOPCNT
8042
#pragma cdir shortloop
8043
    for (i=0; i<ni; i++) {
8044
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
8045
     /* test for range errors (not always needed but do it anyway) */
8046
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8047
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8048
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
8049
    }
8050
   /* update xpp and tp */
8051
    if (realign) xp = (short *) *xpp;
8052
    xp += ni;
8053
    tp += ni;
8054
    *xpp = (void*)xp;
8055
  }
8056
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8057
8058
#else   /* not SX */
8059
0
  const char *xp = (const char *) *xpp;
8060
0
  int status = NC_NOERR;
8061
8062
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8063
0
  {
8064
0
    const int lstatus = ncx_get_short_long(xp, tp);
8065
0
    if (status == NC_NOERR) /* report the first encountered error */
8066
0
      status = lstatus;
8067
0
  }
8068
8069
0
  *xpp = (const void *)xp;
8070
0
  return status;
8071
0
#endif
8072
0
}
8073
8074
int
8075
ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
8076
0
{
8077
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8078
8079
 /* basic algorithm is:
8080
  *   - ensure sane alignment of input data
8081
  *   - copy (conversion happens automatically) input data
8082
  *     to output
8083
  *   - update xpp to point at next unconverted input, and tp to point
8084
  *     at next location for converted output
8085
  */
8086
  long i, j, ni;
8087
  short tmp[LOOPCNT];        /* in case input is misaligned */
8088
  short *xp;
8089
  int nrange = 0;         /* number of range errors */
8090
  int realign = 0;        /* "do we need to fix input data alignment?" */
8091
  long cxp = (long) *((char**)xpp);
8092
8093
  realign = (cxp & 7) % SIZEOF_SHORT;
8094
  /* sjl: manually stripmine so we can limit amount of
8095
   * vector work space reserved to LOOPCNT elements. Also
8096
   * makes vectorisation easy */
8097
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8098
    ni=Min(nelems-j,LOOPCNT);
8099
    if (realign) {
8100
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8101
      xp = tmp;
8102
    } else {
8103
      xp = (short *) *xpp;
8104
    }
8105
   /* copy the next block */
8106
#pragma cdir loopcnt=LOOPCNT
8107
#pragma cdir shortloop
8108
    for (i=0; i<ni; i++) {
8109
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
8110
     /* test for range errors (not always needed but do it anyway) */
8111
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8112
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8113
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
8114
    }
8115
   /* update xpp and tp */
8116
    if (realign) xp = (short *) *xpp;
8117
    xp += ni;
8118
    tp += ni;
8119
    *xpp = (void*)xp;
8120
  }
8121
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8122
8123
#else   /* not SX */
8124
0
  const char *xp = (const char *) *xpp;
8125
0
  int status = NC_NOERR;
8126
8127
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8128
0
  {
8129
0
    const int lstatus = ncx_get_short_float(xp, tp);
8130
0
    if (status == NC_NOERR) /* report the first encountered error */
8131
0
      status = lstatus;
8132
0
  }
8133
8134
0
  *xpp = (const void *)xp;
8135
0
  return status;
8136
0
#endif
8137
0
}
8138
8139
int
8140
ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
8141
0
{
8142
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8143
8144
 /* basic algorithm is:
8145
  *   - ensure sane alignment of input data
8146
  *   - copy (conversion happens automatically) input data
8147
  *     to output
8148
  *   - update xpp to point at next unconverted input, and tp to point
8149
  *     at next location for converted output
8150
  */
8151
  long i, j, ni;
8152
  short tmp[LOOPCNT];        /* in case input is misaligned */
8153
  short *xp;
8154
  int nrange = 0;         /* number of range errors */
8155
  int realign = 0;        /* "do we need to fix input data alignment?" */
8156
  long cxp = (long) *((char**)xpp);
8157
8158
  realign = (cxp & 7) % SIZEOF_SHORT;
8159
  /* sjl: manually stripmine so we can limit amount of
8160
   * vector work space reserved to LOOPCNT elements. Also
8161
   * makes vectorisation easy */
8162
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8163
    ni=Min(nelems-j,LOOPCNT);
8164
    if (realign) {
8165
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8166
      xp = tmp;
8167
    } else {
8168
      xp = (short *) *xpp;
8169
    }
8170
   /* copy the next block */
8171
#pragma cdir loopcnt=LOOPCNT
8172
#pragma cdir shortloop
8173
    for (i=0; i<ni; i++) {
8174
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
8175
     /* test for range errors (not always needed but do it anyway) */
8176
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8177
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8178
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
8179
    }
8180
   /* update xpp and tp */
8181
    if (realign) xp = (short *) *xpp;
8182
    xp += ni;
8183
    tp += ni;
8184
    *xpp = (void*)xp;
8185
  }
8186
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8187
8188
#else   /* not SX */
8189
0
  const char *xp = (const char *) *xpp;
8190
0
  int status = NC_NOERR;
8191
8192
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8193
0
  {
8194
0
    const int lstatus = ncx_get_short_double(xp, tp);
8195
0
    if (status == NC_NOERR) /* report the first encountered error */
8196
0
      status = lstatus;
8197
0
  }
8198
8199
0
  *xpp = (const void *)xp;
8200
0
  return status;
8201
0
#endif
8202
0
}
8203
8204
int
8205
ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8206
0
{
8207
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8208
8209
 /* basic algorithm is:
8210
  *   - ensure sane alignment of input data
8211
  *   - copy (conversion happens automatically) input data
8212
  *     to output
8213
  *   - update xpp to point at next unconverted input, and tp to point
8214
  *     at next location for converted output
8215
  */
8216
  long i, j, ni;
8217
  short tmp[LOOPCNT];        /* in case input is misaligned */
8218
  short *xp;
8219
  int nrange = 0;         /* number of range errors */
8220
  int realign = 0;        /* "do we need to fix input data alignment?" */
8221
  long cxp = (long) *((char**)xpp);
8222
8223
  realign = (cxp & 7) % SIZEOF_SHORT;
8224
  /* sjl: manually stripmine so we can limit amount of
8225
   * vector work space reserved to LOOPCNT elements. Also
8226
   * makes vectorisation easy */
8227
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8228
    ni=Min(nelems-j,LOOPCNT);
8229
    if (realign) {
8230
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8231
      xp = tmp;
8232
    } else {
8233
      xp = (short *) *xpp;
8234
    }
8235
   /* copy the next block */
8236
#pragma cdir loopcnt=LOOPCNT
8237
#pragma cdir shortloop
8238
    for (i=0; i<ni; i++) {
8239
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
8240
     /* test for range errors (not always needed but do it anyway) */
8241
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8242
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8243
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
8244
    }
8245
   /* update xpp and tp */
8246
    if (realign) xp = (short *) *xpp;
8247
    xp += ni;
8248
    tp += ni;
8249
    *xpp = (void*)xp;
8250
  }
8251
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8252
8253
#else   /* not SX */
8254
0
  const char *xp = (const char *) *xpp;
8255
0
  int status = NC_NOERR;
8256
8257
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8258
0
  {
8259
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8260
0
    if (status == NC_NOERR) /* report the first encountered error */
8261
0
      status = lstatus;
8262
0
  }
8263
8264
0
  *xpp = (const void *)xp;
8265
0
  return status;
8266
0
#endif
8267
0
}
8268
8269
int
8270
ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8271
0
{
8272
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8273
8274
 /* basic algorithm is:
8275
  *   - ensure sane alignment of input data
8276
  *   - copy (conversion happens automatically) input data
8277
  *     to output
8278
  *   - update xpp to point at next unconverted input, and tp to point
8279
  *     at next location for converted output
8280
  */
8281
  long i, j, ni;
8282
  short tmp[LOOPCNT];        /* in case input is misaligned */
8283
  short *xp;
8284
  int nrange = 0;         /* number of range errors */
8285
  int realign = 0;        /* "do we need to fix input data alignment?" */
8286
  long cxp = (long) *((char**)xpp);
8287
8288
  realign = (cxp & 7) % SIZEOF_SHORT;
8289
  /* sjl: manually stripmine so we can limit amount of
8290
   * vector work space reserved to LOOPCNT elements. Also
8291
   * makes vectorisation easy */
8292
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8293
    ni=Min(nelems-j,LOOPCNT);
8294
    if (realign) {
8295
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8296
      xp = tmp;
8297
    } else {
8298
      xp = (short *) *xpp;
8299
    }
8300
   /* copy the next block */
8301
#pragma cdir loopcnt=LOOPCNT
8302
#pragma cdir shortloop
8303
    for (i=0; i<ni; i++) {
8304
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
8305
     /* test for range errors (not always needed but do it anyway) */
8306
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8307
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8308
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
8309
    }
8310
   /* update xpp and tp */
8311
    if (realign) xp = (short *) *xpp;
8312
    xp += ni;
8313
    tp += ni;
8314
    *xpp = (void*)xp;
8315
  }
8316
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8317
8318
#else   /* not SX */
8319
0
  const char *xp = (const char *) *xpp;
8320
0
  int status = NC_NOERR;
8321
8322
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8323
0
  {
8324
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8325
0
    if (status == NC_NOERR) /* report the first encountered error */
8326
0
      status = lstatus;
8327
0
  }
8328
8329
0
  *xpp = (const void *)xp;
8330
0
  return status;
8331
0
#endif
8332
0
}
8333
8334
int
8335
ncx_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8336
0
{
8337
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8338
8339
 /* basic algorithm is:
8340
  *   - ensure sane alignment of input data
8341
  *   - copy (conversion happens automatically) input data
8342
  *     to output
8343
  *   - update xpp to point at next unconverted input, and tp to point
8344
  *     at next location for converted output
8345
  */
8346
  long i, j, ni;
8347
  short tmp[LOOPCNT];        /* in case input is misaligned */
8348
  short *xp;
8349
  int nrange = 0;         /* number of range errors */
8350
  int realign = 0;        /* "do we need to fix input data alignment?" */
8351
  long cxp = (long) *((char**)xpp);
8352
8353
  realign = (cxp & 7) % SIZEOF_SHORT;
8354
  /* sjl: manually stripmine so we can limit amount of
8355
   * vector work space reserved to LOOPCNT elements. Also
8356
   * makes vectorisation easy */
8357
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8358
    ni=Min(nelems-j,LOOPCNT);
8359
    if (realign) {
8360
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8361
      xp = tmp;
8362
    } else {
8363
      xp = (short *) *xpp;
8364
    }
8365
   /* copy the next block */
8366
#pragma cdir loopcnt=LOOPCNT
8367
#pragma cdir shortloop
8368
    for (i=0; i<ni; i++) {
8369
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
8370
     /* test for range errors (not always needed but do it anyway) */
8371
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8372
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8373
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
8374
    }
8375
   /* update xpp and tp */
8376
    if (realign) xp = (short *) *xpp;
8377
    xp += ni;
8378
    tp += ni;
8379
    *xpp = (void*)xp;
8380
  }
8381
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8382
8383
#else   /* not SX */
8384
0
  const char *xp = (const char *) *xpp;
8385
0
  int status = NC_NOERR;
8386
8387
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8388
0
  {
8389
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8390
0
    if (status == NC_NOERR) /* report the first encountered error */
8391
0
      status = lstatus;
8392
0
  }
8393
8394
0
  *xpp = (const void *)xp;
8395
0
  return status;
8396
0
#endif
8397
0
}
8398
8399
int
8400
ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8401
0
{
8402
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8403
8404
 /* basic algorithm is:
8405
  *   - ensure sane alignment of input data
8406
  *   - copy (conversion happens automatically) input data
8407
  *     to output
8408
  *   - update xpp to point at next unconverted input, and tp to point
8409
  *     at next location for converted output
8410
  */
8411
  long i, j, ni;
8412
  short tmp[LOOPCNT];        /* in case input is misaligned */
8413
  short *xp;
8414
  int nrange = 0;         /* number of range errors */
8415
  int realign = 0;        /* "do we need to fix input data alignment?" */
8416
  long cxp = (long) *((char**)xpp);
8417
8418
  realign = (cxp & 7) % SIZEOF_SHORT;
8419
  /* sjl: manually stripmine so we can limit amount of
8420
   * vector work space reserved to LOOPCNT elements. Also
8421
   * makes vectorisation easy */
8422
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8423
    ni=Min(nelems-j,LOOPCNT);
8424
    if (realign) {
8425
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8426
      xp = tmp;
8427
    } else {
8428
      xp = (short *) *xpp;
8429
    }
8430
   /* copy the next block */
8431
#pragma cdir loopcnt=LOOPCNT
8432
#pragma cdir shortloop
8433
    for (i=0; i<ni; i++) {
8434
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
8435
     /* test for range errors (not always needed but do it anyway) */
8436
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8437
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8438
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
8439
    }
8440
   /* update xpp and tp */
8441
    if (realign) xp = (short *) *xpp;
8442
    xp += ni;
8443
    tp += ni;
8444
    *xpp = (void*)xp;
8445
  }
8446
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8447
8448
#else   /* not SX */
8449
0
  const char *xp = (const char *) *xpp;
8450
0
  int status = NC_NOERR;
8451
8452
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8453
0
  {
8454
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8455
0
    if (status == NC_NOERR) /* report the first encountered error */
8456
0
      status = lstatus;
8457
0
  }
8458
8459
0
  *xpp = (const void *)xp;
8460
0
  return status;
8461
0
#endif
8462
0
}
8463
8464
int
8465
ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8466
0
{
8467
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8468
8469
 /* basic algorithm is:
8470
  *   - ensure sane alignment of input data
8471
  *   - copy (conversion happens automatically) input data
8472
  *     to output
8473
  *   - update xpp to point at next unconverted input, and tp to point
8474
  *     at next location for converted output
8475
  */
8476
  long i, j, ni;
8477
  short tmp[LOOPCNT];        /* in case input is misaligned */
8478
  short *xp;
8479
  int nrange = 0;         /* number of range errors */
8480
  int realign = 0;        /* "do we need to fix input data alignment?" */
8481
  long cxp = (long) *((char**)xpp);
8482
8483
  realign = (cxp & 7) % SIZEOF_SHORT;
8484
  /* sjl: manually stripmine so we can limit amount of
8485
   * vector work space reserved to LOOPCNT elements. Also
8486
   * makes vectorisation easy */
8487
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8488
    ni=Min(nelems-j,LOOPCNT);
8489
    if (realign) {
8490
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8491
      xp = tmp;
8492
    } else {
8493
      xp = (short *) *xpp;
8494
    }
8495
   /* copy the next block */
8496
#pragma cdir loopcnt=LOOPCNT
8497
#pragma cdir shortloop
8498
    for (i=0; i<ni; i++) {
8499
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
8500
     /* test for range errors (not always needed but do it anyway) */
8501
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8502
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8503
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
8504
    }
8505
   /* update xpp and tp */
8506
    if (realign) xp = (short *) *xpp;
8507
    xp += ni;
8508
    tp += ni;
8509
    *xpp = (void*)xp;
8510
  }
8511
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8512
8513
#else   /* not SX */
8514
0
  const char *xp = (const char *) *xpp;
8515
0
  int status = NC_NOERR;
8516
8517
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8518
0
  {
8519
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8520
0
    if (status == NC_NOERR) /* report the first encountered error */
8521
0
      status = lstatus;
8522
0
  }
8523
8524
0
  *xpp = (const void *)xp;
8525
0
  return status;
8526
0
#endif
8527
0
}
8528
8529
8530
int
8531
ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
8532
0
{
8533
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8534
8535
0
  const char *xp = (const char *) *xpp;
8536
0
  int status = NC_NOERR;
8537
8538
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8539
0
  {
8540
0
    const int lstatus = ncx_get_short_schar(xp, tp);
8541
0
    if (status == NC_NOERR) /* report the first encountered error */
8542
0
      status = lstatus;
8543
0
  }
8544
8545
0
  if (rndup != 0)
8546
0
    xp += X_SIZEOF_SHORT;
8547
8548
0
  *xpp = (void *)xp;
8549
0
  return status;
8550
0
}
8551
8552
int
8553
ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8554
0
{
8555
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8556
8557
0
  const char *xp = (const char *) *xpp;
8558
0
  int status = NC_NOERR;
8559
8560
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8561
0
  {
8562
0
    const int lstatus = ncx_get_short_uchar(xp, tp);
8563
0
    if (status == NC_NOERR) /* report the first encountered error */
8564
0
      status = lstatus;
8565
0
  }
8566
8567
0
  if (rndup != 0)
8568
0
    xp += X_SIZEOF_SHORT;
8569
8570
0
  *xpp = (void *)xp;
8571
0
  return status;
8572
0
}
8573
8574
int
8575
ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
8576
0
{
8577
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8578
8579
0
  const char *xp = (const char *) *xpp;
8580
0
  int status = NC_NOERR;
8581
8582
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8583
0
  {
8584
0
    const int lstatus = ncx_get_short_short(xp, tp);
8585
0
    if (status == NC_NOERR) /* report the first encountered error */
8586
0
      status = lstatus;
8587
0
  }
8588
8589
0
  if (rndup != 0)
8590
0
    xp += X_SIZEOF_SHORT;
8591
8592
0
  *xpp = (void *)xp;
8593
0
  return status;
8594
0
}
8595
8596
int
8597
ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
8598
0
{
8599
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8600
8601
0
  const char *xp = (const char *) *xpp;
8602
0
  int status = NC_NOERR;
8603
8604
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8605
0
  {
8606
0
    const int lstatus = ncx_get_short_int(xp, tp);
8607
0
    if (status == NC_NOERR) /* report the first encountered error */
8608
0
      status = lstatus;
8609
0
  }
8610
8611
0
  if (rndup != 0)
8612
0
    xp += X_SIZEOF_SHORT;
8613
8614
0
  *xpp = (void *)xp;
8615
0
  return status;
8616
0
}
8617
8618
int
8619
ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
8620
0
{
8621
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8622
8623
0
  const char *xp = (const char *) *xpp;
8624
0
  int status = NC_NOERR;
8625
8626
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8627
0
  {
8628
0
    const int lstatus = ncx_get_short_long(xp, tp);
8629
0
    if (status == NC_NOERR) /* report the first encountered error */
8630
0
      status = lstatus;
8631
0
  }
8632
8633
0
  if (rndup != 0)
8634
0
    xp += X_SIZEOF_SHORT;
8635
8636
0
  *xpp = (void *)xp;
8637
0
  return status;
8638
0
}
8639
8640
int
8641
ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
8642
0
{
8643
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8644
8645
0
  const char *xp = (const char *) *xpp;
8646
0
  int status = NC_NOERR;
8647
8648
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8649
0
  {
8650
0
    const int lstatus = ncx_get_short_float(xp, tp);
8651
0
    if (status == NC_NOERR) /* report the first encountered error */
8652
0
      status = lstatus;
8653
0
  }
8654
8655
0
  if (rndup != 0)
8656
0
    xp += X_SIZEOF_SHORT;
8657
8658
0
  *xpp = (void *)xp;
8659
0
  return status;
8660
0
}
8661
8662
int
8663
ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
8664
0
{
8665
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8666
8667
0
  const char *xp = (const char *) *xpp;
8668
0
  int status = NC_NOERR;
8669
8670
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8671
0
  {
8672
0
    const int lstatus = ncx_get_short_double(xp, tp);
8673
0
    if (status == NC_NOERR) /* report the first encountered error */
8674
0
      status = lstatus;
8675
0
  }
8676
8677
0
  if (rndup != 0)
8678
0
    xp += X_SIZEOF_SHORT;
8679
8680
0
  *xpp = (void *)xp;
8681
0
  return status;
8682
0
}
8683
8684
int
8685
ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8686
0
{
8687
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8688
8689
0
  const char *xp = (const char *) *xpp;
8690
0
  int status = NC_NOERR;
8691
8692
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8693
0
  {
8694
0
    const int lstatus = ncx_get_short_uint(xp, tp);
8695
0
    if (status == NC_NOERR) /* report the first encountered error */
8696
0
      status = lstatus;
8697
0
  }
8698
8699
0
  if (rndup != 0)
8700
0
    xp += X_SIZEOF_SHORT;
8701
8702
0
  *xpp = (void *)xp;
8703
0
  return status;
8704
0
}
8705
8706
int
8707
ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8708
0
{
8709
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8710
8711
0
  const char *xp = (const char *) *xpp;
8712
0
  int status = NC_NOERR;
8713
8714
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8715
0
  {
8716
0
    const int lstatus = ncx_get_short_longlong(xp, tp);
8717
0
    if (status == NC_NOERR) /* report the first encountered error */
8718
0
      status = lstatus;
8719
0
  }
8720
8721
0
  if (rndup != 0)
8722
0
    xp += X_SIZEOF_SHORT;
8723
8724
0
  *xpp = (void *)xp;
8725
0
  return status;
8726
0
}
8727
8728
int
8729
ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8730
0
{
8731
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8732
8733
0
  const char *xp = (const char *) *xpp;
8734
0
  int status = NC_NOERR;
8735
8736
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8737
0
  {
8738
0
    const int lstatus = ncx_get_short_ulonglong(xp, tp);
8739
0
    if (status == NC_NOERR) /* report the first encountered error */
8740
0
      status = lstatus;
8741
0
  }
8742
8743
0
  if (rndup != 0)
8744
0
    xp += X_SIZEOF_SHORT;
8745
8746
0
  *xpp = (void *)xp;
8747
0
  return status;
8748
0
}
8749
8750
int
8751
ncx_pad_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8752
0
{
8753
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
8754
8755
0
  const char *xp = (const char *) *xpp;
8756
0
  int status = NC_NOERR;
8757
8758
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8759
0
  {
8760
0
    const int lstatus = ncx_get_short_ushort(xp, tp);
8761
0
    if (status == NC_NOERR) /* report the first encountered error */
8762
0
      status = lstatus;
8763
0
  }
8764
8765
0
  if (rndup != 0)
8766
0
    xp += X_SIZEOF_SHORT;
8767
8768
0
  *xpp = (void *)xp;
8769
0
  return status;
8770
0
}
8771
8772
8773
#if X_SIZEOF_SHORT == SIZEOF_SHORT
8774
/* optimized version */
8775
int
8776
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8777
0
{
8778
#ifdef WORDS_BIGENDIAN
8779
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
8780
# else
8781
0
  swapn2b(*xpp, tp, nelems);
8782
0
# endif
8783
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
8784
0
  return NC_NOERR;
8785
0
}
8786
#else
8787
int
8788
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8789
{
8790
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8791
8792
 /* basic algorithm is:
8793
  *   - ensure sane alignment of output data
8794
  *   - copy (conversion happens automatically) input data
8795
  *     to output
8796
  *   - update tp to point at next unconverted input, and xpp to point
8797
  *     at next location for converted output
8798
  */
8799
  long i, j, ni;
8800
  short tmp[LOOPCNT];        /* in case input is misaligned */
8801
  short *xp;
8802
  int nrange = 0;         /* number of range errors */
8803
  int realign = 0;        /* "do we need to fix input data alignment?" */
8804
  long cxp = (long) *((char**)xpp);
8805
8806
  realign = (cxp & 7) % SIZEOF_SHORT;
8807
  /* sjl: manually stripmine so we can limit amount of
8808
   * vector work space reserved to LOOPCNT elements. Also
8809
   * makes vectorisation easy */
8810
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8811
    ni=Min(nelems-j,LOOPCNT);
8812
    if (realign) {
8813
      xp = tmp;
8814
    } else {
8815
      xp = (short *) *xpp;
8816
    }
8817
   /* copy the next block */
8818
#pragma cdir loopcnt=LOOPCNT
8819
#pragma cdir shortloop
8820
    for (i=0; i<ni; i++) {
8821
      /* the normal case: */
8822
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8823
     /* test for range errors (not always needed but do it anyway) */
8824
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8825
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8826
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8827
    }
8828
   /* copy workspace back if necessary */
8829
    if (realign) {
8830
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8831
      xp = (short *) *xpp;
8832
    }
8833
   /* update xpp and tp */
8834
    xp += ni;
8835
    tp += ni;
8836
    *xpp = (void*)xp;
8837
  }
8838
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8839
8840
#else   /* not SX */
8841
8842
  char *xp = (char *) *xpp;
8843
  int status = NC_NOERR;
8844
8845
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8846
  {
8847
    int lstatus = ncx_put_short_short(xp, tp, fillp);
8848
    if (status == NC_NOERR) /* report the first encountered error */
8849
      status = lstatus;
8850
  }
8851
8852
  *xpp = (void *)xp;
8853
  return status;
8854
#endif
8855
}
8856
8857
#endif
8858
int
8859
ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
8860
0
{
8861
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8862
8863
 /* basic algorithm is:
8864
  *   - ensure sane alignment of output data
8865
  *   - copy (conversion happens automatically) input data
8866
  *     to output
8867
  *   - update tp to point at next unconverted input, and xpp to point
8868
  *     at next location for converted output
8869
  */
8870
  long i, j, ni;
8871
  short tmp[LOOPCNT];        /* in case input is misaligned */
8872
  short *xp;
8873
  int nrange = 0;         /* number of range errors */
8874
  int realign = 0;        /* "do we need to fix input data alignment?" */
8875
  long cxp = (long) *((char**)xpp);
8876
8877
  realign = (cxp & 7) % SIZEOF_SHORT;
8878
  /* sjl: manually stripmine so we can limit amount of
8879
   * vector work space reserved to LOOPCNT elements. Also
8880
   * makes vectorisation easy */
8881
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8882
    ni=Min(nelems-j,LOOPCNT);
8883
    if (realign) {
8884
      xp = tmp;
8885
    } else {
8886
      xp = (short *) *xpp;
8887
    }
8888
   /* copy the next block */
8889
#pragma cdir loopcnt=LOOPCNT
8890
#pragma cdir shortloop
8891
    for (i=0; i<ni; i++) {
8892
      /* the normal case: */
8893
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8894
     /* test for range errors (not always needed but do it anyway) */
8895
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8896
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8897
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8898
    }
8899
   /* copy workspace back if necessary */
8900
    if (realign) {
8901
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8902
      xp = (short *) *xpp;
8903
    }
8904
   /* update xpp and tp */
8905
    xp += ni;
8906
    tp += ni;
8907
    *xpp = (void*)xp;
8908
  }
8909
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8910
8911
#else   /* not SX */
8912
8913
0
  char *xp = (char *) *xpp;
8914
0
  int status = NC_NOERR;
8915
8916
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8917
0
  {
8918
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
8919
0
    if (status == NC_NOERR) /* report the first encountered error */
8920
0
      status = lstatus;
8921
0
  }
8922
8923
0
  *xpp = (void *)xp;
8924
0
  return status;
8925
0
#endif
8926
0
}
8927
8928
int
8929
ncx_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
8930
0
{
8931
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8932
8933
 /* basic algorithm is:
8934
  *   - ensure sane alignment of output data
8935
  *   - copy (conversion happens automatically) input data
8936
  *     to output
8937
  *   - update tp to point at next unconverted input, and xpp to point
8938
  *     at next location for converted output
8939
  */
8940
  long i, j, ni;
8941
  short tmp[LOOPCNT];        /* in case input is misaligned */
8942
  short *xp;
8943
  int nrange = 0;         /* number of range errors */
8944
  int realign = 0;        /* "do we need to fix input data alignment?" */
8945
  long cxp = (long) *((char**)xpp);
8946
8947
  realign = (cxp & 7) % SIZEOF_SHORT;
8948
  /* sjl: manually stripmine so we can limit amount of
8949
   * vector work space reserved to LOOPCNT elements. Also
8950
   * makes vectorisation easy */
8951
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8952
    ni=Min(nelems-j,LOOPCNT);
8953
    if (realign) {
8954
      xp = tmp;
8955
    } else {
8956
      xp = (short *) *xpp;
8957
    }
8958
   /* copy the next block */
8959
#pragma cdir loopcnt=LOOPCNT
8960
#pragma cdir shortloop
8961
    for (i=0; i<ni; i++) {
8962
      /* the normal case: */
8963
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8964
     /* test for range errors (not always needed but do it anyway) */
8965
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8966
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8967
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8968
    }
8969
   /* copy workspace back if necessary */
8970
    if (realign) {
8971
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8972
      xp = (short *) *xpp;
8973
    }
8974
   /* update xpp and tp */
8975
    xp += ni;
8976
    tp += ni;
8977
    *xpp = (void*)xp;
8978
  }
8979
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
8980
8981
#else   /* not SX */
8982
8983
0
  char *xp = (char *) *xpp;
8984
0
  int status = NC_NOERR;
8985
8986
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8987
0
  {
8988
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
8989
0
    if (status == NC_NOERR) /* report the first encountered error */
8990
0
      status = lstatus;
8991
0
  }
8992
8993
0
  *xpp = (void *)xp;
8994
0
  return status;
8995
0
#endif
8996
0
}
8997
8998
int
8999
ncx_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
9000
0
{
9001
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9002
9003
 /* basic algorithm is:
9004
  *   - ensure sane alignment of output data
9005
  *   - copy (conversion happens automatically) input data
9006
  *     to output
9007
  *   - update tp to point at next unconverted input, and xpp to point
9008
  *     at next location for converted output
9009
  */
9010
  long i, j, ni;
9011
  short tmp[LOOPCNT];        /* in case input is misaligned */
9012
  short *xp;
9013
  int nrange = 0;         /* number of range errors */
9014
  int realign = 0;        /* "do we need to fix input data alignment?" */
9015
  long cxp = (long) *((char**)xpp);
9016
9017
  realign = (cxp & 7) % SIZEOF_SHORT;
9018
  /* sjl: manually stripmine so we can limit amount of
9019
   * vector work space reserved to LOOPCNT elements. Also
9020
   * makes vectorisation easy */
9021
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9022
    ni=Min(nelems-j,LOOPCNT);
9023
    if (realign) {
9024
      xp = tmp;
9025
    } else {
9026
      xp = (short *) *xpp;
9027
    }
9028
   /* copy the next block */
9029
#pragma cdir loopcnt=LOOPCNT
9030
#pragma cdir shortloop
9031
    for (i=0; i<ni; i++) {
9032
      /* the normal case: */
9033
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9034
     /* test for range errors (not always needed but do it anyway) */
9035
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9036
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9037
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9038
    }
9039
   /* copy workspace back if necessary */
9040
    if (realign) {
9041
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9042
      xp = (short *) *xpp;
9043
    }
9044
   /* update xpp and tp */
9045
    xp += ni;
9046
    tp += ni;
9047
    *xpp = (void*)xp;
9048
  }
9049
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9050
9051
#else   /* not SX */
9052
9053
0
  char *xp = (char *) *xpp;
9054
0
  int status = NC_NOERR;
9055
9056
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9057
0
  {
9058
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
9059
0
    if (status == NC_NOERR) /* report the first encountered error */
9060
0
      status = lstatus;
9061
0
  }
9062
9063
0
  *xpp = (void *)xp;
9064
0
  return status;
9065
0
#endif
9066
0
}
9067
9068
int
9069
ncx_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9070
0
{
9071
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9072
9073
 /* basic algorithm is:
9074
  *   - ensure sane alignment of output data
9075
  *   - copy (conversion happens automatically) input data
9076
  *     to output
9077
  *   - update tp to point at next unconverted input, and xpp to point
9078
  *     at next location for converted output
9079
  */
9080
  long i, j, ni;
9081
  short tmp[LOOPCNT];        /* in case input is misaligned */
9082
  short *xp;
9083
  int nrange = 0;         /* number of range errors */
9084
  int realign = 0;        /* "do we need to fix input data alignment?" */
9085
  long cxp = (long) *((char**)xpp);
9086
9087
  realign = (cxp & 7) % SIZEOF_SHORT;
9088
  /* sjl: manually stripmine so we can limit amount of
9089
   * vector work space reserved to LOOPCNT elements. Also
9090
   * makes vectorisation easy */
9091
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9092
    ni=Min(nelems-j,LOOPCNT);
9093
    if (realign) {
9094
      xp = tmp;
9095
    } else {
9096
      xp = (short *) *xpp;
9097
    }
9098
   /* copy the next block */
9099
#pragma cdir loopcnt=LOOPCNT
9100
#pragma cdir shortloop
9101
    for (i=0; i<ni; i++) {
9102
      /* the normal case: */
9103
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9104
     /* test for range errors (not always needed but do it anyway) */
9105
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9106
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9107
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9108
    }
9109
   /* copy workspace back if necessary */
9110
    if (realign) {
9111
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9112
      xp = (short *) *xpp;
9113
    }
9114
   /* update xpp and tp */
9115
    xp += ni;
9116
    tp += ni;
9117
    *xpp = (void*)xp;
9118
  }
9119
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9120
9121
#else   /* not SX */
9122
9123
0
  char *xp = (char *) *xpp;
9124
0
  int status = NC_NOERR;
9125
9126
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9127
0
  {
9128
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
9129
0
    if (status == NC_NOERR) /* report the first encountered error */
9130
0
      status = lstatus;
9131
0
  }
9132
9133
0
  *xpp = (void *)xp;
9134
0
  return status;
9135
0
#endif
9136
0
}
9137
9138
int
9139
ncx_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9140
0
{
9141
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9142
9143
 /* basic algorithm is:
9144
  *   - ensure sane alignment of output data
9145
  *   - copy (conversion happens automatically) input data
9146
  *     to output
9147
  *   - update tp to point at next unconverted input, and xpp to point
9148
  *     at next location for converted output
9149
  */
9150
  long i, j, ni;
9151
  short tmp[LOOPCNT];        /* in case input is misaligned */
9152
  short *xp;
9153
  int nrange = 0;         /* number of range errors */
9154
  int realign = 0;        /* "do we need to fix input data alignment?" */
9155
  long cxp = (long) *((char**)xpp);
9156
9157
  realign = (cxp & 7) % SIZEOF_SHORT;
9158
  /* sjl: manually stripmine so we can limit amount of
9159
   * vector work space reserved to LOOPCNT elements. Also
9160
   * makes vectorisation easy */
9161
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9162
    ni=Min(nelems-j,LOOPCNT);
9163
    if (realign) {
9164
      xp = tmp;
9165
    } else {
9166
      xp = (short *) *xpp;
9167
    }
9168
   /* copy the next block */
9169
#pragma cdir loopcnt=LOOPCNT
9170
#pragma cdir shortloop
9171
    for (i=0; i<ni; i++) {
9172
      /* the normal case: */
9173
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9174
     /* test for range errors (not always needed but do it anyway) */
9175
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9176
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9177
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9178
    }
9179
   /* copy workspace back if necessary */
9180
    if (realign) {
9181
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9182
      xp = (short *) *xpp;
9183
    }
9184
   /* update xpp and tp */
9185
    xp += ni;
9186
    tp += ni;
9187
    *xpp = (void*)xp;
9188
  }
9189
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9190
9191
#else   /* not SX */
9192
9193
0
  char *xp = (char *) *xpp;
9194
0
  int status = NC_NOERR;
9195
9196
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9197
0
  {
9198
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
9199
0
    if (status == NC_NOERR) /* report the first encountered error */
9200
0
      status = lstatus;
9201
0
  }
9202
9203
0
  *xpp = (void *)xp;
9204
0
  return status;
9205
0
#endif
9206
0
}
9207
9208
int
9209
ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9210
0
{
9211
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9212
9213
 /* basic algorithm is:
9214
  *   - ensure sane alignment of output data
9215
  *   - copy (conversion happens automatically) input data
9216
  *     to output
9217
  *   - update tp to point at next unconverted input, and xpp to point
9218
  *     at next location for converted output
9219
  */
9220
  long i, j, ni;
9221
  short tmp[LOOPCNT];        /* in case input is misaligned */
9222
  short *xp;
9223
  int nrange = 0;         /* number of range errors */
9224
  int realign = 0;        /* "do we need to fix input data alignment?" */
9225
  long cxp = (long) *((char**)xpp);
9226
9227
  realign = (cxp & 7) % SIZEOF_SHORT;
9228
  /* sjl: manually stripmine so we can limit amount of
9229
   * vector work space reserved to LOOPCNT elements. Also
9230
   * makes vectorisation easy */
9231
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9232
    ni=Min(nelems-j,LOOPCNT);
9233
    if (realign) {
9234
      xp = tmp;
9235
    } else {
9236
      xp = (short *) *xpp;
9237
    }
9238
   /* copy the next block */
9239
#pragma cdir loopcnt=LOOPCNT
9240
#pragma cdir shortloop
9241
    for (i=0; i<ni; i++) {
9242
      /* the normal case: */
9243
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9244
     /* test for range errors (not always needed but do it anyway) */
9245
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9246
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9247
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9248
    }
9249
   /* copy workspace back if necessary */
9250
    if (realign) {
9251
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9252
      xp = (short *) *xpp;
9253
    }
9254
   /* update xpp and tp */
9255
    xp += ni;
9256
    tp += ni;
9257
    *xpp = (void*)xp;
9258
  }
9259
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9260
9261
#else   /* not SX */
9262
9263
0
  char *xp = (char *) *xpp;
9264
0
  int status = NC_NOERR;
9265
9266
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9267
0
  {
9268
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9269
0
    if (status == NC_NOERR) /* report the first encountered error */
9270
0
      status = lstatus;
9271
0
  }
9272
9273
0
  *xpp = (void *)xp;
9274
0
  return status;
9275
0
#endif
9276
0
}
9277
9278
int
9279
ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9280
0
{
9281
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9282
9283
 /* basic algorithm is:
9284
  *   - ensure sane alignment of output data
9285
  *   - copy (conversion happens automatically) input data
9286
  *     to output
9287
  *   - update tp to point at next unconverted input, and xpp to point
9288
  *     at next location for converted output
9289
  */
9290
  long i, j, ni;
9291
  short tmp[LOOPCNT];        /* in case input is misaligned */
9292
  short *xp;
9293
  int nrange = 0;         /* number of range errors */
9294
  int realign = 0;        /* "do we need to fix input data alignment?" */
9295
  long cxp = (long) *((char**)xpp);
9296
9297
  realign = (cxp & 7) % SIZEOF_SHORT;
9298
  /* sjl: manually stripmine so we can limit amount of
9299
   * vector work space reserved to LOOPCNT elements. Also
9300
   * makes vectorisation easy */
9301
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9302
    ni=Min(nelems-j,LOOPCNT);
9303
    if (realign) {
9304
      xp = tmp;
9305
    } else {
9306
      xp = (short *) *xpp;
9307
    }
9308
   /* copy the next block */
9309
#pragma cdir loopcnt=LOOPCNT
9310
#pragma cdir shortloop
9311
    for (i=0; i<ni; i++) {
9312
      /* the normal case: */
9313
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9314
     /* test for range errors (not always needed but do it anyway) */
9315
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9316
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9317
      nrange += tp[i] > X_SHORT_MAX ;
9318
    }
9319
   /* copy workspace back if necessary */
9320
    if (realign) {
9321
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9322
      xp = (short *) *xpp;
9323
    }
9324
   /* update xpp and tp */
9325
    xp += ni;
9326
    tp += ni;
9327
    *xpp = (void*)xp;
9328
  }
9329
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9330
9331
#else   /* not SX */
9332
9333
0
  char *xp = (char *) *xpp;
9334
0
  int status = NC_NOERR;
9335
9336
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9337
0
  {
9338
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9339
0
    if (status == NC_NOERR) /* report the first encountered error */
9340
0
      status = lstatus;
9341
0
  }
9342
9343
0
  *xpp = (void *)xp;
9344
0
  return status;
9345
0
#endif
9346
0
}
9347
9348
int
9349
ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9350
0
{
9351
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9352
9353
 /* basic algorithm is:
9354
  *   - ensure sane alignment of output data
9355
  *   - copy (conversion happens automatically) input data
9356
  *     to output
9357
  *   - update tp to point at next unconverted input, and xpp to point
9358
  *     at next location for converted output
9359
  */
9360
  long i, j, ni;
9361
  short tmp[LOOPCNT];        /* in case input is misaligned */
9362
  short *xp;
9363
  int nrange = 0;         /* number of range errors */
9364
  int realign = 0;        /* "do we need to fix input data alignment?" */
9365
  long cxp = (long) *((char**)xpp);
9366
9367
  realign = (cxp & 7) % SIZEOF_SHORT;
9368
  /* sjl: manually stripmine so we can limit amount of
9369
   * vector work space reserved to LOOPCNT elements. Also
9370
   * makes vectorisation easy */
9371
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9372
    ni=Min(nelems-j,LOOPCNT);
9373
    if (realign) {
9374
      xp = tmp;
9375
    } else {
9376
      xp = (short *) *xpp;
9377
    }
9378
   /* copy the next block */
9379
#pragma cdir loopcnt=LOOPCNT
9380
#pragma cdir shortloop
9381
    for (i=0; i<ni; i++) {
9382
      /* the normal case: */
9383
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9384
     /* test for range errors (not always needed but do it anyway) */
9385
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9386
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9387
      nrange += tp[i] > X_SHORT_MAX ;
9388
    }
9389
   /* copy workspace back if necessary */
9390
    if (realign) {
9391
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9392
      xp = (short *) *xpp;
9393
    }
9394
   /* update xpp and tp */
9395
    xp += ni;
9396
    tp += ni;
9397
    *xpp = (void*)xp;
9398
  }
9399
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9400
9401
#else   /* not SX */
9402
9403
0
  char *xp = (char *) *xpp;
9404
0
  int status = NC_NOERR;
9405
9406
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9407
0
  {
9408
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9409
0
    if (status == NC_NOERR) /* report the first encountered error */
9410
0
      status = lstatus;
9411
0
  }
9412
9413
0
  *xpp = (void *)xp;
9414
0
  return status;
9415
0
#endif
9416
0
}
9417
9418
int
9419
ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9420
0
{
9421
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9422
9423
 /* basic algorithm is:
9424
  *   - ensure sane alignment of output data
9425
  *   - copy (conversion happens automatically) input data
9426
  *     to output
9427
  *   - update tp to point at next unconverted input, and xpp to point
9428
  *     at next location for converted output
9429
  */
9430
  long i, j, ni;
9431
  short tmp[LOOPCNT];        /* in case input is misaligned */
9432
  short *xp;
9433
  int nrange = 0;         /* number of range errors */
9434
  int realign = 0;        /* "do we need to fix input data alignment?" */
9435
  long cxp = (long) *((char**)xpp);
9436
9437
  realign = (cxp & 7) % SIZEOF_SHORT;
9438
  /* sjl: manually stripmine so we can limit amount of
9439
   * vector work space reserved to LOOPCNT elements. Also
9440
   * makes vectorisation easy */
9441
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9442
    ni=Min(nelems-j,LOOPCNT);
9443
    if (realign) {
9444
      xp = tmp;
9445
    } else {
9446
      xp = (short *) *xpp;
9447
    }
9448
   /* copy the next block */
9449
#pragma cdir loopcnt=LOOPCNT
9450
#pragma cdir shortloop
9451
    for (i=0; i<ni; i++) {
9452
      /* the normal case: */
9453
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9454
     /* test for range errors (not always needed but do it anyway) */
9455
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9456
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9457
      nrange += tp[i] > X_SHORT_MAX ;
9458
    }
9459
   /* copy workspace back if necessary */
9460
    if (realign) {
9461
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9462
      xp = (short *) *xpp;
9463
    }
9464
   /* update xpp and tp */
9465
    xp += ni;
9466
    tp += ni;
9467
    *xpp = (void*)xp;
9468
  }
9469
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9470
9471
#else   /* not SX */
9472
9473
0
  char *xp = (char *) *xpp;
9474
0
  int status = NC_NOERR;
9475
9476
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9477
0
  {
9478
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9479
0
    if (status == NC_NOERR) /* report the first encountered error */
9480
0
      status = lstatus;
9481
0
  }
9482
9483
0
  *xpp = (void *)xp;
9484
0
  return status;
9485
0
#endif
9486
0
}
9487
9488
int
9489
ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9490
0
{
9491
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9492
9493
 /* basic algorithm is:
9494
  *   - ensure sane alignment of output data
9495
  *   - copy (conversion happens automatically) input data
9496
  *     to output
9497
  *   - update tp to point at next unconverted input, and xpp to point
9498
  *     at next location for converted output
9499
  */
9500
  long i, j, ni;
9501
  short tmp[LOOPCNT];        /* in case input is misaligned */
9502
  short *xp;
9503
  int nrange = 0;         /* number of range errors */
9504
  int realign = 0;        /* "do we need to fix input data alignment?" */
9505
  long cxp = (long) *((char**)xpp);
9506
9507
  realign = (cxp & 7) % SIZEOF_SHORT;
9508
  /* sjl: manually stripmine so we can limit amount of
9509
   * vector work space reserved to LOOPCNT elements. Also
9510
   * makes vectorisation easy */
9511
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9512
    ni=Min(nelems-j,LOOPCNT);
9513
    if (realign) {
9514
      xp = tmp;
9515
    } else {
9516
      xp = (short *) *xpp;
9517
    }
9518
   /* copy the next block */
9519
#pragma cdir loopcnt=LOOPCNT
9520
#pragma cdir shortloop
9521
    for (i=0; i<ni; i++) {
9522
      /* the normal case: */
9523
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9524
     /* test for range errors (not always needed but do it anyway) */
9525
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9526
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9527
      nrange += tp[i] > X_SHORT_MAX ;
9528
    }
9529
   /* copy workspace back if necessary */
9530
    if (realign) {
9531
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9532
      xp = (short *) *xpp;
9533
    }
9534
   /* update xpp and tp */
9535
    xp += ni;
9536
    tp += ni;
9537
    *xpp = (void*)xp;
9538
  }
9539
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9540
9541
#else   /* not SX */
9542
9543
0
  char *xp = (char *) *xpp;
9544
0
  int status = NC_NOERR;
9545
9546
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9547
0
  {
9548
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9549
0
    if (status == NC_NOERR) /* report the first encountered error */
9550
0
      status = lstatus;
9551
0
  }
9552
9553
0
  *xpp = (void *)xp;
9554
0
  return status;
9555
0
#endif
9556
0
}
9557
9558
9559
int
9560
ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
9561
0
{
9562
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9563
9564
0
  char *xp = (char *) *xpp;
9565
0
  int status = NC_NOERR;
9566
9567
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9568
0
  {
9569
0
    int lstatus = ncx_put_short_schar(xp, tp, fillp);
9570
0
    if (status == NC_NOERR) /* report the first encountered error */
9571
0
      status = lstatus;
9572
0
  }
9573
9574
0
  if (rndup != 0)
9575
0
  {
9576
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9577
0
    xp += X_SIZEOF_SHORT;
9578
0
  }
9579
9580
0
  *xpp = (void *)xp;
9581
0
  return status;
9582
0
}
9583
9584
int
9585
ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9586
0
{
9587
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9588
9589
0
  char *xp = (char *) *xpp;
9590
0
  int status = NC_NOERR;
9591
9592
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9593
0
  {
9594
0
    int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9595
0
    if (status == NC_NOERR) /* report the first encountered error */
9596
0
      status = lstatus;
9597
0
  }
9598
9599
0
  if (rndup != 0)
9600
0
  {
9601
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9602
0
    xp += X_SIZEOF_SHORT;
9603
0
  }
9604
9605
0
  *xpp = (void *)xp;
9606
0
  return status;
9607
0
}
9608
9609
int
9610
ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
9611
0
{
9612
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9613
9614
0
  char *xp = (char *) *xpp;
9615
0
  int status = NC_NOERR;
9616
9617
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9618
0
  {
9619
0
    int lstatus = ncx_put_short_short(xp, tp, fillp);
9620
0
    if (status == NC_NOERR) /* report the first encountered error */
9621
0
      status = lstatus;
9622
0
  }
9623
9624
0
  if (rndup != 0)
9625
0
  {
9626
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9627
0
    xp += X_SIZEOF_SHORT;
9628
0
  }
9629
9630
0
  *xpp = (void *)xp;
9631
0
  return status;
9632
0
}
9633
9634
int
9635
ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
9636
0
{
9637
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9638
9639
0
  char *xp = (char *) *xpp;
9640
0
  int status = NC_NOERR;
9641
9642
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9643
0
  {
9644
0
    int lstatus = ncx_put_short_int(xp, tp, fillp);
9645
0
    if (status == NC_NOERR) /* report the first encountered error */
9646
0
      status = lstatus;
9647
0
  }
9648
9649
0
  if (rndup != 0)
9650
0
  {
9651
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9652
0
    xp += X_SIZEOF_SHORT;
9653
0
  }
9654
9655
0
  *xpp = (void *)xp;
9656
0
  return status;
9657
0
}
9658
9659
int
9660
ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
9661
0
{
9662
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9663
9664
0
  char *xp = (char *) *xpp;
9665
0
  int status = NC_NOERR;
9666
9667
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9668
0
  {
9669
0
    int lstatus = ncx_put_short_long(xp, tp, fillp);
9670
0
    if (status == NC_NOERR) /* report the first encountered error */
9671
0
      status = lstatus;
9672
0
  }
9673
9674
0
  if (rndup != 0)
9675
0
  {
9676
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9677
0
    xp += X_SIZEOF_SHORT;
9678
0
  }
9679
9680
0
  *xpp = (void *)xp;
9681
0
  return status;
9682
0
}
9683
9684
int
9685
ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9686
0
{
9687
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9688
9689
0
  char *xp = (char *) *xpp;
9690
0
  int status = NC_NOERR;
9691
9692
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9693
0
  {
9694
0
    int lstatus = ncx_put_short_float(xp, tp, fillp);
9695
0
    if (status == NC_NOERR) /* report the first encountered error */
9696
0
      status = lstatus;
9697
0
  }
9698
9699
0
  if (rndup != 0)
9700
0
  {
9701
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9702
0
    xp += X_SIZEOF_SHORT;
9703
0
  }
9704
9705
0
  *xpp = (void *)xp;
9706
0
  return status;
9707
0
}
9708
9709
int
9710
ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9711
0
{
9712
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9713
9714
0
  char *xp = (char *) *xpp;
9715
0
  int status = NC_NOERR;
9716
9717
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9718
0
  {
9719
0
    int lstatus = ncx_put_short_double(xp, tp, fillp);
9720
0
    if (status == NC_NOERR) /* report the first encountered error */
9721
0
      status = lstatus;
9722
0
  }
9723
9724
0
  if (rndup != 0)
9725
0
  {
9726
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9727
0
    xp += X_SIZEOF_SHORT;
9728
0
  }
9729
9730
0
  *xpp = (void *)xp;
9731
0
  return status;
9732
0
}
9733
9734
int
9735
ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9736
0
{
9737
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9738
9739
0
  char *xp = (char *) *xpp;
9740
0
  int status = NC_NOERR;
9741
9742
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9743
0
  {
9744
0
    int lstatus = ncx_put_short_uint(xp, tp, fillp);
9745
0
    if (status == NC_NOERR) /* report the first encountered error */
9746
0
      status = lstatus;
9747
0
  }
9748
9749
0
  if (rndup != 0)
9750
0
  {
9751
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9752
0
    xp += X_SIZEOF_SHORT;
9753
0
  }
9754
9755
0
  *xpp = (void *)xp;
9756
0
  return status;
9757
0
}
9758
9759
int
9760
ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9761
0
{
9762
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9763
9764
0
  char *xp = (char *) *xpp;
9765
0
  int status = NC_NOERR;
9766
9767
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9768
0
  {
9769
0
    int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9770
0
    if (status == NC_NOERR) /* report the first encountered error */
9771
0
      status = lstatus;
9772
0
  }
9773
9774
0
  if (rndup != 0)
9775
0
  {
9776
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9777
0
    xp += X_SIZEOF_SHORT;
9778
0
  }
9779
9780
0
  *xpp = (void *)xp;
9781
0
  return status;
9782
0
}
9783
9784
int
9785
ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9786
0
{
9787
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9788
9789
0
  char *xp = (char *) *xpp;
9790
0
  int status = NC_NOERR;
9791
9792
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9793
0
  {
9794
0
    int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9795
0
    if (status == NC_NOERR) /* report the first encountered error */
9796
0
      status = lstatus;
9797
0
  }
9798
9799
0
  if (rndup != 0)
9800
0
  {
9801
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9802
0
    xp += X_SIZEOF_SHORT;
9803
0
  }
9804
9805
0
  *xpp = (void *)xp;
9806
0
  return status;
9807
0
}
9808
9809
int
9810
ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9811
0
{
9812
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
9813
9814
0
  char *xp = (char *) *xpp;
9815
0
  int status = NC_NOERR;
9816
9817
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9818
0
  {
9819
0
    int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9820
0
    if (status == NC_NOERR) /* report the first encountered error */
9821
0
      status = lstatus;
9822
0
  }
9823
9824
0
  if (rndup != 0)
9825
0
  {
9826
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9827
0
    xp += X_SIZEOF_SHORT;
9828
0
  }
9829
9830
0
  *xpp = (void *)xp;
9831
0
  return status;
9832
0
}
9833
9834
9835
9836
/* ushort --------------------------------------------------------------------*/
9837
9838
#if X_SIZEOF_USHORT == SIZEOF_USHORT
9839
/* optimized version */
9840
int
9841
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
9842
0
{
9843
#ifdef WORDS_BIGENDIAN
9844
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
9845
# else
9846
0
  swapn2b(tp, *xpp, nelems);
9847
0
# endif
9848
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
9849
0
  return NC_NOERR;
9850
0
}
9851
#else
9852
int
9853
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
9854
{
9855
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9856
9857
 /* basic algorithm is:
9858
  *   - ensure sane alignment of input data
9859
  *   - copy (conversion happens automatically) input data
9860
  *     to output
9861
  *   - update xpp to point at next unconverted input, and tp to point
9862
  *     at next location for converted output
9863
  */
9864
  long i, j, ni;
9865
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9866
  ushort *xp;
9867
  int nrange = 0;         /* number of range errors */
9868
  int realign = 0;        /* "do we need to fix input data alignment?" */
9869
  long cxp = (long) *((char**)xpp);
9870
9871
  realign = (cxp & 7) % SIZEOF_USHORT;
9872
  /* sjl: manually stripmine so we can limit amount of
9873
   * vector work space reserved to LOOPCNT elements. Also
9874
   * makes vectorisation easy */
9875
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9876
    ni=Min(nelems-j,LOOPCNT);
9877
    if (realign) {
9878
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9879
      xp = tmp;
9880
    } else {
9881
      xp = (ushort *) *xpp;
9882
    }
9883
   /* copy the next block */
9884
#pragma cdir loopcnt=LOOPCNT
9885
#pragma cdir shortloop
9886
    for (i=0; i<ni; i++) {
9887
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
9888
     /* test for range errors (not always needed but do it anyway) */
9889
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9890
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9891
      nrange += xp[i] > USHORT_MAX ;
9892
    }
9893
   /* update xpp and tp */
9894
    if (realign) xp = (ushort *) *xpp;
9895
    xp += ni;
9896
    tp += ni;
9897
    *xpp = (void*)xp;
9898
  }
9899
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9900
9901
#else   /* not SX */
9902
  const char *xp = (const char *) *xpp;
9903
  int status = NC_NOERR;
9904
9905
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9906
  {
9907
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
9908
    if (status == NC_NOERR) /* report the first encountered error */
9909
      status = lstatus;
9910
  }
9911
9912
  *xpp = (const void *)xp;
9913
  return status;
9914
#endif
9915
}
9916
9917
#endif
9918
int
9919
ncx_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
9920
0
{
9921
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9922
9923
 /* basic algorithm is:
9924
  *   - ensure sane alignment of input data
9925
  *   - copy (conversion happens automatically) input data
9926
  *     to output
9927
  *   - update xpp to point at next unconverted input, and tp to point
9928
  *     at next location for converted output
9929
  */
9930
  long i, j, ni;
9931
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9932
  ushort *xp;
9933
  int nrange = 0;         /* number of range errors */
9934
  int realign = 0;        /* "do we need to fix input data alignment?" */
9935
  long cxp = (long) *((char**)xpp);
9936
9937
  realign = (cxp & 7) % SIZEOF_USHORT;
9938
  /* sjl: manually stripmine so we can limit amount of
9939
   * vector work space reserved to LOOPCNT elements. Also
9940
   * makes vectorisation easy */
9941
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9942
    ni=Min(nelems-j,LOOPCNT);
9943
    if (realign) {
9944
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9945
      xp = tmp;
9946
    } else {
9947
      xp = (ushort *) *xpp;
9948
    }
9949
   /* copy the next block */
9950
#pragma cdir loopcnt=LOOPCNT
9951
#pragma cdir shortloop
9952
    for (i=0; i<ni; i++) {
9953
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
9954
     /* test for range errors (not always needed but do it anyway) */
9955
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9956
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9957
      nrange += xp[i] > SCHAR_MAX ;
9958
    }
9959
   /* update xpp and tp */
9960
    if (realign) xp = (ushort *) *xpp;
9961
    xp += ni;
9962
    tp += ni;
9963
    *xpp = (void*)xp;
9964
  }
9965
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
9966
9967
#else   /* not SX */
9968
0
  const char *xp = (const char *) *xpp;
9969
0
  int status = NC_NOERR;
9970
9971
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9972
0
  {
9973
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
9974
0
    if (status == NC_NOERR) /* report the first encountered error */
9975
0
      status = lstatus;
9976
0
  }
9977
9978
0
  *xpp = (const void *)xp;
9979
0
  return status;
9980
0
#endif
9981
0
}
9982
9983
int
9984
ncx_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
9985
0
{
9986
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9987
9988
 /* basic algorithm is:
9989
  *   - ensure sane alignment of input data
9990
  *   - copy (conversion happens automatically) input data
9991
  *     to output
9992
  *   - update xpp to point at next unconverted input, and tp to point
9993
  *     at next location for converted output
9994
  */
9995
  long i, j, ni;
9996
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
9997
  ushort *xp;
9998
  int nrange = 0;         /* number of range errors */
9999
  int realign = 0;        /* "do we need to fix input data alignment?" */
10000
  long cxp = (long) *((char**)xpp);
10001
10002
  realign = (cxp & 7) % SIZEOF_USHORT;
10003
  /* sjl: manually stripmine so we can limit amount of
10004
   * vector work space reserved to LOOPCNT elements. Also
10005
   * makes vectorisation easy */
10006
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10007
    ni=Min(nelems-j,LOOPCNT);
10008
    if (realign) {
10009
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10010
      xp = tmp;
10011
    } else {
10012
      xp = (ushort *) *xpp;
10013
    }
10014
   /* copy the next block */
10015
#pragma cdir loopcnt=LOOPCNT
10016
#pragma cdir shortloop
10017
    for (i=0; i<ni; i++) {
10018
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
10019
     /* test for range errors (not always needed but do it anyway) */
10020
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10021
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10022
      nrange += xp[i] > SHORT_MAX ;
10023
    }
10024
   /* update xpp and tp */
10025
    if (realign) xp = (ushort *) *xpp;
10026
    xp += ni;
10027
    tp += ni;
10028
    *xpp = (void*)xp;
10029
  }
10030
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10031
10032
#else   /* not SX */
10033
0
  const char *xp = (const char *) *xpp;
10034
0
  int status = NC_NOERR;
10035
10036
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10037
0
  {
10038
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
10039
0
    if (status == NC_NOERR) /* report the first encountered error */
10040
0
      status = lstatus;
10041
0
  }
10042
10043
0
  *xpp = (const void *)xp;
10044
0
  return status;
10045
0
#endif
10046
0
}
10047
10048
int
10049
ncx_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10050
0
{
10051
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10052
10053
 /* basic algorithm is:
10054
  *   - ensure sane alignment of input data
10055
  *   - copy (conversion happens automatically) input data
10056
  *     to output
10057
  *   - update xpp to point at next unconverted input, and tp to point
10058
  *     at next location for converted output
10059
  */
10060
  long i, j, ni;
10061
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10062
  ushort *xp;
10063
  int nrange = 0;         /* number of range errors */
10064
  int realign = 0;        /* "do we need to fix input data alignment?" */
10065
  long cxp = (long) *((char**)xpp);
10066
10067
  realign = (cxp & 7) % SIZEOF_USHORT;
10068
  /* sjl: manually stripmine so we can limit amount of
10069
   * vector work space reserved to LOOPCNT elements. Also
10070
   * makes vectorisation easy */
10071
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10072
    ni=Min(nelems-j,LOOPCNT);
10073
    if (realign) {
10074
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10075
      xp = tmp;
10076
    } else {
10077
      xp = (ushort *) *xpp;
10078
    }
10079
   /* copy the next block */
10080
#pragma cdir loopcnt=LOOPCNT
10081
#pragma cdir shortloop
10082
    for (i=0; i<ni; i++) {
10083
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
10084
     /* test for range errors (not always needed but do it anyway) */
10085
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10086
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10087
      nrange += xp[i] > INT_MAX ;
10088
    }
10089
   /* update xpp and tp */
10090
    if (realign) xp = (ushort *) *xpp;
10091
    xp += ni;
10092
    tp += ni;
10093
    *xpp = (void*)xp;
10094
  }
10095
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10096
10097
#else   /* not SX */
10098
0
  const char *xp = (const char *) *xpp;
10099
0
  int status = NC_NOERR;
10100
10101
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10102
0
  {
10103
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
10104
0
    if (status == NC_NOERR) /* report the first encountered error */
10105
0
      status = lstatus;
10106
0
  }
10107
10108
0
  *xpp = (const void *)xp;
10109
0
  return status;
10110
0
#endif
10111
0
}
10112
10113
int
10114
ncx_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10115
0
{
10116
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10117
10118
 /* basic algorithm is:
10119
  *   - ensure sane alignment of input data
10120
  *   - copy (conversion happens automatically) input data
10121
  *     to output
10122
  *   - update xpp to point at next unconverted input, and tp to point
10123
  *     at next location for converted output
10124
  */
10125
  long i, j, ni;
10126
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10127
  ushort *xp;
10128
  int nrange = 0;         /* number of range errors */
10129
  int realign = 0;        /* "do we need to fix input data alignment?" */
10130
  long cxp = (long) *((char**)xpp);
10131
10132
  realign = (cxp & 7) % SIZEOF_USHORT;
10133
  /* sjl: manually stripmine so we can limit amount of
10134
   * vector work space reserved to LOOPCNT elements. Also
10135
   * makes vectorisation easy */
10136
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10137
    ni=Min(nelems-j,LOOPCNT);
10138
    if (realign) {
10139
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10140
      xp = tmp;
10141
    } else {
10142
      xp = (ushort *) *xpp;
10143
    }
10144
   /* copy the next block */
10145
#pragma cdir loopcnt=LOOPCNT
10146
#pragma cdir shortloop
10147
    for (i=0; i<ni; i++) {
10148
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
10149
     /* test for range errors (not always needed but do it anyway) */
10150
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10151
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10152
      nrange += xp[i] > LONG_MAX ;
10153
    }
10154
   /* update xpp and tp */
10155
    if (realign) xp = (ushort *) *xpp;
10156
    xp += ni;
10157
    tp += ni;
10158
    *xpp = (void*)xp;
10159
  }
10160
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10161
10162
#else   /* not SX */
10163
0
  const char *xp = (const char *) *xpp;
10164
0
  int status = NC_NOERR;
10165
10166
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10167
0
  {
10168
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
10169
0
    if (status == NC_NOERR) /* report the first encountered error */
10170
0
      status = lstatus;
10171
0
  }
10172
10173
0
  *xpp = (const void *)xp;
10174
0
  return status;
10175
0
#endif
10176
0
}
10177
10178
int
10179
ncx_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10180
0
{
10181
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10182
10183
 /* basic algorithm is:
10184
  *   - ensure sane alignment of input data
10185
  *   - copy (conversion happens automatically) input data
10186
  *     to output
10187
  *   - update xpp to point at next unconverted input, and tp to point
10188
  *     at next location for converted output
10189
  */
10190
  long i, j, ni;
10191
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10192
  ushort *xp;
10193
  int nrange = 0;         /* number of range errors */
10194
  int realign = 0;        /* "do we need to fix input data alignment?" */
10195
  long cxp = (long) *((char**)xpp);
10196
10197
  realign = (cxp & 7) % SIZEOF_USHORT;
10198
  /* sjl: manually stripmine so we can limit amount of
10199
   * vector work space reserved to LOOPCNT elements. Also
10200
   * makes vectorisation easy */
10201
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10202
    ni=Min(nelems-j,LOOPCNT);
10203
    if (realign) {
10204
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10205
      xp = tmp;
10206
    } else {
10207
      xp = (ushort *) *xpp;
10208
    }
10209
   /* copy the next block */
10210
#pragma cdir loopcnt=LOOPCNT
10211
#pragma cdir shortloop
10212
    for (i=0; i<ni; i++) {
10213
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
10214
     /* test for range errors (not always needed but do it anyway) */
10215
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10216
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10217
      nrange += xp[i] > FLOAT_MAX ;
10218
    }
10219
   /* update xpp and tp */
10220
    if (realign) xp = (ushort *) *xpp;
10221
    xp += ni;
10222
    tp += ni;
10223
    *xpp = (void*)xp;
10224
  }
10225
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10226
10227
#else   /* not SX */
10228
0
  const char *xp = (const char *) *xpp;
10229
0
  int status = NC_NOERR;
10230
10231
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10232
0
  {
10233
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10234
0
    if (status == NC_NOERR) /* report the first encountered error */
10235
0
      status = lstatus;
10236
0
  }
10237
10238
0
  *xpp = (const void *)xp;
10239
0
  return status;
10240
0
#endif
10241
0
}
10242
10243
int
10244
ncx_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10245
0
{
10246
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10247
10248
 /* basic algorithm is:
10249
  *   - ensure sane alignment of input data
10250
  *   - copy (conversion happens automatically) input data
10251
  *     to output
10252
  *   - update xpp to point at next unconverted input, and tp to point
10253
  *     at next location for converted output
10254
  */
10255
  long i, j, ni;
10256
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10257
  ushort *xp;
10258
  int nrange = 0;         /* number of range errors */
10259
  int realign = 0;        /* "do we need to fix input data alignment?" */
10260
  long cxp = (long) *((char**)xpp);
10261
10262
  realign = (cxp & 7) % SIZEOF_USHORT;
10263
  /* sjl: manually stripmine so we can limit amount of
10264
   * vector work space reserved to LOOPCNT elements. Also
10265
   * makes vectorisation easy */
10266
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10267
    ni=Min(nelems-j,LOOPCNT);
10268
    if (realign) {
10269
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10270
      xp = tmp;
10271
    } else {
10272
      xp = (ushort *) *xpp;
10273
    }
10274
   /* copy the next block */
10275
#pragma cdir loopcnt=LOOPCNT
10276
#pragma cdir shortloop
10277
    for (i=0; i<ni; i++) {
10278
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
10279
     /* test for range errors (not always needed but do it anyway) */
10280
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10281
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10282
      nrange += xp[i] > DOUBLE_MAX ;
10283
    }
10284
   /* update xpp and tp */
10285
    if (realign) xp = (ushort *) *xpp;
10286
    xp += ni;
10287
    tp += ni;
10288
    *xpp = (void*)xp;
10289
  }
10290
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10291
10292
#else   /* not SX */
10293
0
  const char *xp = (const char *) *xpp;
10294
0
  int status = NC_NOERR;
10295
10296
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10297
0
  {
10298
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10299
0
    if (status == NC_NOERR) /* report the first encountered error */
10300
0
      status = lstatus;
10301
0
  }
10302
10303
0
  *xpp = (const void *)xp;
10304
0
  return status;
10305
0
#endif
10306
0
}
10307
10308
int
10309
ncx_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10310
0
{
10311
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10312
10313
 /* basic algorithm is:
10314
  *   - ensure sane alignment of input data
10315
  *   - copy (conversion happens automatically) input data
10316
  *     to output
10317
  *   - update xpp to point at next unconverted input, and tp to point
10318
  *     at next location for converted output
10319
  */
10320
  long i, j, ni;
10321
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10322
  ushort *xp;
10323
  int nrange = 0;         /* number of range errors */
10324
  int realign = 0;        /* "do we need to fix input data alignment?" */
10325
  long cxp = (long) *((char**)xpp);
10326
10327
  realign = (cxp & 7) % SIZEOF_USHORT;
10328
  /* sjl: manually stripmine so we can limit amount of
10329
   * vector work space reserved to LOOPCNT elements. Also
10330
   * makes vectorisation easy */
10331
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10332
    ni=Min(nelems-j,LOOPCNT);
10333
    if (realign) {
10334
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10335
      xp = tmp;
10336
    } else {
10337
      xp = (ushort *) *xpp;
10338
    }
10339
   /* copy the next block */
10340
#pragma cdir loopcnt=LOOPCNT
10341
#pragma cdir shortloop
10342
    for (i=0; i<ni; i++) {
10343
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
10344
     /* test for range errors (not always needed but do it anyway) */
10345
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10346
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10347
      nrange += xp[i] > LONGLONG_MAX ;
10348
    }
10349
   /* update xpp and tp */
10350
    if (realign) xp = (ushort *) *xpp;
10351
    xp += ni;
10352
    tp += ni;
10353
    *xpp = (void*)xp;
10354
  }
10355
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10356
10357
#else   /* not SX */
10358
0
  const char *xp = (const char *) *xpp;
10359
0
  int status = NC_NOERR;
10360
10361
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10362
0
  {
10363
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10364
0
    if (status == NC_NOERR) /* report the first encountered error */
10365
0
      status = lstatus;
10366
0
  }
10367
10368
0
  *xpp = (const void *)xp;
10369
0
  return status;
10370
0
#endif
10371
0
}
10372
10373
int
10374
ncx_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10375
0
{
10376
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10377
10378
 /* basic algorithm is:
10379
  *   - ensure sane alignment of input data
10380
  *   - copy (conversion happens automatically) input data
10381
  *     to output
10382
  *   - update xpp to point at next unconverted input, and tp to point
10383
  *     at next location for converted output
10384
  */
10385
  long i, j, ni;
10386
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10387
  ushort *xp;
10388
  int nrange = 0;         /* number of range errors */
10389
  int realign = 0;        /* "do we need to fix input data alignment?" */
10390
  long cxp = (long) *((char**)xpp);
10391
10392
  realign = (cxp & 7) % SIZEOF_USHORT;
10393
  /* sjl: manually stripmine so we can limit amount of
10394
   * vector work space reserved to LOOPCNT elements. Also
10395
   * makes vectorisation easy */
10396
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10397
    ni=Min(nelems-j,LOOPCNT);
10398
    if (realign) {
10399
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10400
      xp = tmp;
10401
    } else {
10402
      xp = (ushort *) *xpp;
10403
    }
10404
   /* copy the next block */
10405
#pragma cdir loopcnt=LOOPCNT
10406
#pragma cdir shortloop
10407
    for (i=0; i<ni; i++) {
10408
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
10409
     /* test for range errors (not always needed but do it anyway) */
10410
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10411
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10412
      nrange += xp[i] > UCHAR_MAX ;
10413
    }
10414
   /* update xpp and tp */
10415
    if (realign) xp = (ushort *) *xpp;
10416
    xp += ni;
10417
    tp += ni;
10418
    *xpp = (void*)xp;
10419
  }
10420
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10421
10422
#else   /* not SX */
10423
0
  const char *xp = (const char *) *xpp;
10424
0
  int status = NC_NOERR;
10425
10426
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10427
0
  {
10428
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10429
0
    if (status == NC_NOERR) /* report the first encountered error */
10430
0
      status = lstatus;
10431
0
  }
10432
10433
0
  *xpp = (const void *)xp;
10434
0
  return status;
10435
0
#endif
10436
0
}
10437
10438
int
10439
ncx_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10440
0
{
10441
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10442
10443
 /* basic algorithm is:
10444
  *   - ensure sane alignment of input data
10445
  *   - copy (conversion happens automatically) input data
10446
  *     to output
10447
  *   - update xpp to point at next unconverted input, and tp to point
10448
  *     at next location for converted output
10449
  */
10450
  long i, j, ni;
10451
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10452
  ushort *xp;
10453
  int nrange = 0;         /* number of range errors */
10454
  int realign = 0;        /* "do we need to fix input data alignment?" */
10455
  long cxp = (long) *((char**)xpp);
10456
10457
  realign = (cxp & 7) % SIZEOF_USHORT;
10458
  /* sjl: manually stripmine so we can limit amount of
10459
   * vector work space reserved to LOOPCNT elements. Also
10460
   * makes vectorisation easy */
10461
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10462
    ni=Min(nelems-j,LOOPCNT);
10463
    if (realign) {
10464
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10465
      xp = tmp;
10466
    } else {
10467
      xp = (ushort *) *xpp;
10468
    }
10469
   /* copy the next block */
10470
#pragma cdir loopcnt=LOOPCNT
10471
#pragma cdir shortloop
10472
    for (i=0; i<ni; i++) {
10473
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
10474
     /* test for range errors (not always needed but do it anyway) */
10475
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10476
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10477
      nrange += xp[i] > UINT_MAX ;
10478
    }
10479
   /* update xpp and tp */
10480
    if (realign) xp = (ushort *) *xpp;
10481
    xp += ni;
10482
    tp += ni;
10483
    *xpp = (void*)xp;
10484
  }
10485
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10486
10487
#else   /* not SX */
10488
0
  const char *xp = (const char *) *xpp;
10489
0
  int status = NC_NOERR;
10490
10491
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10492
0
  {
10493
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10494
0
    if (status == NC_NOERR) /* report the first encountered error */
10495
0
      status = lstatus;
10496
0
  }
10497
10498
0
  *xpp = (const void *)xp;
10499
0
  return status;
10500
0
#endif
10501
0
}
10502
10503
int
10504
ncx_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10505
0
{
10506
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10507
10508
 /* basic algorithm is:
10509
  *   - ensure sane alignment of input data
10510
  *   - copy (conversion happens automatically) input data
10511
  *     to output
10512
  *   - update xpp to point at next unconverted input, and tp to point
10513
  *     at next location for converted output
10514
  */
10515
  long i, j, ni;
10516
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10517
  ushort *xp;
10518
  int nrange = 0;         /* number of range errors */
10519
  int realign = 0;        /* "do we need to fix input data alignment?" */
10520
  long cxp = (long) *((char**)xpp);
10521
10522
  realign = (cxp & 7) % SIZEOF_USHORT;
10523
  /* sjl: manually stripmine so we can limit amount of
10524
   * vector work space reserved to LOOPCNT elements. Also
10525
   * makes vectorisation easy */
10526
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10527
    ni=Min(nelems-j,LOOPCNT);
10528
    if (realign) {
10529
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10530
      xp = tmp;
10531
    } else {
10532
      xp = (ushort *) *xpp;
10533
    }
10534
   /* copy the next block */
10535
#pragma cdir loopcnt=LOOPCNT
10536
#pragma cdir shortloop
10537
    for (i=0; i<ni; i++) {
10538
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
10539
     /* test for range errors (not always needed but do it anyway) */
10540
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10541
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10542
      nrange += xp[i] > ULONGLONG_MAX ;
10543
    }
10544
   /* update xpp and tp */
10545
    if (realign) xp = (ushort *) *xpp;
10546
    xp += ni;
10547
    tp += ni;
10548
    *xpp = (void*)xp;
10549
  }
10550
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10551
10552
#else   /* not SX */
10553
0
  const char *xp = (const char *) *xpp;
10554
0
  int status = NC_NOERR;
10555
10556
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10557
0
  {
10558
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10559
0
    if (status == NC_NOERR) /* report the first encountered error */
10560
0
      status = lstatus;
10561
0
  }
10562
10563
0
  *xpp = (const void *)xp;
10564
0
  return status;
10565
0
#endif
10566
0
}
10567
10568
10569
int
10570
ncx_pad_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
10571
0
{
10572
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10573
10574
0
  const char *xp = (const char *) *xpp;
10575
0
  int status = NC_NOERR;
10576
10577
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10578
0
  {
10579
0
    const int lstatus = ncx_get_ushort_schar(xp, tp);
10580
0
    if (status == NC_NOERR) /* report the first encountered error */
10581
0
      status = lstatus;
10582
0
  }
10583
10584
0
  if (rndup != 0)
10585
0
    xp += X_SIZEOF_USHORT;
10586
10587
0
  *xpp = (void *)xp;
10588
0
  return status;
10589
0
}
10590
10591
int
10592
ncx_pad_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
10593
0
{
10594
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10595
10596
0
  const char *xp = (const char *) *xpp;
10597
0
  int status = NC_NOERR;
10598
10599
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10600
0
  {
10601
0
    const int lstatus = ncx_get_ushort_short(xp, tp);
10602
0
    if (status == NC_NOERR) /* report the first encountered error */
10603
0
      status = lstatus;
10604
0
  }
10605
10606
0
  if (rndup != 0)
10607
0
    xp += X_SIZEOF_USHORT;
10608
10609
0
  *xpp = (void *)xp;
10610
0
  return status;
10611
0
}
10612
10613
int
10614
ncx_pad_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10615
0
{
10616
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10617
10618
0
  const char *xp = (const char *) *xpp;
10619
0
  int status = NC_NOERR;
10620
10621
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10622
0
  {
10623
0
    const int lstatus = ncx_get_ushort_int(xp, tp);
10624
0
    if (status == NC_NOERR) /* report the first encountered error */
10625
0
      status = lstatus;
10626
0
  }
10627
10628
0
  if (rndup != 0)
10629
0
    xp += X_SIZEOF_USHORT;
10630
10631
0
  *xpp = (void *)xp;
10632
0
  return status;
10633
0
}
10634
10635
int
10636
ncx_pad_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10637
0
{
10638
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10639
10640
0
  const char *xp = (const char *) *xpp;
10641
0
  int status = NC_NOERR;
10642
10643
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10644
0
  {
10645
0
    const int lstatus = ncx_get_ushort_long(xp, tp);
10646
0
    if (status == NC_NOERR) /* report the first encountered error */
10647
0
      status = lstatus;
10648
0
  }
10649
10650
0
  if (rndup != 0)
10651
0
    xp += X_SIZEOF_USHORT;
10652
10653
0
  *xpp = (void *)xp;
10654
0
  return status;
10655
0
}
10656
10657
int
10658
ncx_pad_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10659
0
{
10660
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10661
10662
0
  const char *xp = (const char *) *xpp;
10663
0
  int status = NC_NOERR;
10664
10665
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10666
0
  {
10667
0
    const int lstatus = ncx_get_ushort_float(xp, tp);
10668
0
    if (status == NC_NOERR) /* report the first encountered error */
10669
0
      status = lstatus;
10670
0
  }
10671
10672
0
  if (rndup != 0)
10673
0
    xp += X_SIZEOF_USHORT;
10674
10675
0
  *xpp = (void *)xp;
10676
0
  return status;
10677
0
}
10678
10679
int
10680
ncx_pad_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10681
0
{
10682
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10683
10684
0
  const char *xp = (const char *) *xpp;
10685
0
  int status = NC_NOERR;
10686
10687
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10688
0
  {
10689
0
    const int lstatus = ncx_get_ushort_double(xp, tp);
10690
0
    if (status == NC_NOERR) /* report the first encountered error */
10691
0
      status = lstatus;
10692
0
  }
10693
10694
0
  if (rndup != 0)
10695
0
    xp += X_SIZEOF_USHORT;
10696
10697
0
  *xpp = (void *)xp;
10698
0
  return status;
10699
0
}
10700
10701
int
10702
ncx_pad_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10703
0
{
10704
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10705
10706
0
  const char *xp = (const char *) *xpp;
10707
0
  int status = NC_NOERR;
10708
10709
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10710
0
  {
10711
0
    const int lstatus = ncx_get_ushort_uchar(xp, tp);
10712
0
    if (status == NC_NOERR) /* report the first encountered error */
10713
0
      status = lstatus;
10714
0
  }
10715
10716
0
  if (rndup != 0)
10717
0
    xp += X_SIZEOF_USHORT;
10718
10719
0
  *xpp = (void *)xp;
10720
0
  return status;
10721
0
}
10722
10723
int
10724
ncx_pad_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
10725
0
{
10726
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10727
10728
0
  const char *xp = (const char *) *xpp;
10729
0
  int status = NC_NOERR;
10730
10731
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10732
0
  {
10733
0
    const int lstatus = ncx_get_ushort_ushort(xp, tp);
10734
0
    if (status == NC_NOERR) /* report the first encountered error */
10735
0
      status = lstatus;
10736
0
  }
10737
10738
0
  if (rndup != 0)
10739
0
    xp += X_SIZEOF_USHORT;
10740
10741
0
  *xpp = (void *)xp;
10742
0
  return status;
10743
0
}
10744
10745
int
10746
ncx_pad_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10747
0
{
10748
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10749
10750
0
  const char *xp = (const char *) *xpp;
10751
0
  int status = NC_NOERR;
10752
10753
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10754
0
  {
10755
0
    const int lstatus = ncx_get_ushort_uint(xp, tp);
10756
0
    if (status == NC_NOERR) /* report the first encountered error */
10757
0
      status = lstatus;
10758
0
  }
10759
10760
0
  if (rndup != 0)
10761
0
    xp += X_SIZEOF_USHORT;
10762
10763
0
  *xpp = (void *)xp;
10764
0
  return status;
10765
0
}
10766
10767
int
10768
ncx_pad_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10769
0
{
10770
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10771
10772
0
  const char *xp = (const char *) *xpp;
10773
0
  int status = NC_NOERR;
10774
10775
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10776
0
  {
10777
0
    const int lstatus = ncx_get_ushort_longlong(xp, tp);
10778
0
    if (status == NC_NOERR) /* report the first encountered error */
10779
0
      status = lstatus;
10780
0
  }
10781
10782
0
  if (rndup != 0)
10783
0
    xp += X_SIZEOF_USHORT;
10784
10785
0
  *xpp = (void *)xp;
10786
0
  return status;
10787
0
}
10788
10789
int
10790
ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10791
0
{
10792
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
10793
10794
0
  const char *xp = (const char *) *xpp;
10795
0
  int status = NC_NOERR;
10796
10797
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10798
0
  {
10799
0
    const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10800
0
    if (status == NC_NOERR) /* report the first encountered error */
10801
0
      status = lstatus;
10802
0
  }
10803
10804
0
  if (rndup != 0)
10805
0
    xp += X_SIZEOF_USHORT;
10806
10807
0
  *xpp = (void *)xp;
10808
0
  return status;
10809
0
}
10810
10811
10812
#if X_SIZEOF_USHORT == SIZEOF_USHORT
10813
/* optimized version */
10814
int
10815
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp, void *fillp)
10816
0
{
10817
#ifdef WORDS_BIGENDIAN
10818
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
10819
# else
10820
0
  swapn2b(*xpp, tp, nelems);
10821
0
# endif
10822
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
10823
0
  return NC_NOERR;
10824
0
}
10825
#else
10826
int
10827
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
10828
{
10829
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10830
10831
 /* basic algorithm is:
10832
  *   - ensure sane alignment of output data
10833
  *   - copy (conversion happens automatically) input data
10834
  *     to output
10835
  *   - update tp to point at next unconverted input, and xpp to point
10836
  *     at next location for converted output
10837
  */
10838
  long i, j, ni;
10839
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10840
  ushort *xp;
10841
  int nrange = 0;         /* number of range errors */
10842
  int realign = 0;        /* "do we need to fix input data alignment?" */
10843
  long cxp = (long) *((char**)xpp);
10844
10845
  realign = (cxp & 7) % SIZEOF_USHORT;
10846
  /* sjl: manually stripmine so we can limit amount of
10847
   * vector work space reserved to LOOPCNT elements. Also
10848
   * makes vectorisation easy */
10849
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10850
    ni=Min(nelems-j,LOOPCNT);
10851
    if (realign) {
10852
      xp = tmp;
10853
    } else {
10854
      xp = (ushort *) *xpp;
10855
    }
10856
   /* copy the next block */
10857
#pragma cdir loopcnt=LOOPCNT
10858
#pragma cdir shortloop
10859
    for (i=0; i<ni; i++) {
10860
      /* the normal case: */
10861
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10862
     /* test for range errors (not always needed but do it anyway) */
10863
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10864
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10865
      nrange += tp[i] > X_USHORT_MAX ;
10866
    }
10867
   /* copy workspace back if necessary */
10868
    if (realign) {
10869
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10870
      xp = (ushort *) *xpp;
10871
    }
10872
   /* update xpp and tp */
10873
    xp += ni;
10874
    tp += ni;
10875
    *xpp = (void*)xp;
10876
  }
10877
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10878
10879
#else   /* not SX */
10880
10881
  char *xp = (char *) *xpp;
10882
  int status = NC_NOERR;
10883
10884
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10885
  {
10886
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
10887
    if (status == NC_NOERR) /* report the first encountered error */
10888
      status = lstatus;
10889
  }
10890
10891
  *xpp = (void *)xp;
10892
  return status;
10893
#endif
10894
}
10895
10896
#endif
10897
int
10898
ncx_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
10899
0
{
10900
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10901
10902
 /* basic algorithm is:
10903
  *   - ensure sane alignment of output data
10904
  *   - copy (conversion happens automatically) input data
10905
  *     to output
10906
  *   - update tp to point at next unconverted input, and xpp to point
10907
  *     at next location for converted output
10908
  */
10909
  long i, j, ni;
10910
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10911
  ushort *xp;
10912
  int nrange = 0;         /* number of range errors */
10913
  int realign = 0;        /* "do we need to fix input data alignment?" */
10914
  long cxp = (long) *((char**)xpp);
10915
10916
  realign = (cxp & 7) % SIZEOF_USHORT;
10917
  /* sjl: manually stripmine so we can limit amount of
10918
   * vector work space reserved to LOOPCNT elements. Also
10919
   * makes vectorisation easy */
10920
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10921
    ni=Min(nelems-j,LOOPCNT);
10922
    if (realign) {
10923
      xp = tmp;
10924
    } else {
10925
      xp = (ushort *) *xpp;
10926
    }
10927
   /* copy the next block */
10928
#pragma cdir loopcnt=LOOPCNT
10929
#pragma cdir shortloop
10930
    for (i=0; i<ni; i++) {
10931
      /* the normal case: */
10932
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10933
     /* test for range errors (not always needed but do it anyway) */
10934
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10935
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10936
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10937
    }
10938
   /* copy workspace back if necessary */
10939
    if (realign) {
10940
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10941
      xp = (ushort *) *xpp;
10942
    }
10943
   /* update xpp and tp */
10944
    xp += ni;
10945
    tp += ni;
10946
    *xpp = (void*)xp;
10947
  }
10948
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
10949
10950
#else   /* not SX */
10951
10952
0
  char *xp = (char *) *xpp;
10953
0
  int status = NC_NOERR;
10954
10955
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10956
0
  {
10957
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
10958
0
    if (status == NC_NOERR) /* report the first encountered error */
10959
0
      status = lstatus;
10960
0
  }
10961
10962
0
  *xpp = (void *)xp;
10963
0
  return status;
10964
0
#endif
10965
0
}
10966
10967
int
10968
ncx_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
10969
0
{
10970
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10971
10972
 /* basic algorithm is:
10973
  *   - ensure sane alignment of output data
10974
  *   - copy (conversion happens automatically) input data
10975
  *     to output
10976
  *   - update tp to point at next unconverted input, and xpp to point
10977
  *     at next location for converted output
10978
  */
10979
  long i, j, ni;
10980
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
10981
  ushort *xp;
10982
  int nrange = 0;         /* number of range errors */
10983
  int realign = 0;        /* "do we need to fix input data alignment?" */
10984
  long cxp = (long) *((char**)xpp);
10985
10986
  realign = (cxp & 7) % SIZEOF_USHORT;
10987
  /* sjl: manually stripmine so we can limit amount of
10988
   * vector work space reserved to LOOPCNT elements. Also
10989
   * makes vectorisation easy */
10990
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10991
    ni=Min(nelems-j,LOOPCNT);
10992
    if (realign) {
10993
      xp = tmp;
10994
    } else {
10995
      xp = (ushort *) *xpp;
10996
    }
10997
   /* copy the next block */
10998
#pragma cdir loopcnt=LOOPCNT
10999
#pragma cdir shortloop
11000
    for (i=0; i<ni; i++) {
11001
      /* the normal case: */
11002
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11003
     /* test for range errors (not always needed but do it anyway) */
11004
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11005
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11006
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11007
    }
11008
   /* copy workspace back if necessary */
11009
    if (realign) {
11010
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11011
      xp = (ushort *) *xpp;
11012
    }
11013
   /* update xpp and tp */
11014
    xp += ni;
11015
    tp += ni;
11016
    *xpp = (void*)xp;
11017
  }
11018
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11019
11020
#else   /* not SX */
11021
11022
0
  char *xp = (char *) *xpp;
11023
0
  int status = NC_NOERR;
11024
11025
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11026
0
  {
11027
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11028
0
    if (status == NC_NOERR) /* report the first encountered error */
11029
0
      status = lstatus;
11030
0
  }
11031
11032
0
  *xpp = (void *)xp;
11033
0
  return status;
11034
0
#endif
11035
0
}
11036
11037
int
11038
ncx_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11039
0
{
11040
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11041
11042
 /* basic algorithm is:
11043
  *   - ensure sane alignment of output data
11044
  *   - copy (conversion happens automatically) input data
11045
  *     to output
11046
  *   - update tp to point at next unconverted input, and xpp to point
11047
  *     at next location for converted output
11048
  */
11049
  long i, j, ni;
11050
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11051
  ushort *xp;
11052
  int nrange = 0;         /* number of range errors */
11053
  int realign = 0;        /* "do we need to fix input data alignment?" */
11054
  long cxp = (long) *((char**)xpp);
11055
11056
  realign = (cxp & 7) % SIZEOF_USHORT;
11057
  /* sjl: manually stripmine so we can limit amount of
11058
   * vector work space reserved to LOOPCNT elements. Also
11059
   * makes vectorisation easy */
11060
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11061
    ni=Min(nelems-j,LOOPCNT);
11062
    if (realign) {
11063
      xp = tmp;
11064
    } else {
11065
      xp = (ushort *) *xpp;
11066
    }
11067
   /* copy the next block */
11068
#pragma cdir loopcnt=LOOPCNT
11069
#pragma cdir shortloop
11070
    for (i=0; i<ni; i++) {
11071
      /* the normal case: */
11072
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11073
     /* test for range errors (not always needed but do it anyway) */
11074
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11075
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11076
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11077
    }
11078
   /* copy workspace back if necessary */
11079
    if (realign) {
11080
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11081
      xp = (ushort *) *xpp;
11082
    }
11083
   /* update xpp and tp */
11084
    xp += ni;
11085
    tp += ni;
11086
    *xpp = (void*)xp;
11087
  }
11088
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11089
11090
#else   /* not SX */
11091
11092
0
  char *xp = (char *) *xpp;
11093
0
  int status = NC_NOERR;
11094
11095
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11096
0
  {
11097
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11098
0
    if (status == NC_NOERR) /* report the first encountered error */
11099
0
      status = lstatus;
11100
0
  }
11101
11102
0
  *xpp = (void *)xp;
11103
0
  return status;
11104
0
#endif
11105
0
}
11106
11107
int
11108
ncx_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11109
0
{
11110
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11111
11112
 /* basic algorithm is:
11113
  *   - ensure sane alignment of output data
11114
  *   - copy (conversion happens automatically) input data
11115
  *     to output
11116
  *   - update tp to point at next unconverted input, and xpp to point
11117
  *     at next location for converted output
11118
  */
11119
  long i, j, ni;
11120
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11121
  ushort *xp;
11122
  int nrange = 0;         /* number of range errors */
11123
  int realign = 0;        /* "do we need to fix input data alignment?" */
11124
  long cxp = (long) *((char**)xpp);
11125
11126
  realign = (cxp & 7) % SIZEOF_USHORT;
11127
  /* sjl: manually stripmine so we can limit amount of
11128
   * vector work space reserved to LOOPCNT elements. Also
11129
   * makes vectorisation easy */
11130
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11131
    ni=Min(nelems-j,LOOPCNT);
11132
    if (realign) {
11133
      xp = tmp;
11134
    } else {
11135
      xp = (ushort *) *xpp;
11136
    }
11137
   /* copy the next block */
11138
#pragma cdir loopcnt=LOOPCNT
11139
#pragma cdir shortloop
11140
    for (i=0; i<ni; i++) {
11141
      /* the normal case: */
11142
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11143
     /* test for range errors (not always needed but do it anyway) */
11144
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11145
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11146
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11147
    }
11148
   /* copy workspace back if necessary */
11149
    if (realign) {
11150
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11151
      xp = (ushort *) *xpp;
11152
    }
11153
   /* update xpp and tp */
11154
    xp += ni;
11155
    tp += ni;
11156
    *xpp = (void*)xp;
11157
  }
11158
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11159
11160
#else   /* not SX */
11161
11162
0
  char *xp = (char *) *xpp;
11163
0
  int status = NC_NOERR;
11164
11165
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11166
0
  {
11167
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11168
0
    if (status == NC_NOERR) /* report the first encountered error */
11169
0
      status = lstatus;
11170
0
  }
11171
11172
0
  *xpp = (void *)xp;
11173
0
  return status;
11174
0
#endif
11175
0
}
11176
11177
int
11178
ncx_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11179
0
{
11180
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11181
11182
 /* basic algorithm is:
11183
  *   - ensure sane alignment of output data
11184
  *   - copy (conversion happens automatically) input data
11185
  *     to output
11186
  *   - update tp to point at next unconverted input, and xpp to point
11187
  *     at next location for converted output
11188
  */
11189
  long i, j, ni;
11190
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11191
  ushort *xp;
11192
  int nrange = 0;         /* number of range errors */
11193
  int realign = 0;        /* "do we need to fix input data alignment?" */
11194
  long cxp = (long) *((char**)xpp);
11195
11196
  realign = (cxp & 7) % SIZEOF_USHORT;
11197
  /* sjl: manually stripmine so we can limit amount of
11198
   * vector work space reserved to LOOPCNT elements. Also
11199
   * makes vectorisation easy */
11200
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11201
    ni=Min(nelems-j,LOOPCNT);
11202
    if (realign) {
11203
      xp = tmp;
11204
    } else {
11205
      xp = (ushort *) *xpp;
11206
    }
11207
   /* copy the next block */
11208
#pragma cdir loopcnt=LOOPCNT
11209
#pragma cdir shortloop
11210
    for (i=0; i<ni; i++) {
11211
      /* the normal case: */
11212
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11213
     /* test for range errors (not always needed but do it anyway) */
11214
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11215
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11216
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11217
    }
11218
   /* copy workspace back if necessary */
11219
    if (realign) {
11220
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11221
      xp = (ushort *) *xpp;
11222
    }
11223
   /* update xpp and tp */
11224
    xp += ni;
11225
    tp += ni;
11226
    *xpp = (void*)xp;
11227
  }
11228
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11229
11230
#else   /* not SX */
11231
11232
0
  char *xp = (char *) *xpp;
11233
0
  int status = NC_NOERR;
11234
11235
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11236
0
  {
11237
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11238
0
    if (status == NC_NOERR) /* report the first encountered error */
11239
0
      status = lstatus;
11240
0
  }
11241
11242
0
  *xpp = (void *)xp;
11243
0
  return status;
11244
0
#endif
11245
0
}
11246
11247
int
11248
ncx_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11249
0
{
11250
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11251
11252
 /* basic algorithm is:
11253
  *   - ensure sane alignment of output data
11254
  *   - copy (conversion happens automatically) input data
11255
  *     to output
11256
  *   - update tp to point at next unconverted input, and xpp to point
11257
  *     at next location for converted output
11258
  */
11259
  long i, j, ni;
11260
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11261
  ushort *xp;
11262
  int nrange = 0;         /* number of range errors */
11263
  int realign = 0;        /* "do we need to fix input data alignment?" */
11264
  long cxp = (long) *((char**)xpp);
11265
11266
  realign = (cxp & 7) % SIZEOF_USHORT;
11267
  /* sjl: manually stripmine so we can limit amount of
11268
   * vector work space reserved to LOOPCNT elements. Also
11269
   * makes vectorisation easy */
11270
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11271
    ni=Min(nelems-j,LOOPCNT);
11272
    if (realign) {
11273
      xp = tmp;
11274
    } else {
11275
      xp = (ushort *) *xpp;
11276
    }
11277
   /* copy the next block */
11278
#pragma cdir loopcnt=LOOPCNT
11279
#pragma cdir shortloop
11280
    for (i=0; i<ni; i++) {
11281
      /* the normal case: */
11282
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11283
     /* test for range errors (not always needed but do it anyway) */
11284
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11285
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11286
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11287
    }
11288
   /* copy workspace back if necessary */
11289
    if (realign) {
11290
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11291
      xp = (ushort *) *xpp;
11292
    }
11293
   /* update xpp and tp */
11294
    xp += ni;
11295
    tp += ni;
11296
    *xpp = (void*)xp;
11297
  }
11298
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11299
11300
#else   /* not SX */
11301
11302
0
  char *xp = (char *) *xpp;
11303
0
  int status = NC_NOERR;
11304
11305
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11306
0
  {
11307
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11308
0
    if (status == NC_NOERR) /* report the first encountered error */
11309
0
      status = lstatus;
11310
0
  }
11311
11312
0
  *xpp = (void *)xp;
11313
0
  return status;
11314
0
#endif
11315
0
}
11316
11317
int
11318
ncx_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11319
0
{
11320
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11321
11322
 /* basic algorithm is:
11323
  *   - ensure sane alignment of output data
11324
  *   - copy (conversion happens automatically) input data
11325
  *     to output
11326
  *   - update tp to point at next unconverted input, and xpp to point
11327
  *     at next location for converted output
11328
  */
11329
  long i, j, ni;
11330
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11331
  ushort *xp;
11332
  int nrange = 0;         /* number of range errors */
11333
  int realign = 0;        /* "do we need to fix input data alignment?" */
11334
  long cxp = (long) *((char**)xpp);
11335
11336
  realign = (cxp & 7) % SIZEOF_USHORT;
11337
  /* sjl: manually stripmine so we can limit amount of
11338
   * vector work space reserved to LOOPCNT elements. Also
11339
   * makes vectorisation easy */
11340
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11341
    ni=Min(nelems-j,LOOPCNT);
11342
    if (realign) {
11343
      xp = tmp;
11344
    } else {
11345
      xp = (ushort *) *xpp;
11346
    }
11347
   /* copy the next block */
11348
#pragma cdir loopcnt=LOOPCNT
11349
#pragma cdir shortloop
11350
    for (i=0; i<ni; i++) {
11351
      /* the normal case: */
11352
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11353
     /* test for range errors (not always needed but do it anyway) */
11354
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11355
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11356
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11357
    }
11358
   /* copy workspace back if necessary */
11359
    if (realign) {
11360
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11361
      xp = (ushort *) *xpp;
11362
    }
11363
   /* update xpp and tp */
11364
    xp += ni;
11365
    tp += ni;
11366
    *xpp = (void*)xp;
11367
  }
11368
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11369
11370
#else   /* not SX */
11371
11372
0
  char *xp = (char *) *xpp;
11373
0
  int status = NC_NOERR;
11374
11375
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11376
0
  {
11377
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11378
0
    if (status == NC_NOERR) /* report the first encountered error */
11379
0
      status = lstatus;
11380
0
  }
11381
11382
0
  *xpp = (void *)xp;
11383
0
  return status;
11384
0
#endif
11385
0
}
11386
11387
int
11388
ncx_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11389
0
{
11390
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11391
11392
 /* basic algorithm is:
11393
  *   - ensure sane alignment of output data
11394
  *   - copy (conversion happens automatically) input data
11395
  *     to output
11396
  *   - update tp to point at next unconverted input, and xpp to point
11397
  *     at next location for converted output
11398
  */
11399
  long i, j, ni;
11400
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11401
  ushort *xp;
11402
  int nrange = 0;         /* number of range errors */
11403
  int realign = 0;        /* "do we need to fix input data alignment?" */
11404
  long cxp = (long) *((char**)xpp);
11405
11406
  realign = (cxp & 7) % SIZEOF_USHORT;
11407
  /* sjl: manually stripmine so we can limit amount of
11408
   * vector work space reserved to LOOPCNT elements. Also
11409
   * makes vectorisation easy */
11410
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11411
    ni=Min(nelems-j,LOOPCNT);
11412
    if (realign) {
11413
      xp = tmp;
11414
    } else {
11415
      xp = (ushort *) *xpp;
11416
    }
11417
   /* copy the next block */
11418
#pragma cdir loopcnt=LOOPCNT
11419
#pragma cdir shortloop
11420
    for (i=0; i<ni; i++) {
11421
      /* the normal case: */
11422
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11423
     /* test for range errors (not always needed but do it anyway) */
11424
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11425
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11426
      nrange += tp[i] > X_USHORT_MAX ;
11427
    }
11428
   /* copy workspace back if necessary */
11429
    if (realign) {
11430
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11431
      xp = (ushort *) *xpp;
11432
    }
11433
   /* update xpp and tp */
11434
    xp += ni;
11435
    tp += ni;
11436
    *xpp = (void*)xp;
11437
  }
11438
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11439
11440
#else   /* not SX */
11441
11442
0
  char *xp = (char *) *xpp;
11443
0
  int status = NC_NOERR;
11444
11445
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11446
0
  {
11447
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11448
0
    if (status == NC_NOERR) /* report the first encountered error */
11449
0
      status = lstatus;
11450
0
  }
11451
11452
0
  *xpp = (void *)xp;
11453
0
  return status;
11454
0
#endif
11455
0
}
11456
11457
int
11458
ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11459
0
{
11460
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11461
11462
 /* basic algorithm is:
11463
  *   - ensure sane alignment of output data
11464
  *   - copy (conversion happens automatically) input data
11465
  *     to output
11466
  *   - update tp to point at next unconverted input, and xpp to point
11467
  *     at next location for converted output
11468
  */
11469
  long i, j, ni;
11470
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11471
  ushort *xp;
11472
  int nrange = 0;         /* number of range errors */
11473
  int realign = 0;        /* "do we need to fix input data alignment?" */
11474
  long cxp = (long) *((char**)xpp);
11475
11476
  realign = (cxp & 7) % SIZEOF_USHORT;
11477
  /* sjl: manually stripmine so we can limit amount of
11478
   * vector work space reserved to LOOPCNT elements. Also
11479
   * makes vectorisation easy */
11480
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11481
    ni=Min(nelems-j,LOOPCNT);
11482
    if (realign) {
11483
      xp = tmp;
11484
    } else {
11485
      xp = (ushort *) *xpp;
11486
    }
11487
   /* copy the next block */
11488
#pragma cdir loopcnt=LOOPCNT
11489
#pragma cdir shortloop
11490
    for (i=0; i<ni; i++) {
11491
      /* the normal case: */
11492
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11493
     /* test for range errors (not always needed but do it anyway) */
11494
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11495
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11496
      nrange += tp[i] > X_USHORT_MAX ;
11497
    }
11498
   /* copy workspace back if necessary */
11499
    if (realign) {
11500
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11501
      xp = (ushort *) *xpp;
11502
    }
11503
   /* update xpp and tp */
11504
    xp += ni;
11505
    tp += ni;
11506
    *xpp = (void*)xp;
11507
  }
11508
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11509
11510
#else   /* not SX */
11511
11512
0
  char *xp = (char *) *xpp;
11513
0
  int status = NC_NOERR;
11514
11515
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11516
0
  {
11517
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11518
0
    if (status == NC_NOERR) /* report the first encountered error */
11519
0
      status = lstatus;
11520
0
  }
11521
11522
0
  *xpp = (void *)xp;
11523
0
  return status;
11524
0
#endif
11525
0
}
11526
11527
int
11528
ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11529
0
{
11530
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11531
11532
 /* basic algorithm is:
11533
  *   - ensure sane alignment of output data
11534
  *   - copy (conversion happens automatically) input data
11535
  *     to output
11536
  *   - update tp to point at next unconverted input, and xpp to point
11537
  *     at next location for converted output
11538
  */
11539
  long i, j, ni;
11540
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
11541
  ushort *xp;
11542
  int nrange = 0;         /* number of range errors */
11543
  int realign = 0;        /* "do we need to fix input data alignment?" */
11544
  long cxp = (long) *((char**)xpp);
11545
11546
  realign = (cxp & 7) % SIZEOF_USHORT;
11547
  /* sjl: manually stripmine so we can limit amount of
11548
   * vector work space reserved to LOOPCNT elements. Also
11549
   * makes vectorisation easy */
11550
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11551
    ni=Min(nelems-j,LOOPCNT);
11552
    if (realign) {
11553
      xp = tmp;
11554
    } else {
11555
      xp = (ushort *) *xpp;
11556
    }
11557
   /* copy the next block */
11558
#pragma cdir loopcnt=LOOPCNT
11559
#pragma cdir shortloop
11560
    for (i=0; i<ni; i++) {
11561
      /* the normal case: */
11562
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11563
     /* test for range errors (not always needed but do it anyway) */
11564
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11565
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11566
      nrange += tp[i] > X_USHORT_MAX ;
11567
    }
11568
   /* copy workspace back if necessary */
11569
    if (realign) {
11570
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11571
      xp = (ushort *) *xpp;
11572
    }
11573
   /* update xpp and tp */
11574
    xp += ni;
11575
    tp += ni;
11576
    *xpp = (void*)xp;
11577
  }
11578
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11579
11580
#else   /* not SX */
11581
11582
0
  char *xp = (char *) *xpp;
11583
0
  int status = NC_NOERR;
11584
11585
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11586
0
  {
11587
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11588
0
    if (status == NC_NOERR) /* report the first encountered error */
11589
0
      status = lstatus;
11590
0
  }
11591
11592
0
  *xpp = (void *)xp;
11593
0
  return status;
11594
0
#endif
11595
0
}
11596
11597
11598
int
11599
ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
11600
0
{
11601
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11602
11603
0
  char *xp = (char *) *xpp;
11604
0
  int status = NC_NOERR;
11605
11606
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11607
0
  {
11608
0
    int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
11609
0
    if (status == NC_NOERR) /* report the first encountered error */
11610
0
      status = lstatus;
11611
0
  }
11612
11613
0
  if (rndup != 0)
11614
0
  {
11615
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11616
0
    xp += X_SIZEOF_USHORT;
11617
0
  }
11618
11619
0
  *xpp = (void *)xp;
11620
0
  return status;
11621
0
}
11622
11623
int
11624
ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11625
0
{
11626
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11627
11628
0
  char *xp = (char *) *xpp;
11629
0
  int status = NC_NOERR;
11630
11631
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11632
0
  {
11633
0
    int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11634
0
    if (status == NC_NOERR) /* report the first encountered error */
11635
0
      status = lstatus;
11636
0
  }
11637
11638
0
  if (rndup != 0)
11639
0
  {
11640
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11641
0
    xp += X_SIZEOF_USHORT;
11642
0
  }
11643
11644
0
  *xpp = (void *)xp;
11645
0
  return status;
11646
0
}
11647
11648
int
11649
ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
11650
0
{
11651
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11652
11653
0
  char *xp = (char *) *xpp;
11654
0
  int status = NC_NOERR;
11655
11656
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11657
0
  {
11658
0
    int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11659
0
    if (status == NC_NOERR) /* report the first encountered error */
11660
0
      status = lstatus;
11661
0
  }
11662
11663
0
  if (rndup != 0)
11664
0
  {
11665
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11666
0
    xp += X_SIZEOF_USHORT;
11667
0
  }
11668
11669
0
  *xpp = (void *)xp;
11670
0
  return status;
11671
0
}
11672
11673
int
11674
ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11675
0
{
11676
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11677
11678
0
  char *xp = (char *) *xpp;
11679
0
  int status = NC_NOERR;
11680
11681
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11682
0
  {
11683
0
    int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11684
0
    if (status == NC_NOERR) /* report the first encountered error */
11685
0
      status = lstatus;
11686
0
  }
11687
11688
0
  if (rndup != 0)
11689
0
  {
11690
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11691
0
    xp += X_SIZEOF_USHORT;
11692
0
  }
11693
11694
0
  *xpp = (void *)xp;
11695
0
  return status;
11696
0
}
11697
11698
int
11699
ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11700
0
{
11701
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11702
11703
0
  char *xp = (char *) *xpp;
11704
0
  int status = NC_NOERR;
11705
11706
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11707
0
  {
11708
0
    int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11709
0
    if (status == NC_NOERR) /* report the first encountered error */
11710
0
      status = lstatus;
11711
0
  }
11712
11713
0
  if (rndup != 0)
11714
0
  {
11715
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11716
0
    xp += X_SIZEOF_USHORT;
11717
0
  }
11718
11719
0
  *xpp = (void *)xp;
11720
0
  return status;
11721
0
}
11722
11723
int
11724
ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11725
0
{
11726
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11727
11728
0
  char *xp = (char *) *xpp;
11729
0
  int status = NC_NOERR;
11730
11731
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11732
0
  {
11733
0
    int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11734
0
    if (status == NC_NOERR) /* report the first encountered error */
11735
0
      status = lstatus;
11736
0
  }
11737
11738
0
  if (rndup != 0)
11739
0
  {
11740
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11741
0
    xp += X_SIZEOF_USHORT;
11742
0
  }
11743
11744
0
  *xpp = (void *)xp;
11745
0
  return status;
11746
0
}
11747
11748
int
11749
ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11750
0
{
11751
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11752
11753
0
  char *xp = (char *) *xpp;
11754
0
  int status = NC_NOERR;
11755
11756
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11757
0
  {
11758
0
    int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11759
0
    if (status == NC_NOERR) /* report the first encountered error */
11760
0
      status = lstatus;
11761
0
  }
11762
11763
0
  if (rndup != 0)
11764
0
  {
11765
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11766
0
    xp += X_SIZEOF_USHORT;
11767
0
  }
11768
11769
0
  *xpp = (void *)xp;
11770
0
  return status;
11771
0
}
11772
11773
int
11774
ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11775
0
{
11776
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11777
11778
0
  char *xp = (char *) *xpp;
11779
0
  int status = NC_NOERR;
11780
11781
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11782
0
  {
11783
0
    int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11784
0
    if (status == NC_NOERR) /* report the first encountered error */
11785
0
      status = lstatus;
11786
0
  }
11787
11788
0
  if (rndup != 0)
11789
0
  {
11790
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11791
0
    xp += X_SIZEOF_USHORT;
11792
0
  }
11793
11794
0
  *xpp = (void *)xp;
11795
0
  return status;
11796
0
}
11797
11798
int
11799
ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11800
0
{
11801
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11802
11803
0
  char *xp = (char *) *xpp;
11804
0
  int status = NC_NOERR;
11805
11806
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11807
0
  {
11808
0
    int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11809
0
    if (status == NC_NOERR) /* report the first encountered error */
11810
0
      status = lstatus;
11811
0
  }
11812
11813
0
  if (rndup != 0)
11814
0
  {
11815
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11816
0
    xp += X_SIZEOF_USHORT;
11817
0
  }
11818
11819
0
  *xpp = (void *)xp;
11820
0
  return status;
11821
0
}
11822
11823
int
11824
ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11825
0
{
11826
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11827
11828
0
  char *xp = (char *) *xpp;
11829
0
  int status = NC_NOERR;
11830
11831
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11832
0
  {
11833
0
    int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11834
0
    if (status == NC_NOERR) /* report the first encountered error */
11835
0
      status = lstatus;
11836
0
  }
11837
11838
0
  if (rndup != 0)
11839
0
  {
11840
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11841
0
    xp += X_SIZEOF_USHORT;
11842
0
  }
11843
11844
0
  *xpp = (void *)xp;
11845
0
  return status;
11846
0
}
11847
11848
int
11849
ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
11850
0
{
11851
0
  const size_t rndup = nelems % X_SIZEOF_SHORT;
11852
11853
0
  char *xp = (char *) *xpp;
11854
0
  int status = NC_NOERR;
11855
11856
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11857
0
  {
11858
0
    int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
11859
0
    if (status == NC_NOERR) /* report the first encountered error */
11860
0
      status = lstatus;
11861
0
  }
11862
11863
0
  if (rndup != 0)
11864
0
  {
11865
0
    (void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11866
0
    xp += X_SIZEOF_USHORT;
11867
0
  }
11868
11869
0
  *xpp = (void *)xp;
11870
0
  return status;
11871
0
}
11872
11873
11874
11875
/* int -----------------------------------------------------------------------*/
11876
11877
#if X_SIZEOF_INT == SIZEOF_INT
11878
/* optimized version */
11879
int
11880
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11881
41.5k
{
11882
#ifdef WORDS_BIGENDIAN
11883
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
11884
# else
11885
41.5k
  swapn4b(tp, *xpp, nelems);
11886
41.5k
# endif
11887
41.5k
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
11888
41.5k
  return NC_NOERR;
11889
41.5k
}
11890
#else
11891
int
11892
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11893
{
11894
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11895
11896
 /* basic algorithm is:
11897
  *   - ensure sane alignment of input data
11898
  *   - copy (conversion happens automatically) input data
11899
  *     to output
11900
  *   - update xpp to point at next unconverted input, and tp to point
11901
  *     at next location for converted output
11902
  */
11903
  long i, j, ni;
11904
  int tmp[LOOPCNT];        /* in case input is misaligned */
11905
  int *xp;
11906
  int nrange = 0;         /* number of range errors */
11907
  int realign = 0;        /* "do we need to fix input data alignment?" */
11908
  long cxp = (long) *((char**)xpp);
11909
11910
  realign = (cxp & 7) % SIZEOF_INT;
11911
  /* sjl: manually stripmine so we can limit amount of
11912
   * vector work space reserved to LOOPCNT elements. Also
11913
   * makes vectorisation easy */
11914
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11915
    ni=Min(nelems-j,LOOPCNT);
11916
    if (realign) {
11917
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11918
      xp = tmp;
11919
    } else {
11920
      xp = (int *) *xpp;
11921
    }
11922
   /* copy the next block */
11923
#pragma cdir loopcnt=LOOPCNT
11924
#pragma cdir shortloop
11925
    for (i=0; i<ni; i++) {
11926
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
11927
     /* test for range errors (not always needed but do it anyway) */
11928
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11929
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11930
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
11931
    }
11932
   /* update xpp and tp */
11933
    if (realign) xp = (int *) *xpp;
11934
    xp += ni;
11935
    tp += ni;
11936
    *xpp = (void*)xp;
11937
  }
11938
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
11939
11940
#else   /* not SX */
11941
  const char *xp = (const char *) *xpp;
11942
  int status = NC_NOERR;
11943
11944
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11945
  {
11946
    const int lstatus = ncx_get_int_int(xp, tp);
11947
    if (status == NC_NOERR) /* report the first encountered error */
11948
      status = lstatus;
11949
  }
11950
11951
  *xpp = (const void *)xp;
11952
  return status;
11953
#endif
11954
}
11955
11956
#endif
11957
int
11958
ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
11959
0
{
11960
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11961
11962
 /* basic algorithm is:
11963
  *   - ensure sane alignment of input data
11964
  *   - copy (conversion happens automatically) input data
11965
  *     to output
11966
  *   - update xpp to point at next unconverted input, and tp to point
11967
  *     at next location for converted output
11968
  */
11969
  long i, j, ni;
11970
  int tmp[LOOPCNT];        /* in case input is misaligned */
11971
  int *xp;
11972
  int nrange = 0;         /* number of range errors */
11973
  int realign = 0;        /* "do we need to fix input data alignment?" */
11974
  long cxp = (long) *((char**)xpp);
11975
11976
  realign = (cxp & 7) % SIZEOF_INT;
11977
  /* sjl: manually stripmine so we can limit amount of
11978
   * vector work space reserved to LOOPCNT elements. Also
11979
   * makes vectorisation easy */
11980
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11981
    ni=Min(nelems-j,LOOPCNT);
11982
    if (realign) {
11983
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11984
      xp = tmp;
11985
    } else {
11986
      xp = (int *) *xpp;
11987
    }
11988
   /* copy the next block */
11989
#pragma cdir loopcnt=LOOPCNT
11990
#pragma cdir shortloop
11991
    for (i=0; i<ni; i++) {
11992
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
11993
     /* test for range errors (not always needed but do it anyway) */
11994
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11995
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11996
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
11997
    }
11998
   /* update xpp and tp */
11999
    if (realign) xp = (int *) *xpp;
12000
    xp += ni;
12001
    tp += ni;
12002
    *xpp = (void*)xp;
12003
  }
12004
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12005
12006
#else   /* not SX */
12007
0
  const char *xp = (const char *) *xpp;
12008
0
  int status = NC_NOERR;
12009
12010
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12011
0
  {
12012
0
    const int lstatus = ncx_get_int_schar(xp, tp);
12013
0
    if (status == NC_NOERR) /* report the first encountered error */
12014
0
      status = lstatus;
12015
0
  }
12016
12017
0
  *xpp = (const void *)xp;
12018
0
  return status;
12019
0
#endif
12020
0
}
12021
12022
int
12023
ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
12024
0
{
12025
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12026
12027
 /* basic algorithm is:
12028
  *   - ensure sane alignment of input data
12029
  *   - copy (conversion happens automatically) input data
12030
  *     to output
12031
  *   - update xpp to point at next unconverted input, and tp to point
12032
  *     at next location for converted output
12033
  */
12034
  long i, j, ni;
12035
  int tmp[LOOPCNT];        /* in case input is misaligned */
12036
  int *xp;
12037
  int nrange = 0;         /* number of range errors */
12038
  int realign = 0;        /* "do we need to fix input data alignment?" */
12039
  long cxp = (long) *((char**)xpp);
12040
12041
  realign = (cxp & 7) % SIZEOF_INT;
12042
  /* sjl: manually stripmine so we can limit amount of
12043
   * vector work space reserved to LOOPCNT elements. Also
12044
   * makes vectorisation easy */
12045
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12046
    ni=Min(nelems-j,LOOPCNT);
12047
    if (realign) {
12048
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12049
      xp = tmp;
12050
    } else {
12051
      xp = (int *) *xpp;
12052
    }
12053
   /* copy the next block */
12054
#pragma cdir loopcnt=LOOPCNT
12055
#pragma cdir shortloop
12056
    for (i=0; i<ni; i++) {
12057
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
12058
     /* test for range errors (not always needed but do it anyway) */
12059
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12060
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12061
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
12062
    }
12063
   /* update xpp and tp */
12064
    if (realign) xp = (int *) *xpp;
12065
    xp += ni;
12066
    tp += ni;
12067
    *xpp = (void*)xp;
12068
  }
12069
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12070
12071
#else   /* not SX */
12072
0
  const char *xp = (const char *) *xpp;
12073
0
  int status = NC_NOERR;
12074
12075
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12076
0
  {
12077
0
    const int lstatus = ncx_get_int_short(xp, tp);
12078
0
    if (status == NC_NOERR) /* report the first encountered error */
12079
0
      status = lstatus;
12080
0
  }
12081
12082
0
  *xpp = (const void *)xp;
12083
0
  return status;
12084
0
#endif
12085
0
}
12086
12087
int
12088
ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
12089
0
{
12090
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12091
12092
 /* basic algorithm is:
12093
  *   - ensure sane alignment of input data
12094
  *   - copy (conversion happens automatically) input data
12095
  *     to output
12096
  *   - update xpp to point at next unconverted input, and tp to point
12097
  *     at next location for converted output
12098
  */
12099
  long i, j, ni;
12100
  int tmp[LOOPCNT];        /* in case input is misaligned */
12101
  int *xp;
12102
  int nrange = 0;         /* number of range errors */
12103
  int realign = 0;        /* "do we need to fix input data alignment?" */
12104
  long cxp = (long) *((char**)xpp);
12105
12106
  realign = (cxp & 7) % SIZEOF_INT;
12107
  /* sjl: manually stripmine so we can limit amount of
12108
   * vector work space reserved to LOOPCNT elements. Also
12109
   * makes vectorisation easy */
12110
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12111
    ni=Min(nelems-j,LOOPCNT);
12112
    if (realign) {
12113
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12114
      xp = tmp;
12115
    } else {
12116
      xp = (int *) *xpp;
12117
    }
12118
   /* copy the next block */
12119
#pragma cdir loopcnt=LOOPCNT
12120
#pragma cdir shortloop
12121
    for (i=0; i<ni; i++) {
12122
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
12123
     /* test for range errors (not always needed but do it anyway) */
12124
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12125
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12126
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
12127
    }
12128
   /* update xpp and tp */
12129
    if (realign) xp = (int *) *xpp;
12130
    xp += ni;
12131
    tp += ni;
12132
    *xpp = (void*)xp;
12133
  }
12134
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12135
12136
#else   /* not SX */
12137
0
  const char *xp = (const char *) *xpp;
12138
0
  int status = NC_NOERR;
12139
12140
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12141
0
  {
12142
0
    const int lstatus = ncx_get_int_long(xp, tp);
12143
0
    if (status == NC_NOERR) /* report the first encountered error */
12144
0
      status = lstatus;
12145
0
  }
12146
12147
0
  *xpp = (const void *)xp;
12148
0
  return status;
12149
0
#endif
12150
0
}
12151
12152
int
12153
ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
12154
0
{
12155
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12156
12157
 /* basic algorithm is:
12158
  *   - ensure sane alignment of input data
12159
  *   - copy (conversion happens automatically) input data
12160
  *     to output
12161
  *   - update xpp to point at next unconverted input, and tp to point
12162
  *     at next location for converted output
12163
  */
12164
  long i, j, ni;
12165
  int tmp[LOOPCNT];        /* in case input is misaligned */
12166
  int *xp;
12167
  int nrange = 0;         /* number of range errors */
12168
  int realign = 0;        /* "do we need to fix input data alignment?" */
12169
  long cxp = (long) *((char**)xpp);
12170
12171
  realign = (cxp & 7) % SIZEOF_INT;
12172
  /* sjl: manually stripmine so we can limit amount of
12173
   * vector work space reserved to LOOPCNT elements. Also
12174
   * makes vectorisation easy */
12175
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12176
    ni=Min(nelems-j,LOOPCNT);
12177
    if (realign) {
12178
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12179
      xp = tmp;
12180
    } else {
12181
      xp = (int *) *xpp;
12182
    }
12183
   /* copy the next block */
12184
#pragma cdir loopcnt=LOOPCNT
12185
#pragma cdir shortloop
12186
    for (i=0; i<ni; i++) {
12187
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
12188
     /* test for range errors (not always needed but do it anyway) */
12189
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12190
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12191
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
12192
    }
12193
   /* update xpp and tp */
12194
    if (realign) xp = (int *) *xpp;
12195
    xp += ni;
12196
    tp += ni;
12197
    *xpp = (void*)xp;
12198
  }
12199
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12200
12201
#else   /* not SX */
12202
0
  const char *xp = (const char *) *xpp;
12203
0
  int status = NC_NOERR;
12204
12205
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12206
0
  {
12207
0
    const int lstatus = ncx_get_int_float(xp, tp);
12208
0
    if (status == NC_NOERR) /* report the first encountered error */
12209
0
      status = lstatus;
12210
0
  }
12211
12212
0
  *xpp = (const void *)xp;
12213
0
  return status;
12214
0
#endif
12215
0
}
12216
12217
int
12218
ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
12219
0
{
12220
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12221
12222
 /* basic algorithm is:
12223
  *   - ensure sane alignment of input data
12224
  *   - copy (conversion happens automatically) input data
12225
  *     to output
12226
  *   - update xpp to point at next unconverted input, and tp to point
12227
  *     at next location for converted output
12228
  */
12229
  long i, j, ni;
12230
  int tmp[LOOPCNT];        /* in case input is misaligned */
12231
  int *xp;
12232
  int nrange = 0;         /* number of range errors */
12233
  int realign = 0;        /* "do we need to fix input data alignment?" */
12234
  long cxp = (long) *((char**)xpp);
12235
12236
  realign = (cxp & 7) % SIZEOF_INT;
12237
  /* sjl: manually stripmine so we can limit amount of
12238
   * vector work space reserved to LOOPCNT elements. Also
12239
   * makes vectorisation easy */
12240
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12241
    ni=Min(nelems-j,LOOPCNT);
12242
    if (realign) {
12243
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12244
      xp = tmp;
12245
    } else {
12246
      xp = (int *) *xpp;
12247
    }
12248
   /* copy the next block */
12249
#pragma cdir loopcnt=LOOPCNT
12250
#pragma cdir shortloop
12251
    for (i=0; i<ni; i++) {
12252
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
12253
     /* test for range errors (not always needed but do it anyway) */
12254
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12255
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12256
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
12257
    }
12258
   /* update xpp and tp */
12259
    if (realign) xp = (int *) *xpp;
12260
    xp += ni;
12261
    tp += ni;
12262
    *xpp = (void*)xp;
12263
  }
12264
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12265
12266
#else   /* not SX */
12267
0
  const char *xp = (const char *) *xpp;
12268
0
  int status = NC_NOERR;
12269
12270
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12271
0
  {
12272
0
    const int lstatus = ncx_get_int_double(xp, tp);
12273
0
    if (status == NC_NOERR) /* report the first encountered error */
12274
0
      status = lstatus;
12275
0
  }
12276
12277
0
  *xpp = (const void *)xp;
12278
0
  return status;
12279
0
#endif
12280
0
}
12281
12282
int
12283
ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp)
12284
0
{
12285
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12286
12287
 /* basic algorithm is:
12288
  *   - ensure sane alignment of input data
12289
  *   - copy (conversion happens automatically) input data
12290
  *     to output
12291
  *   - update xpp to point at next unconverted input, and tp to point
12292
  *     at next location for converted output
12293
  */
12294
  long i, j, ni;
12295
  int tmp[LOOPCNT];        /* in case input is misaligned */
12296
  int *xp;
12297
  int nrange = 0;         /* number of range errors */
12298
  int realign = 0;        /* "do we need to fix input data alignment?" */
12299
  long cxp = (long) *((char**)xpp);
12300
12301
  realign = (cxp & 7) % SIZEOF_INT;
12302
  /* sjl: manually stripmine so we can limit amount of
12303
   * vector work space reserved to LOOPCNT elements. Also
12304
   * makes vectorisation easy */
12305
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12306
    ni=Min(nelems-j,LOOPCNT);
12307
    if (realign) {
12308
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12309
      xp = tmp;
12310
    } else {
12311
      xp = (int *) *xpp;
12312
    }
12313
   /* copy the next block */
12314
#pragma cdir loopcnt=LOOPCNT
12315
#pragma cdir shortloop
12316
    for (i=0; i<ni; i++) {
12317
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
12318
     /* test for range errors (not always needed but do it anyway) */
12319
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12320
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12321
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
12322
    }
12323
   /* update xpp and tp */
12324
    if (realign) xp = (int *) *xpp;
12325
    xp += ni;
12326
    tp += ni;
12327
    *xpp = (void*)xp;
12328
  }
12329
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12330
12331
#else   /* not SX */
12332
0
  const char *xp = (const char *) *xpp;
12333
0
  int status = NC_NOERR;
12334
12335
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12336
0
  {
12337
0
    const int lstatus = ncx_get_int_longlong(xp, tp);
12338
0
    if (status == NC_NOERR) /* report the first encountered error */
12339
0
      status = lstatus;
12340
0
  }
12341
12342
0
  *xpp = (const void *)xp;
12343
0
  return status;
12344
0
#endif
12345
0
}
12346
12347
int
12348
ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
12349
0
{
12350
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12351
12352
 /* basic algorithm is:
12353
  *   - ensure sane alignment of input data
12354
  *   - copy (conversion happens automatically) input data
12355
  *     to output
12356
  *   - update xpp to point at next unconverted input, and tp to point
12357
  *     at next location for converted output
12358
  */
12359
  long i, j, ni;
12360
  int tmp[LOOPCNT];        /* in case input is misaligned */
12361
  int *xp;
12362
  int nrange = 0;         /* number of range errors */
12363
  int realign = 0;        /* "do we need to fix input data alignment?" */
12364
  long cxp = (long) *((char**)xpp);
12365
12366
  realign = (cxp & 7) % SIZEOF_INT;
12367
  /* sjl: manually stripmine so we can limit amount of
12368
   * vector work space reserved to LOOPCNT elements. Also
12369
   * makes vectorisation easy */
12370
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12371
    ni=Min(nelems-j,LOOPCNT);
12372
    if (realign) {
12373
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12374
      xp = tmp;
12375
    } else {
12376
      xp = (int *) *xpp;
12377
    }
12378
   /* copy the next block */
12379
#pragma cdir loopcnt=LOOPCNT
12380
#pragma cdir shortloop
12381
    for (i=0; i<ni; i++) {
12382
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
12383
     /* test for range errors (not always needed but do it anyway) */
12384
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12385
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12386
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
12387
    }
12388
   /* update xpp and tp */
12389
    if (realign) xp = (int *) *xpp;
12390
    xp += ni;
12391
    tp += ni;
12392
    *xpp = (void*)xp;
12393
  }
12394
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12395
12396
#else   /* not SX */
12397
0
  const char *xp = (const char *) *xpp;
12398
0
  int status = NC_NOERR;
12399
12400
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12401
0
  {
12402
0
    const int lstatus = ncx_get_int_uchar(xp, tp);
12403
0
    if (status == NC_NOERR) /* report the first encountered error */
12404
0
      status = lstatus;
12405
0
  }
12406
12407
0
  *xpp = (const void *)xp;
12408
0
  return status;
12409
0
#endif
12410
0
}
12411
12412
int
12413
ncx_getn_int_ushort(const void **xpp, size_t nelems, ushort *tp)
12414
0
{
12415
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12416
12417
 /* basic algorithm is:
12418
  *   - ensure sane alignment of input data
12419
  *   - copy (conversion happens automatically) input data
12420
  *     to output
12421
  *   - update xpp to point at next unconverted input, and tp to point
12422
  *     at next location for converted output
12423
  */
12424
  long i, j, ni;
12425
  int tmp[LOOPCNT];        /* in case input is misaligned */
12426
  int *xp;
12427
  int nrange = 0;         /* number of range errors */
12428
  int realign = 0;        /* "do we need to fix input data alignment?" */
12429
  long cxp = (long) *((char**)xpp);
12430
12431
  realign = (cxp & 7) % SIZEOF_INT;
12432
  /* sjl: manually stripmine so we can limit amount of
12433
   * vector work space reserved to LOOPCNT elements. Also
12434
   * makes vectorisation easy */
12435
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12436
    ni=Min(nelems-j,LOOPCNT);
12437
    if (realign) {
12438
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12439
      xp = tmp;
12440
    } else {
12441
      xp = (int *) *xpp;
12442
    }
12443
   /* copy the next block */
12444
#pragma cdir loopcnt=LOOPCNT
12445
#pragma cdir shortloop
12446
    for (i=0; i<ni; i++) {
12447
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
12448
     /* test for range errors (not always needed but do it anyway) */
12449
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12450
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12451
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
12452
    }
12453
   /* update xpp and tp */
12454
    if (realign) xp = (int *) *xpp;
12455
    xp += ni;
12456
    tp += ni;
12457
    *xpp = (void*)xp;
12458
  }
12459
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12460
12461
#else   /* not SX */
12462
0
  const char *xp = (const char *) *xpp;
12463
0
  int status = NC_NOERR;
12464
12465
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12466
0
  {
12467
0
    const int lstatus = ncx_get_int_ushort(xp, tp);
12468
0
    if (status == NC_NOERR) /* report the first encountered error */
12469
0
      status = lstatus;
12470
0
  }
12471
12472
0
  *xpp = (const void *)xp;
12473
0
  return status;
12474
0
#endif
12475
0
}
12476
12477
int
12478
ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp)
12479
0
{
12480
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12481
12482
 /* basic algorithm is:
12483
  *   - ensure sane alignment of input data
12484
  *   - copy (conversion happens automatically) input data
12485
  *     to output
12486
  *   - update xpp to point at next unconverted input, and tp to point
12487
  *     at next location for converted output
12488
  */
12489
  long i, j, ni;
12490
  int tmp[LOOPCNT];        /* in case input is misaligned */
12491
  int *xp;
12492
  int nrange = 0;         /* number of range errors */
12493
  int realign = 0;        /* "do we need to fix input data alignment?" */
12494
  long cxp = (long) *((char**)xpp);
12495
12496
  realign = (cxp & 7) % SIZEOF_INT;
12497
  /* sjl: manually stripmine so we can limit amount of
12498
   * vector work space reserved to LOOPCNT elements. Also
12499
   * makes vectorisation easy */
12500
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12501
    ni=Min(nelems-j,LOOPCNT);
12502
    if (realign) {
12503
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12504
      xp = tmp;
12505
    } else {
12506
      xp = (int *) *xpp;
12507
    }
12508
   /* copy the next block */
12509
#pragma cdir loopcnt=LOOPCNT
12510
#pragma cdir shortloop
12511
    for (i=0; i<ni; i++) {
12512
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
12513
     /* test for range errors (not always needed but do it anyway) */
12514
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12515
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12516
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
12517
    }
12518
   /* update xpp and tp */
12519
    if (realign) xp = (int *) *xpp;
12520
    xp += ni;
12521
    tp += ni;
12522
    *xpp = (void*)xp;
12523
  }
12524
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12525
12526
#else   /* not SX */
12527
0
  const char *xp = (const char *) *xpp;
12528
0
  int status = NC_NOERR;
12529
12530
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12531
0
  {
12532
0
    const int lstatus = ncx_get_int_uint(xp, tp);
12533
0
    if (status == NC_NOERR) /* report the first encountered error */
12534
0
      status = lstatus;
12535
0
  }
12536
12537
0
  *xpp = (const void *)xp;
12538
0
  return status;
12539
0
#endif
12540
0
}
12541
12542
int
12543
ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
12544
0
{
12545
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12546
12547
 /* basic algorithm is:
12548
  *   - ensure sane alignment of input data
12549
  *   - copy (conversion happens automatically) input data
12550
  *     to output
12551
  *   - update xpp to point at next unconverted input, and tp to point
12552
  *     at next location for converted output
12553
  */
12554
  long i, j, ni;
12555
  int tmp[LOOPCNT];        /* in case input is misaligned */
12556
  int *xp;
12557
  int nrange = 0;         /* number of range errors */
12558
  int realign = 0;        /* "do we need to fix input data alignment?" */
12559
  long cxp = (long) *((char**)xpp);
12560
12561
  realign = (cxp & 7) % SIZEOF_INT;
12562
  /* sjl: manually stripmine so we can limit amount of
12563
   * vector work space reserved to LOOPCNT elements. Also
12564
   * makes vectorisation easy */
12565
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12566
    ni=Min(nelems-j,LOOPCNT);
12567
    if (realign) {
12568
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12569
      xp = tmp;
12570
    } else {
12571
      xp = (int *) *xpp;
12572
    }
12573
   /* copy the next block */
12574
#pragma cdir loopcnt=LOOPCNT
12575
#pragma cdir shortloop
12576
    for (i=0; i<ni; i++) {
12577
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
12578
     /* test for range errors (not always needed but do it anyway) */
12579
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12580
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12581
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
12582
    }
12583
   /* update xpp and tp */
12584
    if (realign) xp = (int *) *xpp;
12585
    xp += ni;
12586
    tp += ni;
12587
    *xpp = (void*)xp;
12588
  }
12589
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12590
12591
#else   /* not SX */
12592
0
  const char *xp = (const char *) *xpp;
12593
0
  int status = NC_NOERR;
12594
12595
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12596
0
  {
12597
0
    const int lstatus = ncx_get_int_ulonglong(xp, tp);
12598
0
    if (status == NC_NOERR) /* report the first encountered error */
12599
0
      status = lstatus;
12600
0
  }
12601
12602
0
  *xpp = (const void *)xp;
12603
0
  return status;
12604
0
#endif
12605
0
}
12606
12607
12608
#if X_SIZEOF_INT == SIZEOF_INT
12609
/* optimized version */
12610
int
12611
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12612
0
{
12613
#ifdef WORDS_BIGENDIAN
12614
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
12615
# else
12616
0
  swapn4b(*xpp, tp, nelems);
12617
0
# endif
12618
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
12619
0
  return NC_NOERR;
12620
0
}
12621
#else
12622
int
12623
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12624
{
12625
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12626
12627
 /* basic algorithm is:
12628
  *   - ensure sane alignment of output data
12629
  *   - copy (conversion happens automatically) input data
12630
  *     to output
12631
  *   - update tp to point at next unconverted input, and xpp to point
12632
  *     at next location for converted output
12633
  */
12634
  long i, j, ni;
12635
  int tmp[LOOPCNT];        /* in case input is misaligned */
12636
  int *xp;
12637
  int nrange = 0;         /* number of range errors */
12638
  int realign = 0;        /* "do we need to fix input data alignment?" */
12639
  long cxp = (long) *((char**)xpp);
12640
12641
  realign = (cxp & 7) % SIZEOF_INT;
12642
  /* sjl: manually stripmine so we can limit amount of
12643
   * vector work space reserved to LOOPCNT elements. Also
12644
   * makes vectorisation easy */
12645
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12646
    ni=Min(nelems-j,LOOPCNT);
12647
    if (realign) {
12648
      xp = tmp;
12649
    } else {
12650
      xp = (int *) *xpp;
12651
    }
12652
   /* copy the next block */
12653
#pragma cdir loopcnt=LOOPCNT
12654
#pragma cdir shortloop
12655
    for (i=0; i<ni; i++) {
12656
      /* the normal case: */
12657
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12658
     /* test for range errors (not always needed but do it anyway) */
12659
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12660
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12661
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12662
    }
12663
   /* copy workspace back if necessary */
12664
    if (realign) {
12665
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12666
      xp = (int *) *xpp;
12667
    }
12668
   /* update xpp and tp */
12669
    xp += ni;
12670
    tp += ni;
12671
    *xpp = (void*)xp;
12672
  }
12673
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12674
12675
#else   /* not SX */
12676
12677
  char *xp = (char *) *xpp;
12678
  int status = NC_NOERR;
12679
12680
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12681
  {
12682
    int lstatus = ncx_put_int_int(xp, tp, fillp);
12683
    if (status == NC_NOERR) /* report the first encountered error */
12684
      status = lstatus;
12685
  }
12686
12687
  *xpp = (void *)xp;
12688
  return status;
12689
#endif
12690
}
12691
12692
#endif
12693
int
12694
ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
12695
0
{
12696
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12697
12698
 /* basic algorithm is:
12699
  *   - ensure sane alignment of output data
12700
  *   - copy (conversion happens automatically) input data
12701
  *     to output
12702
  *   - update tp to point at next unconverted input, and xpp to point
12703
  *     at next location for converted output
12704
  */
12705
  long i, j, ni;
12706
  int tmp[LOOPCNT];        /* in case input is misaligned */
12707
  int *xp;
12708
  int nrange = 0;         /* number of range errors */
12709
  int realign = 0;        /* "do we need to fix input data alignment?" */
12710
  long cxp = (long) *((char**)xpp);
12711
12712
  realign = (cxp & 7) % SIZEOF_INT;
12713
  /* sjl: manually stripmine so we can limit amount of
12714
   * vector work space reserved to LOOPCNT elements. Also
12715
   * makes vectorisation easy */
12716
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12717
    ni=Min(nelems-j,LOOPCNT);
12718
    if (realign) {
12719
      xp = tmp;
12720
    } else {
12721
      xp = (int *) *xpp;
12722
    }
12723
   /* copy the next block */
12724
#pragma cdir loopcnt=LOOPCNT
12725
#pragma cdir shortloop
12726
    for (i=0; i<ni; i++) {
12727
      /* the normal case: */
12728
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12729
     /* test for range errors (not always needed but do it anyway) */
12730
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12731
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12732
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12733
    }
12734
   /* copy workspace back if necessary */
12735
    if (realign) {
12736
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12737
      xp = (int *) *xpp;
12738
    }
12739
   /* update xpp and tp */
12740
    xp += ni;
12741
    tp += ni;
12742
    *xpp = (void*)xp;
12743
  }
12744
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12745
12746
#else   /* not SX */
12747
12748
0
  char *xp = (char *) *xpp;
12749
0
  int status = NC_NOERR;
12750
12751
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12752
0
  {
12753
0
    int lstatus = ncx_put_int_schar(xp, tp, fillp);
12754
0
    if (status == NC_NOERR) /* report the first encountered error */
12755
0
      status = lstatus;
12756
0
  }
12757
12758
0
  *xpp = (void *)xp;
12759
0
  return status;
12760
0
#endif
12761
0
}
12762
12763
int
12764
ncx_putn_int_short(void **xpp, size_t nelems, const short *tp, void *fillp)
12765
0
{
12766
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12767
12768
 /* basic algorithm is:
12769
  *   - ensure sane alignment of output data
12770
  *   - copy (conversion happens automatically) input data
12771
  *     to output
12772
  *   - update tp to point at next unconverted input, and xpp to point
12773
  *     at next location for converted output
12774
  */
12775
  long i, j, ni;
12776
  int tmp[LOOPCNT];        /* in case input is misaligned */
12777
  int *xp;
12778
  int nrange = 0;         /* number of range errors */
12779
  int realign = 0;        /* "do we need to fix input data alignment?" */
12780
  long cxp = (long) *((char**)xpp);
12781
12782
  realign = (cxp & 7) % SIZEOF_INT;
12783
  /* sjl: manually stripmine so we can limit amount of
12784
   * vector work space reserved to LOOPCNT elements. Also
12785
   * makes vectorisation easy */
12786
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12787
    ni=Min(nelems-j,LOOPCNT);
12788
    if (realign) {
12789
      xp = tmp;
12790
    } else {
12791
      xp = (int *) *xpp;
12792
    }
12793
   /* copy the next block */
12794
#pragma cdir loopcnt=LOOPCNT
12795
#pragma cdir shortloop
12796
    for (i=0; i<ni; i++) {
12797
      /* the normal case: */
12798
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12799
     /* test for range errors (not always needed but do it anyway) */
12800
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12801
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12802
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12803
    }
12804
   /* copy workspace back if necessary */
12805
    if (realign) {
12806
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12807
      xp = (int *) *xpp;
12808
    }
12809
   /* update xpp and tp */
12810
    xp += ni;
12811
    tp += ni;
12812
    *xpp = (void*)xp;
12813
  }
12814
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12815
12816
#else   /* not SX */
12817
12818
0
  char *xp = (char *) *xpp;
12819
0
  int status = NC_NOERR;
12820
12821
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12822
0
  {
12823
0
    int lstatus = ncx_put_int_short(xp, tp, fillp);
12824
0
    if (status == NC_NOERR) /* report the first encountered error */
12825
0
      status = lstatus;
12826
0
  }
12827
12828
0
  *xpp = (void *)xp;
12829
0
  return status;
12830
0
#endif
12831
0
}
12832
12833
int
12834
ncx_putn_int_long(void **xpp, size_t nelems, const long *tp, void *fillp)
12835
0
{
12836
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12837
12838
 /* basic algorithm is:
12839
  *   - ensure sane alignment of output data
12840
  *   - copy (conversion happens automatically) input data
12841
  *     to output
12842
  *   - update tp to point at next unconverted input, and xpp to point
12843
  *     at next location for converted output
12844
  */
12845
  long i, j, ni;
12846
  int tmp[LOOPCNT];        /* in case input is misaligned */
12847
  int *xp;
12848
  int nrange = 0;         /* number of range errors */
12849
  int realign = 0;        /* "do we need to fix input data alignment?" */
12850
  long cxp = (long) *((char**)xpp);
12851
12852
  realign = (cxp & 7) % SIZEOF_INT;
12853
  /* sjl: manually stripmine so we can limit amount of
12854
   * vector work space reserved to LOOPCNT elements. Also
12855
   * makes vectorisation easy */
12856
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12857
    ni=Min(nelems-j,LOOPCNT);
12858
    if (realign) {
12859
      xp = tmp;
12860
    } else {
12861
      xp = (int *) *xpp;
12862
    }
12863
   /* copy the next block */
12864
#pragma cdir loopcnt=LOOPCNT
12865
#pragma cdir shortloop
12866
    for (i=0; i<ni; i++) {
12867
      /* the normal case: */
12868
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12869
     /* test for range errors (not always needed but do it anyway) */
12870
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12871
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12872
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12873
    }
12874
   /* copy workspace back if necessary */
12875
    if (realign) {
12876
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12877
      xp = (int *) *xpp;
12878
    }
12879
   /* update xpp and tp */
12880
    xp += ni;
12881
    tp += ni;
12882
    *xpp = (void*)xp;
12883
  }
12884
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12885
12886
#else   /* not SX */
12887
12888
0
  char *xp = (char *) *xpp;
12889
0
  int status = NC_NOERR;
12890
12891
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12892
0
  {
12893
0
    int lstatus = ncx_put_int_long(xp, tp, fillp);
12894
0
    if (status == NC_NOERR) /* report the first encountered error */
12895
0
      status = lstatus;
12896
0
  }
12897
12898
0
  *xpp = (void *)xp;
12899
0
  return status;
12900
0
#endif
12901
0
}
12902
12903
int
12904
ncx_putn_int_float(void **xpp, size_t nelems, const float *tp, void *fillp)
12905
0
{
12906
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12907
12908
 /* basic algorithm is:
12909
  *   - ensure sane alignment of output data
12910
  *   - copy (conversion happens automatically) input data
12911
  *     to output
12912
  *   - update tp to point at next unconverted input, and xpp to point
12913
  *     at next location for converted output
12914
  */
12915
  long i, j, ni;
12916
  int tmp[LOOPCNT];        /* in case input is misaligned */
12917
  int *xp;
12918
  double d;               /* special case for ncx_putn_int_float */
12919
  int nrange = 0;         /* number of range errors */
12920
  int realign = 0;        /* "do we need to fix input data alignment?" */
12921
  long cxp = (long) *((char**)xpp);
12922
12923
  realign = (cxp & 7) % SIZEOF_INT;
12924
  /* sjl: manually stripmine so we can limit amount of
12925
   * vector work space reserved to LOOPCNT elements. Also
12926
   * makes vectorisation easy */
12927
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12928
    ni=Min(nelems-j,LOOPCNT);
12929
    if (realign) {
12930
      xp = tmp;
12931
    } else {
12932
      xp = (int *) *xpp;
12933
    }
12934
   /* copy the next block */
12935
#pragma cdir loopcnt=LOOPCNT
12936
#pragma cdir shortloop
12937
    for (i=0; i<ni; i++) {
12938
      /* for some reason int to float, for putn, requires a special case */
12939
      d = tp[i];
12940
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
12941
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12942
    }
12943
   /* copy workspace back if necessary */
12944
    if (realign) {
12945
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12946
      xp = (int *) *xpp;
12947
    }
12948
   /* update xpp and tp */
12949
    xp += ni;
12950
    tp += ni;
12951
    *xpp = (void*)xp;
12952
  }
12953
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
12954
12955
#else   /* not SX */
12956
12957
0
  char *xp = (char *) *xpp;
12958
0
  int status = NC_NOERR;
12959
12960
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12961
0
  {
12962
0
    int lstatus = ncx_put_int_float(xp, tp, fillp);
12963
0
    if (status == NC_NOERR) /* report the first encountered error */
12964
0
      status = lstatus;
12965
0
  }
12966
12967
0
  *xpp = (void *)xp;
12968
0
  return status;
12969
0
#endif
12970
0
}
12971
12972
int
12973
ncx_putn_int_double(void **xpp, size_t nelems, const double *tp, void *fillp)
12974
0
{
12975
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12976
12977
 /* basic algorithm is:
12978
  *   - ensure sane alignment of output data
12979
  *   - copy (conversion happens automatically) input data
12980
  *     to output
12981
  *   - update tp to point at next unconverted input, and xpp to point
12982
  *     at next location for converted output
12983
  */
12984
  long i, j, ni;
12985
  int tmp[LOOPCNT];        /* in case input is misaligned */
12986
  int *xp;
12987
  int nrange = 0;         /* number of range errors */
12988
  int realign = 0;        /* "do we need to fix input data alignment?" */
12989
  long cxp = (long) *((char**)xpp);
12990
12991
  realign = (cxp & 7) % SIZEOF_INT;
12992
  /* sjl: manually stripmine so we can limit amount of
12993
   * vector work space reserved to LOOPCNT elements. Also
12994
   * makes vectorisation easy */
12995
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12996
    ni=Min(nelems-j,LOOPCNT);
12997
    if (realign) {
12998
      xp = tmp;
12999
    } else {
13000
      xp = (int *) *xpp;
13001
    }
13002
   /* copy the next block */
13003
#pragma cdir loopcnt=LOOPCNT
13004
#pragma cdir shortloop
13005
    for (i=0; i<ni; i++) {
13006
      /* the normal case: */
13007
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13008
     /* test for range errors (not always needed but do it anyway) */
13009
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13010
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13011
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
13012
    }
13013
   /* copy workspace back if necessary */
13014
    if (realign) {
13015
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13016
      xp = (int *) *xpp;
13017
    }
13018
   /* update xpp and tp */
13019
    xp += ni;
13020
    tp += ni;
13021
    *xpp = (void*)xp;
13022
  }
13023
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13024
13025
#else   /* not SX */
13026
13027
0
  char *xp = (char *) *xpp;
13028
0
  int status = NC_NOERR;
13029
13030
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13031
0
  {
13032
0
    int lstatus = ncx_put_int_double(xp, tp, fillp);
13033
0
    if (status == NC_NOERR) /* report the first encountered error */
13034
0
      status = lstatus;
13035
0
  }
13036
13037
0
  *xpp = (void *)xp;
13038
0
  return status;
13039
0
#endif
13040
0
}
13041
13042
int
13043
ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
13044
0
{
13045
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13046
13047
 /* basic algorithm is:
13048
  *   - ensure sane alignment of output data
13049
  *   - copy (conversion happens automatically) input data
13050
  *     to output
13051
  *   - update tp to point at next unconverted input, and xpp to point
13052
  *     at next location for converted output
13053
  */
13054
  long i, j, ni;
13055
  int tmp[LOOPCNT];        /* in case input is misaligned */
13056
  int *xp;
13057
  int nrange = 0;         /* number of range errors */
13058
  int realign = 0;        /* "do we need to fix input data alignment?" */
13059
  long cxp = (long) *((char**)xpp);
13060
13061
  realign = (cxp & 7) % SIZEOF_INT;
13062
  /* sjl: manually stripmine so we can limit amount of
13063
   * vector work space reserved to LOOPCNT elements. Also
13064
   * makes vectorisation easy */
13065
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13066
    ni=Min(nelems-j,LOOPCNT);
13067
    if (realign) {
13068
      xp = tmp;
13069
    } else {
13070
      xp = (int *) *xpp;
13071
    }
13072
   /* copy the next block */
13073
#pragma cdir loopcnt=LOOPCNT
13074
#pragma cdir shortloop
13075
    for (i=0; i<ni; i++) {
13076
      /* the normal case: */
13077
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13078
     /* test for range errors (not always needed but do it anyway) */
13079
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13080
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13081
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
13082
    }
13083
   /* copy workspace back if necessary */
13084
    if (realign) {
13085
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13086
      xp = (int *) *xpp;
13087
    }
13088
   /* update xpp and tp */
13089
    xp += ni;
13090
    tp += ni;
13091
    *xpp = (void*)xp;
13092
  }
13093
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13094
13095
#else   /* not SX */
13096
13097
0
  char *xp = (char *) *xpp;
13098
0
  int status = NC_NOERR;
13099
13100
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13101
0
  {
13102
0
    int lstatus = ncx_put_int_longlong(xp, tp, fillp);
13103
0
    if (status == NC_NOERR) /* report the first encountered error */
13104
0
      status = lstatus;
13105
0
  }
13106
13107
0
  *xpp = (void *)xp;
13108
0
  return status;
13109
0
#endif
13110
0
}
13111
13112
int
13113
ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
13114
0
{
13115
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13116
13117
 /* basic algorithm is:
13118
  *   - ensure sane alignment of output data
13119
  *   - copy (conversion happens automatically) input data
13120
  *     to output
13121
  *   - update tp to point at next unconverted input, and xpp to point
13122
  *     at next location for converted output
13123
  */
13124
  long i, j, ni;
13125
  int tmp[LOOPCNT];        /* in case input is misaligned */
13126
  int *xp;
13127
  int nrange = 0;         /* number of range errors */
13128
  int realign = 0;        /* "do we need to fix input data alignment?" */
13129
  long cxp = (long) *((char**)xpp);
13130
13131
  realign = (cxp & 7) % SIZEOF_INT;
13132
  /* sjl: manually stripmine so we can limit amount of
13133
   * vector work space reserved to LOOPCNT elements. Also
13134
   * makes vectorisation easy */
13135
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13136
    ni=Min(nelems-j,LOOPCNT);
13137
    if (realign) {
13138
      xp = tmp;
13139
    } else {
13140
      xp = (int *) *xpp;
13141
    }
13142
   /* copy the next block */
13143
#pragma cdir loopcnt=LOOPCNT
13144
#pragma cdir shortloop
13145
    for (i=0; i<ni; i++) {
13146
      /* the normal case: */
13147
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13148
     /* test for range errors (not always needed but do it anyway) */
13149
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13150
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13151
      nrange += tp[i] > X_INT_MAX ;
13152
    }
13153
   /* copy workspace back if necessary */
13154
    if (realign) {
13155
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13156
      xp = (int *) *xpp;
13157
    }
13158
   /* update xpp and tp */
13159
    xp += ni;
13160
    tp += ni;
13161
    *xpp = (void*)xp;
13162
  }
13163
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13164
13165
#else   /* not SX */
13166
13167
0
  char *xp = (char *) *xpp;
13168
0
  int status = NC_NOERR;
13169
13170
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13171
0
  {
13172
0
    int lstatus = ncx_put_int_uchar(xp, tp, fillp);
13173
0
    if (status == NC_NOERR) /* report the first encountered error */
13174
0
      status = lstatus;
13175
0
  }
13176
13177
0
  *xpp = (void *)xp;
13178
0
  return status;
13179
0
#endif
13180
0
}
13181
13182
int
13183
ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
13184
0
{
13185
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13186
13187
 /* basic algorithm is:
13188
  *   - ensure sane alignment of output data
13189
  *   - copy (conversion happens automatically) input data
13190
  *     to output
13191
  *   - update tp to point at next unconverted input, and xpp to point
13192
  *     at next location for converted output
13193
  */
13194
  long i, j, ni;
13195
  int tmp[LOOPCNT];        /* in case input is misaligned */
13196
  int *xp;
13197
  int nrange = 0;         /* number of range errors */
13198
  int realign = 0;        /* "do we need to fix input data alignment?" */
13199
  long cxp = (long) *((char**)xpp);
13200
13201
  realign = (cxp & 7) % SIZEOF_INT;
13202
  /* sjl: manually stripmine so we can limit amount of
13203
   * vector work space reserved to LOOPCNT elements. Also
13204
   * makes vectorisation easy */
13205
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13206
    ni=Min(nelems-j,LOOPCNT);
13207
    if (realign) {
13208
      xp = tmp;
13209
    } else {
13210
      xp = (int *) *xpp;
13211
    }
13212
   /* copy the next block */
13213
#pragma cdir loopcnt=LOOPCNT
13214
#pragma cdir shortloop
13215
    for (i=0; i<ni; i++) {
13216
      /* the normal case: */
13217
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13218
     /* test for range errors (not always needed but do it anyway) */
13219
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13220
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13221
      nrange += tp[i] > X_INT_MAX ;
13222
    }
13223
   /* copy workspace back if necessary */
13224
    if (realign) {
13225
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13226
      xp = (int *) *xpp;
13227
    }
13228
   /* update xpp and tp */
13229
    xp += ni;
13230
    tp += ni;
13231
    *xpp = (void*)xp;
13232
  }
13233
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13234
13235
#else   /* not SX */
13236
13237
0
  char *xp = (char *) *xpp;
13238
0
  int status = NC_NOERR;
13239
13240
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13241
0
  {
13242
0
    int lstatus = ncx_put_int_ushort(xp, tp, fillp);
13243
0
    if (status == NC_NOERR) /* report the first encountered error */
13244
0
      status = lstatus;
13245
0
  }
13246
13247
0
  *xpp = (void *)xp;
13248
0
  return status;
13249
0
#endif
13250
0
}
13251
13252
int
13253
ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13254
0
{
13255
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13256
13257
 /* basic algorithm is:
13258
  *   - ensure sane alignment of output data
13259
  *   - copy (conversion happens automatically) input data
13260
  *     to output
13261
  *   - update tp to point at next unconverted input, and xpp to point
13262
  *     at next location for converted output
13263
  */
13264
  long i, j, ni;
13265
  int tmp[LOOPCNT];        /* in case input is misaligned */
13266
  int *xp;
13267
  int nrange = 0;         /* number of range errors */
13268
  int realign = 0;        /* "do we need to fix input data alignment?" */
13269
  long cxp = (long) *((char**)xpp);
13270
13271
  realign = (cxp & 7) % SIZEOF_INT;
13272
  /* sjl: manually stripmine so we can limit amount of
13273
   * vector work space reserved to LOOPCNT elements. Also
13274
   * makes vectorisation easy */
13275
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13276
    ni=Min(nelems-j,LOOPCNT);
13277
    if (realign) {
13278
      xp = tmp;
13279
    } else {
13280
      xp = (int *) *xpp;
13281
    }
13282
   /* copy the next block */
13283
#pragma cdir loopcnt=LOOPCNT
13284
#pragma cdir shortloop
13285
    for (i=0; i<ni; i++) {
13286
      /* the normal case: */
13287
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13288
     /* test for range errors (not always needed but do it anyway) */
13289
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13290
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13291
      nrange += tp[i] > X_INT_MAX ;
13292
    }
13293
   /* copy workspace back if necessary */
13294
    if (realign) {
13295
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13296
      xp = (int *) *xpp;
13297
    }
13298
   /* update xpp and tp */
13299
    xp += ni;
13300
    tp += ni;
13301
    *xpp = (void*)xp;
13302
  }
13303
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13304
13305
#else   /* not SX */
13306
13307
0
  char *xp = (char *) *xpp;
13308
0
  int status = NC_NOERR;
13309
13310
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13311
0
  {
13312
0
    int lstatus = ncx_put_int_uint(xp, tp, fillp);
13313
0
    if (status == NC_NOERR) /* report the first encountered error */
13314
0
      status = lstatus;
13315
0
  }
13316
13317
0
  *xpp = (void *)xp;
13318
0
  return status;
13319
0
#endif
13320
0
}
13321
13322
int
13323
ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
13324
0
{
13325
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13326
13327
 /* basic algorithm is:
13328
  *   - ensure sane alignment of output data
13329
  *   - copy (conversion happens automatically) input data
13330
  *     to output
13331
  *   - update tp to point at next unconverted input, and xpp to point
13332
  *     at next location for converted output
13333
  */
13334
  long i, j, ni;
13335
  int tmp[LOOPCNT];        /* in case input is misaligned */
13336
  int *xp;
13337
  int nrange = 0;         /* number of range errors */
13338
  int realign = 0;        /* "do we need to fix input data alignment?" */
13339
  long cxp = (long) *((char**)xpp);
13340
13341
  realign = (cxp & 7) % SIZEOF_INT;
13342
  /* sjl: manually stripmine so we can limit amount of
13343
   * vector work space reserved to LOOPCNT elements. Also
13344
   * makes vectorisation easy */
13345
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13346
    ni=Min(nelems-j,LOOPCNT);
13347
    if (realign) {
13348
      xp = tmp;
13349
    } else {
13350
      xp = (int *) *xpp;
13351
    }
13352
   /* copy the next block */
13353
#pragma cdir loopcnt=LOOPCNT
13354
#pragma cdir shortloop
13355
    for (i=0; i<ni; i++) {
13356
      /* the normal case: */
13357
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13358
     /* test for range errors (not always needed but do it anyway) */
13359
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13360
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13361
      nrange += tp[i] > X_INT_MAX ;
13362
    }
13363
   /* copy workspace back if necessary */
13364
    if (realign) {
13365
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13366
      xp = (int *) *xpp;
13367
    }
13368
   /* update xpp and tp */
13369
    xp += ni;
13370
    tp += ni;
13371
    *xpp = (void*)xp;
13372
  }
13373
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13374
13375
#else   /* not SX */
13376
13377
0
  char *xp = (char *) *xpp;
13378
0
  int status = NC_NOERR;
13379
13380
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13381
0
  {
13382
0
    int lstatus = ncx_put_int_ulonglong(xp, tp, fillp);
13383
0
    if (status == NC_NOERR) /* report the first encountered error */
13384
0
      status = lstatus;
13385
0
  }
13386
13387
0
  *xpp = (void *)xp;
13388
0
  return status;
13389
0
#endif
13390
0
}
13391
13392
13393
/* uint ----------------------------------------------------------------------*/
13394
13395
#if X_SIZEOF_UINT == SIZEOF_UINT
13396
/* optimized version */
13397
int
13398
ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
13399
0
{
13400
#ifdef WORDS_BIGENDIAN
13401
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
13402
# else
13403
0
  swapn4b(tp, *xpp, nelems);
13404
0
# endif
13405
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
13406
0
  return NC_NOERR;
13407
0
}
13408
#else
13409
int
13410
ncx_getn_uint_uint(const void **xpp, size_t nelems, uint *tp)
13411
{
13412
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13413
13414
 /* basic algorithm is:
13415
  *   - ensure sane alignment of input data
13416
  *   - copy (conversion happens automatically) input data
13417
  *     to output
13418
  *   - update xpp to point at next unconverted input, and tp to point
13419
  *     at next location for converted output
13420
  */
13421
  long i, j, ni;
13422
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13423
  uint *xp;
13424
  int nrange = 0;         /* number of range errors */
13425
  int realign = 0;        /* "do we need to fix input data alignment?" */
13426
  long cxp = (long) *((char**)xpp);
13427
13428
  realign = (cxp & 7) % SIZEOF_UINT;
13429
  /* sjl: manually stripmine so we can limit amount of
13430
   * vector work space reserved to LOOPCNT elements. Also
13431
   * makes vectorisation easy */
13432
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13433
    ni=Min(nelems-j,LOOPCNT);
13434
    if (realign) {
13435
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13436
      xp = tmp;
13437
    } else {
13438
      xp = (uint *) *xpp;
13439
    }
13440
   /* copy the next block */
13441
#pragma cdir loopcnt=LOOPCNT
13442
#pragma cdir shortloop
13443
    for (i=0; i<ni; i++) {
13444
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
13445
     /* test for range errors (not always needed but do it anyway) */
13446
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13447
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13448
      nrange += xp[i] > UINT_MAX ;
13449
    }
13450
   /* update xpp and tp */
13451
    if (realign) xp = (uint *) *xpp;
13452
    xp += ni;
13453
    tp += ni;
13454
    *xpp = (void*)xp;
13455
  }
13456
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13457
13458
#else   /* not SX */
13459
  const char *xp = (const char *) *xpp;
13460
  int status = NC_NOERR;
13461
13462
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13463
  {
13464
    const int lstatus = ncx_get_uint_uint(xp, tp);
13465
    if (status == NC_NOERR) /* report the first encountered error */
13466
      status = lstatus;
13467
  }
13468
13469
  *xpp = (const void *)xp;
13470
  return status;
13471
#endif
13472
}
13473
13474
#endif
13475
int
13476
ncx_getn_uint_schar(const void **xpp, size_t nelems, schar *tp)
13477
0
{
13478
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13479
13480
 /* basic algorithm is:
13481
  *   - ensure sane alignment of input data
13482
  *   - copy (conversion happens automatically) input data
13483
  *     to output
13484
  *   - update xpp to point at next unconverted input, and tp to point
13485
  *     at next location for converted output
13486
  */
13487
  long i, j, ni;
13488
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13489
  uint *xp;
13490
  int nrange = 0;         /* number of range errors */
13491
  int realign = 0;        /* "do we need to fix input data alignment?" */
13492
  long cxp = (long) *((char**)xpp);
13493
13494
  realign = (cxp & 7) % SIZEOF_UINT;
13495
  /* sjl: manually stripmine so we can limit amount of
13496
   * vector work space reserved to LOOPCNT elements. Also
13497
   * makes vectorisation easy */
13498
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13499
    ni=Min(nelems-j,LOOPCNT);
13500
    if (realign) {
13501
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13502
      xp = tmp;
13503
    } else {
13504
      xp = (uint *) *xpp;
13505
    }
13506
   /* copy the next block */
13507
#pragma cdir loopcnt=LOOPCNT
13508
#pragma cdir shortloop
13509
    for (i=0; i<ni; i++) {
13510
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
13511
     /* test for range errors (not always needed but do it anyway) */
13512
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13513
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13514
      nrange += xp[i] > SCHAR_MAX ;
13515
    }
13516
   /* update xpp and tp */
13517
    if (realign) xp = (uint *) *xpp;
13518
    xp += ni;
13519
    tp += ni;
13520
    *xpp = (void*)xp;
13521
  }
13522
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13523
13524
#else   /* not SX */
13525
0
  const char *xp = (const char *) *xpp;
13526
0
  int status = NC_NOERR;
13527
13528
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13529
0
  {
13530
0
    const int lstatus = ncx_get_uint_schar(xp, tp);
13531
0
    if (status == NC_NOERR) /* report the first encountered error */
13532
0
      status = lstatus;
13533
0
  }
13534
13535
0
  *xpp = (const void *)xp;
13536
0
  return status;
13537
0
#endif
13538
0
}
13539
13540
int
13541
ncx_getn_uint_short(const void **xpp, size_t nelems, short *tp)
13542
0
{
13543
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13544
13545
 /* basic algorithm is:
13546
  *   - ensure sane alignment of input data
13547
  *   - copy (conversion happens automatically) input data
13548
  *     to output
13549
  *   - update xpp to point at next unconverted input, and tp to point
13550
  *     at next location for converted output
13551
  */
13552
  long i, j, ni;
13553
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13554
  uint *xp;
13555
  int nrange = 0;         /* number of range errors */
13556
  int realign = 0;        /* "do we need to fix input data alignment?" */
13557
  long cxp = (long) *((char**)xpp);
13558
13559
  realign = (cxp & 7) % SIZEOF_UINT;
13560
  /* sjl: manually stripmine so we can limit amount of
13561
   * vector work space reserved to LOOPCNT elements. Also
13562
   * makes vectorisation easy */
13563
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13564
    ni=Min(nelems-j,LOOPCNT);
13565
    if (realign) {
13566
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13567
      xp = tmp;
13568
    } else {
13569
      xp = (uint *) *xpp;
13570
    }
13571
   /* copy the next block */
13572
#pragma cdir loopcnt=LOOPCNT
13573
#pragma cdir shortloop
13574
    for (i=0; i<ni; i++) {
13575
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
13576
     /* test for range errors (not always needed but do it anyway) */
13577
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13578
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13579
      nrange += xp[i] > SHORT_MAX ;
13580
    }
13581
   /* update xpp and tp */
13582
    if (realign) xp = (uint *) *xpp;
13583
    xp += ni;
13584
    tp += ni;
13585
    *xpp = (void*)xp;
13586
  }
13587
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13588
13589
#else   /* not SX */
13590
0
  const char *xp = (const char *) *xpp;
13591
0
  int status = NC_NOERR;
13592
13593
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13594
0
  {
13595
0
    const int lstatus = ncx_get_uint_short(xp, tp);
13596
0
    if (status == NC_NOERR) /* report the first encountered error */
13597
0
      status = lstatus;
13598
0
  }
13599
13600
0
  *xpp = (const void *)xp;
13601
0
  return status;
13602
0
#endif
13603
0
}
13604
13605
int
13606
ncx_getn_uint_int(const void **xpp, size_t nelems, int *tp)
13607
0
{
13608
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13609
13610
 /* basic algorithm is:
13611
  *   - ensure sane alignment of input data
13612
  *   - copy (conversion happens automatically) input data
13613
  *     to output
13614
  *   - update xpp to point at next unconverted input, and tp to point
13615
  *     at next location for converted output
13616
  */
13617
  long i, j, ni;
13618
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13619
  uint *xp;
13620
  int nrange = 0;         /* number of range errors */
13621
  int realign = 0;        /* "do we need to fix input data alignment?" */
13622
  long cxp = (long) *((char**)xpp);
13623
13624
  realign = (cxp & 7) % SIZEOF_UINT;
13625
  /* sjl: manually stripmine so we can limit amount of
13626
   * vector work space reserved to LOOPCNT elements. Also
13627
   * makes vectorisation easy */
13628
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13629
    ni=Min(nelems-j,LOOPCNT);
13630
    if (realign) {
13631
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13632
      xp = tmp;
13633
    } else {
13634
      xp = (uint *) *xpp;
13635
    }
13636
   /* copy the next block */
13637
#pragma cdir loopcnt=LOOPCNT
13638
#pragma cdir shortloop
13639
    for (i=0; i<ni; i++) {
13640
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
13641
     /* test for range errors (not always needed but do it anyway) */
13642
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13643
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13644
      nrange += xp[i] > INT_MAX ;
13645
    }
13646
   /* update xpp and tp */
13647
    if (realign) xp = (uint *) *xpp;
13648
    xp += ni;
13649
    tp += ni;
13650
    *xpp = (void*)xp;
13651
  }
13652
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13653
13654
#else   /* not SX */
13655
0
  const char *xp = (const char *) *xpp;
13656
0
  int status = NC_NOERR;
13657
13658
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13659
0
  {
13660
0
    const int lstatus = ncx_get_uint_int(xp, tp);
13661
0
    if (status == NC_NOERR) /* report the first encountered error */
13662
0
      status = lstatus;
13663
0
  }
13664
13665
0
  *xpp = (const void *)xp;
13666
0
  return status;
13667
0
#endif
13668
0
}
13669
13670
int
13671
ncx_getn_uint_long(const void **xpp, size_t nelems, long *tp)
13672
0
{
13673
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13674
13675
 /* basic algorithm is:
13676
  *   - ensure sane alignment of input data
13677
  *   - copy (conversion happens automatically) input data
13678
  *     to output
13679
  *   - update xpp to point at next unconverted input, and tp to point
13680
  *     at next location for converted output
13681
  */
13682
  long i, j, ni;
13683
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13684
  uint *xp;
13685
  int nrange = 0;         /* number of range errors */
13686
  int realign = 0;        /* "do we need to fix input data alignment?" */
13687
  long cxp = (long) *((char**)xpp);
13688
13689
  realign = (cxp & 7) % SIZEOF_UINT;
13690
  /* sjl: manually stripmine so we can limit amount of
13691
   * vector work space reserved to LOOPCNT elements. Also
13692
   * makes vectorisation easy */
13693
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13694
    ni=Min(nelems-j,LOOPCNT);
13695
    if (realign) {
13696
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13697
      xp = tmp;
13698
    } else {
13699
      xp = (uint *) *xpp;
13700
    }
13701
   /* copy the next block */
13702
#pragma cdir loopcnt=LOOPCNT
13703
#pragma cdir shortloop
13704
    for (i=0; i<ni; i++) {
13705
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
13706
     /* test for range errors (not always needed but do it anyway) */
13707
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13708
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13709
      nrange += xp[i] > LONG_MAX ;
13710
    }
13711
   /* update xpp and tp */
13712
    if (realign) xp = (uint *) *xpp;
13713
    xp += ni;
13714
    tp += ni;
13715
    *xpp = (void*)xp;
13716
  }
13717
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13718
13719
#else   /* not SX */
13720
0
  const char *xp = (const char *) *xpp;
13721
0
  int status = NC_NOERR;
13722
13723
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13724
0
  {
13725
0
    const int lstatus = ncx_get_uint_long(xp, tp);
13726
0
    if (status == NC_NOERR) /* report the first encountered error */
13727
0
      status = lstatus;
13728
0
  }
13729
13730
0
  *xpp = (const void *)xp;
13731
0
  return status;
13732
0
#endif
13733
0
}
13734
13735
int
13736
ncx_getn_uint_float(const void **xpp, size_t nelems, float *tp)
13737
0
{
13738
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13739
13740
 /* basic algorithm is:
13741
  *   - ensure sane alignment of input data
13742
  *   - copy (conversion happens automatically) input data
13743
  *     to output
13744
  *   - update xpp to point at next unconverted input, and tp to point
13745
  *     at next location for converted output
13746
  */
13747
  long i, j, ni;
13748
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13749
  uint *xp;
13750
  int nrange = 0;         /* number of range errors */
13751
  int realign = 0;        /* "do we need to fix input data alignment?" */
13752
  long cxp = (long) *((char**)xpp);
13753
13754
  realign = (cxp & 7) % SIZEOF_UINT;
13755
  /* sjl: manually stripmine so we can limit amount of
13756
   * vector work space reserved to LOOPCNT elements. Also
13757
   * makes vectorisation easy */
13758
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13759
    ni=Min(nelems-j,LOOPCNT);
13760
    if (realign) {
13761
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13762
      xp = tmp;
13763
    } else {
13764
      xp = (uint *) *xpp;
13765
    }
13766
   /* copy the next block */
13767
#pragma cdir loopcnt=LOOPCNT
13768
#pragma cdir shortloop
13769
    for (i=0; i<ni; i++) {
13770
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
13771
     /* test for range errors (not always needed but do it anyway) */
13772
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13773
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13774
      nrange += xp[i] > FLOAT_MAX ;
13775
    }
13776
   /* update xpp and tp */
13777
    if (realign) xp = (uint *) *xpp;
13778
    xp += ni;
13779
    tp += ni;
13780
    *xpp = (void*)xp;
13781
  }
13782
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13783
13784
#else   /* not SX */
13785
0
  const char *xp = (const char *) *xpp;
13786
0
  int status = NC_NOERR;
13787
13788
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13789
0
  {
13790
0
    const int lstatus = ncx_get_uint_float(xp, tp);
13791
0
    if (status == NC_NOERR) /* report the first encountered error */
13792
0
      status = lstatus;
13793
0
  }
13794
13795
0
  *xpp = (const void *)xp;
13796
0
  return status;
13797
0
#endif
13798
0
}
13799
13800
int
13801
ncx_getn_uint_double(const void **xpp, size_t nelems, double *tp)
13802
0
{
13803
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13804
13805
 /* basic algorithm is:
13806
  *   - ensure sane alignment of input data
13807
  *   - copy (conversion happens automatically) input data
13808
  *     to output
13809
  *   - update xpp to point at next unconverted input, and tp to point
13810
  *     at next location for converted output
13811
  */
13812
  long i, j, ni;
13813
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13814
  uint *xp;
13815
  int nrange = 0;         /* number of range errors */
13816
  int realign = 0;        /* "do we need to fix input data alignment?" */
13817
  long cxp = (long) *((char**)xpp);
13818
13819
  realign = (cxp & 7) % SIZEOF_UINT;
13820
  /* sjl: manually stripmine so we can limit amount of
13821
   * vector work space reserved to LOOPCNT elements. Also
13822
   * makes vectorisation easy */
13823
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13824
    ni=Min(nelems-j,LOOPCNT);
13825
    if (realign) {
13826
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13827
      xp = tmp;
13828
    } else {
13829
      xp = (uint *) *xpp;
13830
    }
13831
   /* copy the next block */
13832
#pragma cdir loopcnt=LOOPCNT
13833
#pragma cdir shortloop
13834
    for (i=0; i<ni; i++) {
13835
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
13836
     /* test for range errors (not always needed but do it anyway) */
13837
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13838
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13839
      nrange += xp[i] > DOUBLE_MAX ;
13840
    }
13841
   /* update xpp and tp */
13842
    if (realign) xp = (uint *) *xpp;
13843
    xp += ni;
13844
    tp += ni;
13845
    *xpp = (void*)xp;
13846
  }
13847
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13848
13849
#else   /* not SX */
13850
0
  const char *xp = (const char *) *xpp;
13851
0
  int status = NC_NOERR;
13852
13853
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13854
0
  {
13855
0
    const int lstatus = ncx_get_uint_double(xp, tp);
13856
0
    if (status == NC_NOERR) /* report the first encountered error */
13857
0
      status = lstatus;
13858
0
  }
13859
13860
0
  *xpp = (const void *)xp;
13861
0
  return status;
13862
0
#endif
13863
0
}
13864
13865
int
13866
ncx_getn_uint_longlong(const void **xpp, size_t nelems, longlong *tp)
13867
0
{
13868
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13869
13870
 /* basic algorithm is:
13871
  *   - ensure sane alignment of input data
13872
  *   - copy (conversion happens automatically) input data
13873
  *     to output
13874
  *   - update xpp to point at next unconverted input, and tp to point
13875
  *     at next location for converted output
13876
  */
13877
  long i, j, ni;
13878
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13879
  uint *xp;
13880
  int nrange = 0;         /* number of range errors */
13881
  int realign = 0;        /* "do we need to fix input data alignment?" */
13882
  long cxp = (long) *((char**)xpp);
13883
13884
  realign = (cxp & 7) % SIZEOF_UINT;
13885
  /* sjl: manually stripmine so we can limit amount of
13886
   * vector work space reserved to LOOPCNT elements. Also
13887
   * makes vectorisation easy */
13888
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13889
    ni=Min(nelems-j,LOOPCNT);
13890
    if (realign) {
13891
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13892
      xp = tmp;
13893
    } else {
13894
      xp = (uint *) *xpp;
13895
    }
13896
   /* copy the next block */
13897
#pragma cdir loopcnt=LOOPCNT
13898
#pragma cdir shortloop
13899
    for (i=0; i<ni; i++) {
13900
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
13901
     /* test for range errors (not always needed but do it anyway) */
13902
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13903
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13904
      nrange += xp[i] > LONGLONG_MAX ;
13905
    }
13906
   /* update xpp and tp */
13907
    if (realign) xp = (uint *) *xpp;
13908
    xp += ni;
13909
    tp += ni;
13910
    *xpp = (void*)xp;
13911
  }
13912
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13913
13914
#else   /* not SX */
13915
0
  const char *xp = (const char *) *xpp;
13916
0
  int status = NC_NOERR;
13917
13918
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13919
0
  {
13920
0
    const int lstatus = ncx_get_uint_longlong(xp, tp);
13921
0
    if (status == NC_NOERR) /* report the first encountered error */
13922
0
      status = lstatus;
13923
0
  }
13924
13925
0
  *xpp = (const void *)xp;
13926
0
  return status;
13927
0
#endif
13928
0
}
13929
13930
int
13931
ncx_getn_uint_uchar(const void **xpp, size_t nelems, uchar *tp)
13932
0
{
13933
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13934
13935
 /* basic algorithm is:
13936
  *   - ensure sane alignment of input data
13937
  *   - copy (conversion happens automatically) input data
13938
  *     to output
13939
  *   - update xpp to point at next unconverted input, and tp to point
13940
  *     at next location for converted output
13941
  */
13942
  long i, j, ni;
13943
  uint tmp[LOOPCNT];        /* in case input is misaligned */
13944
  uint *xp;
13945
  int nrange = 0;         /* number of range errors */
13946
  int realign = 0;        /* "do we need to fix input data alignment?" */
13947
  long cxp = (long) *((char**)xpp);
13948
13949
  realign = (cxp & 7) % SIZEOF_UINT;
13950
  /* sjl: manually stripmine so we can limit amount of
13951
   * vector work space reserved to LOOPCNT elements. Also
13952
   * makes vectorisation easy */
13953
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13954
    ni=Min(nelems-j,LOOPCNT);
13955
    if (realign) {
13956
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13957
      xp = tmp;
13958
    } else {
13959
      xp = (uint *) *xpp;
13960
    }
13961
   /* copy the next block */
13962
#pragma cdir loopcnt=LOOPCNT
13963
#pragma cdir shortloop
13964
    for (i=0; i<ni; i++) {
13965
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
13966
     /* test for range errors (not always needed but do it anyway) */
13967
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13968
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13969
      nrange += xp[i] > UCHAR_MAX ;
13970
    }
13971
   /* update xpp and tp */
13972
    if (realign) xp = (uint *) *xpp;
13973
    xp += ni;
13974
    tp += ni;
13975
    *xpp = (void*)xp;
13976
  }
13977
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
13978
13979
#else   /* not SX */
13980
0
  const char *xp = (const char *) *xpp;
13981
0
  int status = NC_NOERR;
13982
13983
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13984
0
  {
13985
0
    const int lstatus = ncx_get_uint_uchar(xp, tp);
13986
0
    if (status == NC_NOERR) /* report the first encountered error */
13987
0
      status = lstatus;
13988
0
  }
13989
13990
0
  *xpp = (const void *)xp;
13991
0
  return status;
13992
0
#endif
13993
0
}
13994
13995
int
13996
ncx_getn_uint_ushort(const void **xpp, size_t nelems, ushort *tp)
13997
0
{
13998
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13999
14000
 /* basic algorithm is:
14001
  *   - ensure sane alignment of input data
14002
  *   - copy (conversion happens automatically) input data
14003
  *     to output
14004
  *   - update xpp to point at next unconverted input, and tp to point
14005
  *     at next location for converted output
14006
  */
14007
  long i, j, ni;
14008
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14009
  uint *xp;
14010
  int nrange = 0;         /* number of range errors */
14011
  int realign = 0;        /* "do we need to fix input data alignment?" */
14012
  long cxp = (long) *((char**)xpp);
14013
14014
  realign = (cxp & 7) % SIZEOF_UINT;
14015
  /* sjl: manually stripmine so we can limit amount of
14016
   * vector work space reserved to LOOPCNT elements. Also
14017
   * makes vectorisation easy */
14018
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14019
    ni=Min(nelems-j,LOOPCNT);
14020
    if (realign) {
14021
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
14022
      xp = tmp;
14023
    } else {
14024
      xp = (uint *) *xpp;
14025
    }
14026
   /* copy the next block */
14027
#pragma cdir loopcnt=LOOPCNT
14028
#pragma cdir shortloop
14029
    for (i=0; i<ni; i++) {
14030
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
14031
     /* test for range errors (not always needed but do it anyway) */
14032
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14033
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14034
      nrange += xp[i] > USHORT_MAX ;
14035
    }
14036
   /* update xpp and tp */
14037
    if (realign) xp = (uint *) *xpp;
14038
    xp += ni;
14039
    tp += ni;
14040
    *xpp = (void*)xp;
14041
  }
14042
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14043
14044
#else   /* not SX */
14045
0
  const char *xp = (const char *) *xpp;
14046
0
  int status = NC_NOERR;
14047
14048
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14049
0
  {
14050
0
    const int lstatus = ncx_get_uint_ushort(xp, tp);
14051
0
    if (status == NC_NOERR) /* report the first encountered error */
14052
0
      status = lstatus;
14053
0
  }
14054
14055
0
  *xpp = (const void *)xp;
14056
0
  return status;
14057
0
#endif
14058
0
}
14059
14060
int
14061
ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
14062
0
{
14063
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14064
14065
 /* basic algorithm is:
14066
  *   - ensure sane alignment of input data
14067
  *   - copy (conversion happens automatically) input data
14068
  *     to output
14069
  *   - update xpp to point at next unconverted input, and tp to point
14070
  *     at next location for converted output
14071
  */
14072
  long i, j, ni;
14073
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14074
  uint *xp;
14075
  int nrange = 0;         /* number of range errors */
14076
  int realign = 0;        /* "do we need to fix input data alignment?" */
14077
  long cxp = (long) *((char**)xpp);
14078
14079
  realign = (cxp & 7) % SIZEOF_UINT;
14080
  /* sjl: manually stripmine so we can limit amount of
14081
   * vector work space reserved to LOOPCNT elements. Also
14082
   * makes vectorisation easy */
14083
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14084
    ni=Min(nelems-j,LOOPCNT);
14085
    if (realign) {
14086
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
14087
      xp = tmp;
14088
    } else {
14089
      xp = (uint *) *xpp;
14090
    }
14091
   /* copy the next block */
14092
#pragma cdir loopcnt=LOOPCNT
14093
#pragma cdir shortloop
14094
    for (i=0; i<ni; i++) {
14095
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
14096
     /* test for range errors (not always needed but do it anyway) */
14097
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14098
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14099
      nrange += xp[i] > ULONGLONG_MAX ;
14100
    }
14101
   /* update xpp and tp */
14102
    if (realign) xp = (uint *) *xpp;
14103
    xp += ni;
14104
    tp += ni;
14105
    *xpp = (void*)xp;
14106
  }
14107
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14108
14109
#else   /* not SX */
14110
0
  const char *xp = (const char *) *xpp;
14111
0
  int status = NC_NOERR;
14112
14113
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14114
0
  {
14115
0
    const int lstatus = ncx_get_uint_ulonglong(xp, tp);
14116
0
    if (status == NC_NOERR) /* report the first encountered error */
14117
0
      status = lstatus;
14118
0
  }
14119
14120
0
  *xpp = (const void *)xp;
14121
0
  return status;
14122
0
#endif
14123
0
}
14124
14125
14126
#if X_SIZEOF_UINT == SIZEOF_UINT
14127
/* optimized version */
14128
int
14129
ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp, void *fillp)
14130
0
{
14131
#ifdef WORDS_BIGENDIAN
14132
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
14133
# else
14134
0
  swapn4b(*xpp, tp, nelems);
14135
0
# endif
14136
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
14137
0
  return NC_NOERR;
14138
0
}
14139
#else
14140
int
14141
ncx_putn_uint_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
14142
{
14143
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14144
14145
 /* basic algorithm is:
14146
  *   - ensure sane alignment of output data
14147
  *   - copy (conversion happens automatically) input data
14148
  *     to output
14149
  *   - update tp to point at next unconverted input, and xpp to point
14150
  *     at next location for converted output
14151
  */
14152
  long i, j, ni;
14153
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14154
  uint *xp;
14155
  int nrange = 0;         /* number of range errors */
14156
  int realign = 0;        /* "do we need to fix input data alignment?" */
14157
  long cxp = (long) *((char**)xpp);
14158
14159
  realign = (cxp & 7) % SIZEOF_UINT;
14160
  /* sjl: manually stripmine so we can limit amount of
14161
   * vector work space reserved to LOOPCNT elements. Also
14162
   * makes vectorisation easy */
14163
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14164
    ni=Min(nelems-j,LOOPCNT);
14165
    if (realign) {
14166
      xp = tmp;
14167
    } else {
14168
      xp = (uint *) *xpp;
14169
    }
14170
   /* copy the next block */
14171
#pragma cdir loopcnt=LOOPCNT
14172
#pragma cdir shortloop
14173
    for (i=0; i<ni; i++) {
14174
      /* the normal case: */
14175
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14176
     /* test for range errors (not always needed but do it anyway) */
14177
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14178
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14179
      nrange += tp[i] > X_UINT_MAX ;
14180
    }
14181
   /* copy workspace back if necessary */
14182
    if (realign) {
14183
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14184
      xp = (uint *) *xpp;
14185
    }
14186
   /* update xpp and tp */
14187
    xp += ni;
14188
    tp += ni;
14189
    *xpp = (void*)xp;
14190
  }
14191
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14192
14193
#else   /* not SX */
14194
14195
  char *xp = (char *) *xpp;
14196
  int status = NC_NOERR;
14197
14198
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14199
  {
14200
    int lstatus = ncx_put_uint_uint(xp, tp, fillp);
14201
    if (status == NC_NOERR) /* report the first encountered error */
14202
      status = lstatus;
14203
  }
14204
14205
  *xpp = (void *)xp;
14206
  return status;
14207
#endif
14208
}
14209
14210
#endif
14211
int
14212
ncx_putn_uint_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
14213
0
{
14214
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14215
14216
 /* basic algorithm is:
14217
  *   - ensure sane alignment of output data
14218
  *   - copy (conversion happens automatically) input data
14219
  *     to output
14220
  *   - update tp to point at next unconverted input, and xpp to point
14221
  *     at next location for converted output
14222
  */
14223
  long i, j, ni;
14224
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14225
  uint *xp;
14226
  int nrange = 0;         /* number of range errors */
14227
  int realign = 0;        /* "do we need to fix input data alignment?" */
14228
  long cxp = (long) *((char**)xpp);
14229
14230
  realign = (cxp & 7) % SIZEOF_UINT;
14231
  /* sjl: manually stripmine so we can limit amount of
14232
   * vector work space reserved to LOOPCNT elements. Also
14233
   * makes vectorisation easy */
14234
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14235
    ni=Min(nelems-j,LOOPCNT);
14236
    if (realign) {
14237
      xp = tmp;
14238
    } else {
14239
      xp = (uint *) *xpp;
14240
    }
14241
   /* copy the next block */
14242
#pragma cdir loopcnt=LOOPCNT
14243
#pragma cdir shortloop
14244
    for (i=0; i<ni; i++) {
14245
      /* the normal case: */
14246
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14247
     /* test for range errors (not always needed but do it anyway) */
14248
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14249
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14250
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14251
    }
14252
   /* copy workspace back if necessary */
14253
    if (realign) {
14254
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14255
      xp = (uint *) *xpp;
14256
    }
14257
   /* update xpp and tp */
14258
    xp += ni;
14259
    tp += ni;
14260
    *xpp = (void*)xp;
14261
  }
14262
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14263
14264
#else   /* not SX */
14265
14266
0
  char *xp = (char *) *xpp;
14267
0
  int status = NC_NOERR;
14268
14269
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14270
0
  {
14271
0
    int lstatus = ncx_put_uint_schar(xp, tp, fillp);
14272
0
    if (status == NC_NOERR) /* report the first encountered error */
14273
0
      status = lstatus;
14274
0
  }
14275
14276
0
  *xpp = (void *)xp;
14277
0
  return status;
14278
0
#endif
14279
0
}
14280
14281
int
14282
ncx_putn_uint_short(void **xpp, size_t nelems, const short *tp, void *fillp)
14283
0
{
14284
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14285
14286
 /* basic algorithm is:
14287
  *   - ensure sane alignment of output data
14288
  *   - copy (conversion happens automatically) input data
14289
  *     to output
14290
  *   - update tp to point at next unconverted input, and xpp to point
14291
  *     at next location for converted output
14292
  */
14293
  long i, j, ni;
14294
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14295
  uint *xp;
14296
  int nrange = 0;         /* number of range errors */
14297
  int realign = 0;        /* "do we need to fix input data alignment?" */
14298
  long cxp = (long) *((char**)xpp);
14299
14300
  realign = (cxp & 7) % SIZEOF_UINT;
14301
  /* sjl: manually stripmine so we can limit amount of
14302
   * vector work space reserved to LOOPCNT elements. Also
14303
   * makes vectorisation easy */
14304
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14305
    ni=Min(nelems-j,LOOPCNT);
14306
    if (realign) {
14307
      xp = tmp;
14308
    } else {
14309
      xp = (uint *) *xpp;
14310
    }
14311
   /* copy the next block */
14312
#pragma cdir loopcnt=LOOPCNT
14313
#pragma cdir shortloop
14314
    for (i=0; i<ni; i++) {
14315
      /* the normal case: */
14316
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14317
     /* test for range errors (not always needed but do it anyway) */
14318
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14319
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14320
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14321
    }
14322
   /* copy workspace back if necessary */
14323
    if (realign) {
14324
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14325
      xp = (uint *) *xpp;
14326
    }
14327
   /* update xpp and tp */
14328
    xp += ni;
14329
    tp += ni;
14330
    *xpp = (void*)xp;
14331
  }
14332
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14333
14334
#else   /* not SX */
14335
14336
0
  char *xp = (char *) *xpp;
14337
0
  int status = NC_NOERR;
14338
14339
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14340
0
  {
14341
0
    int lstatus = ncx_put_uint_short(xp, tp, fillp);
14342
0
    if (status == NC_NOERR) /* report the first encountered error */
14343
0
      status = lstatus;
14344
0
  }
14345
14346
0
  *xpp = (void *)xp;
14347
0
  return status;
14348
0
#endif
14349
0
}
14350
14351
int
14352
ncx_putn_uint_int(void **xpp, size_t nelems, const int *tp, void *fillp)
14353
0
{
14354
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14355
14356
 /* basic algorithm is:
14357
  *   - ensure sane alignment of output data
14358
  *   - copy (conversion happens automatically) input data
14359
  *     to output
14360
  *   - update tp to point at next unconverted input, and xpp to point
14361
  *     at next location for converted output
14362
  */
14363
  long i, j, ni;
14364
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14365
  uint *xp;
14366
  int nrange = 0;         /* number of range errors */
14367
  int realign = 0;        /* "do we need to fix input data alignment?" */
14368
  long cxp = (long) *((char**)xpp);
14369
14370
  realign = (cxp & 7) % SIZEOF_UINT;
14371
  /* sjl: manually stripmine so we can limit amount of
14372
   * vector work space reserved to LOOPCNT elements. Also
14373
   * makes vectorisation easy */
14374
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14375
    ni=Min(nelems-j,LOOPCNT);
14376
    if (realign) {
14377
      xp = tmp;
14378
    } else {
14379
      xp = (uint *) *xpp;
14380
    }
14381
   /* copy the next block */
14382
#pragma cdir loopcnt=LOOPCNT
14383
#pragma cdir shortloop
14384
    for (i=0; i<ni; i++) {
14385
      /* the normal case: */
14386
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14387
     /* test for range errors (not always needed but do it anyway) */
14388
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14389
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14390
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14391
    }
14392
   /* copy workspace back if necessary */
14393
    if (realign) {
14394
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14395
      xp = (uint *) *xpp;
14396
    }
14397
   /* update xpp and tp */
14398
    xp += ni;
14399
    tp += ni;
14400
    *xpp = (void*)xp;
14401
  }
14402
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14403
14404
#else   /* not SX */
14405
14406
0
  char *xp = (char *) *xpp;
14407
0
  int status = NC_NOERR;
14408
14409
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14410
0
  {
14411
0
    int lstatus = ncx_put_uint_int(xp, tp, fillp);
14412
0
    if (status == NC_NOERR) /* report the first encountered error */
14413
0
      status = lstatus;
14414
0
  }
14415
14416
0
  *xpp = (void *)xp;
14417
0
  return status;
14418
0
#endif
14419
0
}
14420
14421
int
14422
ncx_putn_uint_long(void **xpp, size_t nelems, const long *tp, void *fillp)
14423
0
{
14424
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14425
14426
 /* basic algorithm is:
14427
  *   - ensure sane alignment of output data
14428
  *   - copy (conversion happens automatically) input data
14429
  *     to output
14430
  *   - update tp to point at next unconverted input, and xpp to point
14431
  *     at next location for converted output
14432
  */
14433
  long i, j, ni;
14434
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14435
  uint *xp;
14436
  int nrange = 0;         /* number of range errors */
14437
  int realign = 0;        /* "do we need to fix input data alignment?" */
14438
  long cxp = (long) *((char**)xpp);
14439
14440
  realign = (cxp & 7) % SIZEOF_UINT;
14441
  /* sjl: manually stripmine so we can limit amount of
14442
   * vector work space reserved to LOOPCNT elements. Also
14443
   * makes vectorisation easy */
14444
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14445
    ni=Min(nelems-j,LOOPCNT);
14446
    if (realign) {
14447
      xp = tmp;
14448
    } else {
14449
      xp = (uint *) *xpp;
14450
    }
14451
   /* copy the next block */
14452
#pragma cdir loopcnt=LOOPCNT
14453
#pragma cdir shortloop
14454
    for (i=0; i<ni; i++) {
14455
      /* the normal case: */
14456
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14457
     /* test for range errors (not always needed but do it anyway) */
14458
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14459
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14460
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14461
    }
14462
   /* copy workspace back if necessary */
14463
    if (realign) {
14464
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14465
      xp = (uint *) *xpp;
14466
    }
14467
   /* update xpp and tp */
14468
    xp += ni;
14469
    tp += ni;
14470
    *xpp = (void*)xp;
14471
  }
14472
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14473
14474
#else   /* not SX */
14475
14476
0
  char *xp = (char *) *xpp;
14477
0
  int status = NC_NOERR;
14478
14479
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14480
0
  {
14481
0
    int lstatus = ncx_put_uint_long(xp, tp, fillp);
14482
0
    if (status == NC_NOERR) /* report the first encountered error */
14483
0
      status = lstatus;
14484
0
  }
14485
14486
0
  *xpp = (void *)xp;
14487
0
  return status;
14488
0
#endif
14489
0
}
14490
14491
int
14492
ncx_putn_uint_float(void **xpp, size_t nelems, const float *tp, void *fillp)
14493
0
{
14494
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14495
14496
 /* basic algorithm is:
14497
  *   - ensure sane alignment of output data
14498
  *   - copy (conversion happens automatically) input data
14499
  *     to output
14500
  *   - update tp to point at next unconverted input, and xpp to point
14501
  *     at next location for converted output
14502
  */
14503
  long i, j, ni;
14504
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14505
  uint *xp;
14506
  int nrange = 0;         /* number of range errors */
14507
  int realign = 0;        /* "do we need to fix input data alignment?" */
14508
  long cxp = (long) *((char**)xpp);
14509
14510
  realign = (cxp & 7) % SIZEOF_UINT;
14511
  /* sjl: manually stripmine so we can limit amount of
14512
   * vector work space reserved to LOOPCNT elements. Also
14513
   * makes vectorisation easy */
14514
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14515
    ni=Min(nelems-j,LOOPCNT);
14516
    if (realign) {
14517
      xp = tmp;
14518
    } else {
14519
      xp = (uint *) *xpp;
14520
    }
14521
   /* copy the next block */
14522
#pragma cdir loopcnt=LOOPCNT
14523
#pragma cdir shortloop
14524
    for (i=0; i<ni; i++) {
14525
      /* the normal case: */
14526
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14527
     /* test for range errors (not always needed but do it anyway) */
14528
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14529
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14530
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14531
    }
14532
   /* copy workspace back if necessary */
14533
    if (realign) {
14534
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14535
      xp = (uint *) *xpp;
14536
    }
14537
   /* update xpp and tp */
14538
    xp += ni;
14539
    tp += ni;
14540
    *xpp = (void*)xp;
14541
  }
14542
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14543
14544
#else   /* not SX */
14545
14546
0
  char *xp = (char *) *xpp;
14547
0
  int status = NC_NOERR;
14548
14549
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14550
0
  {
14551
0
    int lstatus = ncx_put_uint_float(xp, tp, fillp);
14552
0
    if (status == NC_NOERR) /* report the first encountered error */
14553
0
      status = lstatus;
14554
0
  }
14555
14556
0
  *xpp = (void *)xp;
14557
0
  return status;
14558
0
#endif
14559
0
}
14560
14561
int
14562
ncx_putn_uint_double(void **xpp, size_t nelems, const double *tp, void *fillp)
14563
0
{
14564
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14565
14566
 /* basic algorithm is:
14567
  *   - ensure sane alignment of output data
14568
  *   - copy (conversion happens automatically) input data
14569
  *     to output
14570
  *   - update tp to point at next unconverted input, and xpp to point
14571
  *     at next location for converted output
14572
  */
14573
  long i, j, ni;
14574
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14575
  uint *xp;
14576
  int nrange = 0;         /* number of range errors */
14577
  int realign = 0;        /* "do we need to fix input data alignment?" */
14578
  long cxp = (long) *((char**)xpp);
14579
14580
  realign = (cxp & 7) % SIZEOF_UINT;
14581
  /* sjl: manually stripmine so we can limit amount of
14582
   * vector work space reserved to LOOPCNT elements. Also
14583
   * makes vectorisation easy */
14584
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14585
    ni=Min(nelems-j,LOOPCNT);
14586
    if (realign) {
14587
      xp = tmp;
14588
    } else {
14589
      xp = (uint *) *xpp;
14590
    }
14591
   /* copy the next block */
14592
#pragma cdir loopcnt=LOOPCNT
14593
#pragma cdir shortloop
14594
    for (i=0; i<ni; i++) {
14595
      /* the normal case: */
14596
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14597
     /* test for range errors (not always needed but do it anyway) */
14598
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14599
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14600
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14601
    }
14602
   /* copy workspace back if necessary */
14603
    if (realign) {
14604
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14605
      xp = (uint *) *xpp;
14606
    }
14607
   /* update xpp and tp */
14608
    xp += ni;
14609
    tp += ni;
14610
    *xpp = (void*)xp;
14611
  }
14612
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14613
14614
#else   /* not SX */
14615
14616
0
  char *xp = (char *) *xpp;
14617
0
  int status = NC_NOERR;
14618
14619
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14620
0
  {
14621
0
    int lstatus = ncx_put_uint_double(xp, tp, fillp);
14622
0
    if (status == NC_NOERR) /* report the first encountered error */
14623
0
      status = lstatus;
14624
0
  }
14625
14626
0
  *xpp = (void *)xp;
14627
0
  return status;
14628
0
#endif
14629
0
}
14630
14631
int
14632
ncx_putn_uint_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
14633
0
{
14634
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14635
14636
 /* basic algorithm is:
14637
  *   - ensure sane alignment of output data
14638
  *   - copy (conversion happens automatically) input data
14639
  *     to output
14640
  *   - update tp to point at next unconverted input, and xpp to point
14641
  *     at next location for converted output
14642
  */
14643
  long i, j, ni;
14644
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14645
  uint *xp;
14646
  int nrange = 0;         /* number of range errors */
14647
  int realign = 0;        /* "do we need to fix input data alignment?" */
14648
  long cxp = (long) *((char**)xpp);
14649
14650
  realign = (cxp & 7) % SIZEOF_UINT;
14651
  /* sjl: manually stripmine so we can limit amount of
14652
   * vector work space reserved to LOOPCNT elements. Also
14653
   * makes vectorisation easy */
14654
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14655
    ni=Min(nelems-j,LOOPCNT);
14656
    if (realign) {
14657
      xp = tmp;
14658
    } else {
14659
      xp = (uint *) *xpp;
14660
    }
14661
   /* copy the next block */
14662
#pragma cdir loopcnt=LOOPCNT
14663
#pragma cdir shortloop
14664
    for (i=0; i<ni; i++) {
14665
      /* the normal case: */
14666
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14667
     /* test for range errors (not always needed but do it anyway) */
14668
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14669
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14670
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14671
    }
14672
   /* copy workspace back if necessary */
14673
    if (realign) {
14674
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14675
      xp = (uint *) *xpp;
14676
    }
14677
   /* update xpp and tp */
14678
    xp += ni;
14679
    tp += ni;
14680
    *xpp = (void*)xp;
14681
  }
14682
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14683
14684
#else   /* not SX */
14685
14686
0
  char *xp = (char *) *xpp;
14687
0
  int status = NC_NOERR;
14688
14689
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14690
0
  {
14691
0
    int lstatus = ncx_put_uint_longlong(xp, tp, fillp);
14692
0
    if (status == NC_NOERR) /* report the first encountered error */
14693
0
      status = lstatus;
14694
0
  }
14695
14696
0
  *xpp = (void *)xp;
14697
0
  return status;
14698
0
#endif
14699
0
}
14700
14701
int
14702
ncx_putn_uint_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
14703
0
{
14704
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14705
14706
 /* basic algorithm is:
14707
  *   - ensure sane alignment of output data
14708
  *   - copy (conversion happens automatically) input data
14709
  *     to output
14710
  *   - update tp to point at next unconverted input, and xpp to point
14711
  *     at next location for converted output
14712
  */
14713
  long i, j, ni;
14714
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14715
  uint *xp;
14716
  int nrange = 0;         /* number of range errors */
14717
  int realign = 0;        /* "do we need to fix input data alignment?" */
14718
  long cxp = (long) *((char**)xpp);
14719
14720
  realign = (cxp & 7) % SIZEOF_UINT;
14721
  /* sjl: manually stripmine so we can limit amount of
14722
   * vector work space reserved to LOOPCNT elements. Also
14723
   * makes vectorisation easy */
14724
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14725
    ni=Min(nelems-j,LOOPCNT);
14726
    if (realign) {
14727
      xp = tmp;
14728
    } else {
14729
      xp = (uint *) *xpp;
14730
    }
14731
   /* copy the next block */
14732
#pragma cdir loopcnt=LOOPCNT
14733
#pragma cdir shortloop
14734
    for (i=0; i<ni; i++) {
14735
      /* the normal case: */
14736
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14737
     /* test for range errors (not always needed but do it anyway) */
14738
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14739
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14740
      nrange += tp[i] > X_UINT_MAX ;
14741
    }
14742
   /* copy workspace back if necessary */
14743
    if (realign) {
14744
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14745
      xp = (uint *) *xpp;
14746
    }
14747
   /* update xpp and tp */
14748
    xp += ni;
14749
    tp += ni;
14750
    *xpp = (void*)xp;
14751
  }
14752
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14753
14754
#else   /* not SX */
14755
14756
0
  char *xp = (char *) *xpp;
14757
0
  int status = NC_NOERR;
14758
14759
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14760
0
  {
14761
0
    int lstatus = ncx_put_uint_uchar(xp, tp, fillp);
14762
0
    if (status == NC_NOERR) /* report the first encountered error */
14763
0
      status = lstatus;
14764
0
  }
14765
14766
0
  *xpp = (void *)xp;
14767
0
  return status;
14768
0
#endif
14769
0
}
14770
14771
int
14772
ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
14773
0
{
14774
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14775
14776
 /* basic algorithm is:
14777
  *   - ensure sane alignment of output data
14778
  *   - copy (conversion happens automatically) input data
14779
  *     to output
14780
  *   - update tp to point at next unconverted input, and xpp to point
14781
  *     at next location for converted output
14782
  */
14783
  long i, j, ni;
14784
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14785
  uint *xp;
14786
  int nrange = 0;         /* number of range errors */
14787
  int realign = 0;        /* "do we need to fix input data alignment?" */
14788
  long cxp = (long) *((char**)xpp);
14789
14790
  realign = (cxp & 7) % SIZEOF_UINT;
14791
  /* sjl: manually stripmine so we can limit amount of
14792
   * vector work space reserved to LOOPCNT elements. Also
14793
   * makes vectorisation easy */
14794
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14795
    ni=Min(nelems-j,LOOPCNT);
14796
    if (realign) {
14797
      xp = tmp;
14798
    } else {
14799
      xp = (uint *) *xpp;
14800
    }
14801
   /* copy the next block */
14802
#pragma cdir loopcnt=LOOPCNT
14803
#pragma cdir shortloop
14804
    for (i=0; i<ni; i++) {
14805
      /* the normal case: */
14806
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14807
     /* test for range errors (not always needed but do it anyway) */
14808
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14809
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14810
      nrange += tp[i] > X_UINT_MAX ;
14811
    }
14812
   /* copy workspace back if necessary */
14813
    if (realign) {
14814
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14815
      xp = (uint *) *xpp;
14816
    }
14817
   /* update xpp and tp */
14818
    xp += ni;
14819
    tp += ni;
14820
    *xpp = (void*)xp;
14821
  }
14822
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14823
14824
#else   /* not SX */
14825
14826
0
  char *xp = (char *) *xpp;
14827
0
  int status = NC_NOERR;
14828
14829
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14830
0
  {
14831
0
    int lstatus = ncx_put_uint_ushort(xp, tp, fillp);
14832
0
    if (status == NC_NOERR) /* report the first encountered error */
14833
0
      status = lstatus;
14834
0
  }
14835
14836
0
  *xpp = (void *)xp;
14837
0
  return status;
14838
0
#endif
14839
0
}
14840
14841
int
14842
ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
14843
0
{
14844
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14845
14846
 /* basic algorithm is:
14847
  *   - ensure sane alignment of output data
14848
  *   - copy (conversion happens automatically) input data
14849
  *     to output
14850
  *   - update tp to point at next unconverted input, and xpp to point
14851
  *     at next location for converted output
14852
  */
14853
  long i, j, ni;
14854
  uint tmp[LOOPCNT];        /* in case input is misaligned */
14855
  uint *xp;
14856
  int nrange = 0;         /* number of range errors */
14857
  int realign = 0;        /* "do we need to fix input data alignment?" */
14858
  long cxp = (long) *((char**)xpp);
14859
14860
  realign = (cxp & 7) % SIZEOF_UINT;
14861
  /* sjl: manually stripmine so we can limit amount of
14862
   * vector work space reserved to LOOPCNT elements. Also
14863
   * makes vectorisation easy */
14864
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14865
    ni=Min(nelems-j,LOOPCNT);
14866
    if (realign) {
14867
      xp = tmp;
14868
    } else {
14869
      xp = (uint *) *xpp;
14870
    }
14871
   /* copy the next block */
14872
#pragma cdir loopcnt=LOOPCNT
14873
#pragma cdir shortloop
14874
    for (i=0; i<ni; i++) {
14875
      /* the normal case: */
14876
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14877
     /* test for range errors (not always needed but do it anyway) */
14878
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14879
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14880
      nrange += tp[i] > X_UINT_MAX ;
14881
    }
14882
   /* copy workspace back if necessary */
14883
    if (realign) {
14884
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14885
      xp = (uint *) *xpp;
14886
    }
14887
   /* update xpp and tp */
14888
    xp += ni;
14889
    tp += ni;
14890
    *xpp = (void*)xp;
14891
  }
14892
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
14893
14894
#else   /* not SX */
14895
14896
0
  char *xp = (char *) *xpp;
14897
0
  int status = NC_NOERR;
14898
14899
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14900
0
  {
14901
0
    int lstatus = ncx_put_uint_ulonglong(xp, tp, fillp);
14902
0
    if (status == NC_NOERR) /* report the first encountered error */
14903
0
      status = lstatus;
14904
0
  }
14905
14906
0
  *xpp = (void *)xp;
14907
0
  return status;
14908
0
#endif
14909
0
}
14910
14911
14912
14913
/* float ---------------------------------------------------------------------*/
14914
14915
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
14916
/* optimized version */
14917
int
14918
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14919
0
{
14920
#ifdef WORDS_BIGENDIAN
14921
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
14922
# else
14923
0
  swapn4b(tp, *xpp, nelems);
14924
0
# endif
14925
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
14926
0
  return NC_NOERR;
14927
0
}
14928
#elif defined(vax) && vax != 0
14929
int
14930
ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
14931
{
14932
  float *const end = ip + nfloats;
14933
14934
  while (ip < end)
14935
  {
14936
    struct vax_single *const vsp = (struct vax_single *) ip;
14937
    const struct ieee_single *const isp =
14938
       (const struct ieee_single *) (*xpp);
14939
    unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
14940
14941
    switch(exp) {
14942
    case 0 :
14943
      /* ieee subnormal */
14944
      if (isp->mant_hi == min.ieee.mant_hi
14945
        && isp->mant_lo_hi == min.ieee.mant_lo_hi
14946
        && isp->mant_lo_lo == min.ieee.mant_lo_lo)
14947
      {
14948
        *vsp = min.s;
14949
      }
14950
      else
14951
      {
14952
        unsigned mantissa = (isp->mant_hi << 16)
14953
           | isp->mant_lo_hi << 8
14954
           | isp->mant_lo_lo;
14955
        unsigned tmp = mantissa >> 20;
14956
        if (tmp >= 4) {
14957
          vsp->exp = 2;
14958
        } else if (tmp >= 2) {
14959
          vsp->exp = 1;
14960
        } else {
14961
          *vsp = min.s;
14962
          break;
14963
        } /* else */
14964
        tmp = mantissa - (1 << (20 + vsp->exp ));
14965
        tmp <<= 3 - vsp->exp;
14966
        vsp->mantissa2 = tmp;
14967
        vsp->mantissa1 = (tmp >> 16);
14968
      }
14969
      break;
14970
    case 0xfe :
14971
    case 0xff :
14972
      *vsp = max.s;
14973
      break;
14974
    default :
14975
      vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
14976
      vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
14977
      vsp->mantissa1 = isp->mant_hi;
14978
    }
14979
14980
    vsp->sign = isp->sign;
14981
14982
14983
    ip++;
14984
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
14985
  }
14986
  return NC_NOERR;
14987
}
14988
#else
14989
int
14990
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14991
{
14992
  const char *xp = *xpp;
14993
  int status = NC_NOERR;
14994
14995
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14996
  {
14997
    const int lstatus = ncx_get_float_float(xp, tp, fillp);
14998
    if (status == NC_NOERR) /* report the first encountered error */
14999
      status = lstatus;
15000
  }
15001
15002
  *xpp = (const void *)xp;
15003
  return status;
15004
}
15005
15006
#endif
15007
int
15008
ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
15009
0
{
15010
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15011
15012
 /* basic algorithm is:
15013
  *   - ensure sane alignment of input data
15014
  *   - copy (conversion happens automatically) input data
15015
  *     to output
15016
  *   - update xpp to point at next unconverted input, and tp to point
15017
  *     at next location for converted output
15018
  */
15019
  long i, j, ni;
15020
  float tmp[LOOPCNT];        /* in case input is misaligned */
15021
  float *xp;
15022
  int nrange = 0;         /* number of range errors */
15023
  int realign = 0;        /* "do we need to fix input data alignment?" */
15024
  long cxp = (long) *((char**)xpp);
15025
15026
  realign = (cxp & 7) % SIZEOF_FLOAT;
15027
  /* sjl: manually stripmine so we can limit amount of
15028
   * vector work space reserved to LOOPCNT elements. Also
15029
   * makes vectorisation easy */
15030
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15031
    ni=Min(nelems-j,LOOPCNT);
15032
    if (realign) {
15033
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15034
      xp = tmp;
15035
    } else {
15036
      xp = (float *) *xpp;
15037
    }
15038
   /* copy the next block */
15039
#pragma cdir loopcnt=LOOPCNT
15040
#pragma cdir shortloop
15041
    for (i=0; i<ni; i++) {
15042
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
15043
     /* test for range errors (not always needed but do it anyway) */
15044
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15045
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15046
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
15047
    }
15048
   /* update xpp and tp */
15049
    if (realign) xp = (float *) *xpp;
15050
    xp += ni;
15051
    tp += ni;
15052
    *xpp = (void*)xp;
15053
  }
15054
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15055
15056
#else   /* not SX */
15057
0
  const char *xp = (const char *) *xpp;
15058
0
  int status = NC_NOERR;
15059
15060
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15061
0
  {
15062
0
    const int lstatus = ncx_get_float_schar(xp, tp);
15063
0
    if (status == NC_NOERR) /* report the first encountered error */
15064
0
      status = lstatus;
15065
0
  }
15066
15067
0
  *xpp = (const void *)xp;
15068
0
  return status;
15069
0
#endif
15070
0
}
15071
15072
int
15073
ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
15074
0
{
15075
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15076
15077
 /* basic algorithm is:
15078
  *   - ensure sane alignment of input data
15079
  *   - copy (conversion happens automatically) input data
15080
  *     to output
15081
  *   - update xpp to point at next unconverted input, and tp to point
15082
  *     at next location for converted output
15083
  */
15084
  long i, j, ni;
15085
  float tmp[LOOPCNT];        /* in case input is misaligned */
15086
  float *xp;
15087
  int nrange = 0;         /* number of range errors */
15088
  int realign = 0;        /* "do we need to fix input data alignment?" */
15089
  long cxp = (long) *((char**)xpp);
15090
15091
  realign = (cxp & 7) % SIZEOF_FLOAT;
15092
  /* sjl: manually stripmine so we can limit amount of
15093
   * vector work space reserved to LOOPCNT elements. Also
15094
   * makes vectorisation easy */
15095
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15096
    ni=Min(nelems-j,LOOPCNT);
15097
    if (realign) {
15098
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15099
      xp = tmp;
15100
    } else {
15101
      xp = (float *) *xpp;
15102
    }
15103
   /* copy the next block */
15104
#pragma cdir loopcnt=LOOPCNT
15105
#pragma cdir shortloop
15106
    for (i=0; i<ni; i++) {
15107
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
15108
     /* test for range errors (not always needed but do it anyway) */
15109
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15110
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15111
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
15112
    }
15113
   /* update xpp and tp */
15114
    if (realign) xp = (float *) *xpp;
15115
    xp += ni;
15116
    tp += ni;
15117
    *xpp = (void*)xp;
15118
  }
15119
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15120
15121
#else   /* not SX */
15122
0
  const char *xp = (const char *) *xpp;
15123
0
  int status = NC_NOERR;
15124
15125
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15126
0
  {
15127
0
    const int lstatus = ncx_get_float_short(xp, tp);
15128
0
    if (status == NC_NOERR) /* report the first encountered error */
15129
0
      status = lstatus;
15130
0
  }
15131
15132
0
  *xpp = (const void *)xp;
15133
0
  return status;
15134
0
#endif
15135
0
}
15136
15137
int
15138
ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
15139
0
{
15140
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15141
15142
 /* basic algorithm is:
15143
  *   - ensure sane alignment of input data
15144
  *   - copy (conversion happens automatically) input data
15145
  *     to output
15146
  *   - update xpp to point at next unconverted input, and tp to point
15147
  *     at next location for converted output
15148
  */
15149
  long i, j, ni;
15150
  float tmp[LOOPCNT];        /* in case input is misaligned */
15151
  float *xp;
15152
  int nrange = 0;         /* number of range errors */
15153
  int realign = 0;        /* "do we need to fix input data alignment?" */
15154
  long cxp = (long) *((char**)xpp);
15155
15156
  realign = (cxp & 7) % SIZEOF_FLOAT;
15157
  /* sjl: manually stripmine so we can limit amount of
15158
   * vector work space reserved to LOOPCNT elements. Also
15159
   * makes vectorisation easy */
15160
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15161
    ni=Min(nelems-j,LOOPCNT);
15162
    if (realign) {
15163
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15164
      xp = tmp;
15165
    } else {
15166
      xp = (float *) *xpp;
15167
    }
15168
   /* copy the next block */
15169
#pragma cdir loopcnt=LOOPCNT
15170
#pragma cdir shortloop
15171
    for (i=0; i<ni; i++) {
15172
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
15173
     /* test for range errors (not always needed but do it anyway) */
15174
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15175
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15176
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
15177
    }
15178
   /* update xpp and tp */
15179
    if (realign) xp = (float *) *xpp;
15180
    xp += ni;
15181
    tp += ni;
15182
    *xpp = (void*)xp;
15183
  }
15184
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15185
15186
#else   /* not SX */
15187
0
  const char *xp = (const char *) *xpp;
15188
0
  int status = NC_NOERR;
15189
15190
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15191
0
  {
15192
0
    const int lstatus = ncx_get_float_int(xp, tp);
15193
0
    if (status == NC_NOERR) /* report the first encountered error */
15194
0
      status = lstatus;
15195
0
  }
15196
15197
0
  *xpp = (const void *)xp;
15198
0
  return status;
15199
0
#endif
15200
0
}
15201
15202
int
15203
ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
15204
0
{
15205
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15206
15207
 /* basic algorithm is:
15208
  *   - ensure sane alignment of input data
15209
  *   - copy (conversion happens automatically) input data
15210
  *     to output
15211
  *   - update xpp to point at next unconverted input, and tp to point
15212
  *     at next location for converted output
15213
  */
15214
  long i, j, ni;
15215
  float tmp[LOOPCNT];        /* in case input is misaligned */
15216
  float *xp;
15217
  int nrange = 0;         /* number of range errors */
15218
  int realign = 0;        /* "do we need to fix input data alignment?" */
15219
  long cxp = (long) *((char**)xpp);
15220
15221
  realign = (cxp & 7) % SIZEOF_FLOAT;
15222
  /* sjl: manually stripmine so we can limit amount of
15223
   * vector work space reserved to LOOPCNT elements. Also
15224
   * makes vectorisation easy */
15225
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15226
    ni=Min(nelems-j,LOOPCNT);
15227
    if (realign) {
15228
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15229
      xp = tmp;
15230
    } else {
15231
      xp = (float *) *xpp;
15232
    }
15233
   /* copy the next block */
15234
#pragma cdir loopcnt=LOOPCNT
15235
#pragma cdir shortloop
15236
    for (i=0; i<ni; i++) {
15237
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
15238
     /* test for range errors (not always needed but do it anyway) */
15239
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15240
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15241
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
15242
    }
15243
   /* update xpp and tp */
15244
    if (realign) xp = (float *) *xpp;
15245
    xp += ni;
15246
    tp += ni;
15247
    *xpp = (void*)xp;
15248
  }
15249
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15250
15251
#else   /* not SX */
15252
0
  const char *xp = (const char *) *xpp;
15253
0
  int status = NC_NOERR;
15254
15255
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15256
0
  {
15257
0
    const int lstatus = ncx_get_float_long(xp, tp);
15258
0
    if (status == NC_NOERR) /* report the first encountered error */
15259
0
      status = lstatus;
15260
0
  }
15261
15262
0
  *xpp = (const void *)xp;
15263
0
  return status;
15264
0
#endif
15265
0
}
15266
15267
int
15268
ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
15269
0
{
15270
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15271
15272
 /* basic algorithm is:
15273
  *   - ensure sane alignment of input data
15274
  *   - copy (conversion happens automatically) input data
15275
  *     to output
15276
  *   - update xpp to point at next unconverted input, and tp to point
15277
  *     at next location for converted output
15278
  */
15279
  long i, j, ni;
15280
  float tmp[LOOPCNT];        /* in case input is misaligned */
15281
  float *xp;
15282
  int nrange = 0;         /* number of range errors */
15283
  int realign = 0;        /* "do we need to fix input data alignment?" */
15284
  long cxp = (long) *((char**)xpp);
15285
15286
  realign = (cxp & 7) % SIZEOF_FLOAT;
15287
  /* sjl: manually stripmine so we can limit amount of
15288
   * vector work space reserved to LOOPCNT elements. Also
15289
   * makes vectorisation easy */
15290
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15291
    ni=Min(nelems-j,LOOPCNT);
15292
    if (realign) {
15293
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15294
      xp = tmp;
15295
    } else {
15296
      xp = (float *) *xpp;
15297
    }
15298
   /* copy the next block */
15299
#pragma cdir loopcnt=LOOPCNT
15300
#pragma cdir shortloop
15301
    for (i=0; i<ni; i++) {
15302
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
15303
     /* test for range errors (not always needed but do it anyway) */
15304
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15305
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15306
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
15307
    }
15308
   /* update xpp and tp */
15309
    if (realign) xp = (float *) *xpp;
15310
    xp += ni;
15311
    tp += ni;
15312
    *xpp = (void*)xp;
15313
  }
15314
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15315
15316
#else   /* not SX */
15317
0
  const char *xp = (const char *) *xpp;
15318
0
  int status = NC_NOERR;
15319
15320
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15321
0
  {
15322
0
    const int lstatus = ncx_get_float_double(xp, tp);
15323
0
    if (status == NC_NOERR) /* report the first encountered error */
15324
0
      status = lstatus;
15325
0
  }
15326
15327
0
  *xpp = (const void *)xp;
15328
0
  return status;
15329
0
#endif
15330
0
}
15331
15332
int
15333
ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp)
15334
0
{
15335
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15336
15337
 /* basic algorithm is:
15338
  *   - ensure sane alignment of input data
15339
  *   - copy (conversion happens automatically) input data
15340
  *     to output
15341
  *   - update xpp to point at next unconverted input, and tp to point
15342
  *     at next location for converted output
15343
  */
15344
  long i, j, ni;
15345
  float tmp[LOOPCNT];        /* in case input is misaligned */
15346
  float *xp;
15347
  int nrange = 0;         /* number of range errors */
15348
  int realign = 0;        /* "do we need to fix input data alignment?" */
15349
  long cxp = (long) *((char**)xpp);
15350
15351
  realign = (cxp & 7) % SIZEOF_FLOAT;
15352
  /* sjl: manually stripmine so we can limit amount of
15353
   * vector work space reserved to LOOPCNT elements. Also
15354
   * makes vectorisation easy */
15355
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15356
    ni=Min(nelems-j,LOOPCNT);
15357
    if (realign) {
15358
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15359
      xp = tmp;
15360
    } else {
15361
      xp = (float *) *xpp;
15362
    }
15363
   /* copy the next block */
15364
#pragma cdir loopcnt=LOOPCNT
15365
#pragma cdir shortloop
15366
    for (i=0; i<ni; i++) {
15367
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
15368
     /* test for range errors (not always needed but do it anyway) */
15369
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15370
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15371
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
15372
    }
15373
   /* update xpp and tp */
15374
    if (realign) xp = (float *) *xpp;
15375
    xp += ni;
15376
    tp += ni;
15377
    *xpp = (void*)xp;
15378
  }
15379
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15380
15381
#else   /* not SX */
15382
0
  const char *xp = (const char *) *xpp;
15383
0
  int status = NC_NOERR;
15384
15385
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15386
0
  {
15387
0
    const int lstatus = ncx_get_float_longlong(xp, tp);
15388
0
    if (status == NC_NOERR) /* report the first encountered error */
15389
0
      status = lstatus;
15390
0
  }
15391
15392
0
  *xpp = (const void *)xp;
15393
0
  return status;
15394
0
#endif
15395
0
}
15396
15397
int
15398
ncx_getn_float_ushort(const void **xpp, size_t nelems, ushort *tp)
15399
0
{
15400
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15401
15402
 /* basic algorithm is:
15403
  *   - ensure sane alignment of input data
15404
  *   - copy (conversion happens automatically) input data
15405
  *     to output
15406
  *   - update xpp to point at next unconverted input, and tp to point
15407
  *     at next location for converted output
15408
  */
15409
  long i, j, ni;
15410
  float tmp[LOOPCNT];        /* in case input is misaligned */
15411
  float *xp;
15412
  int nrange = 0;         /* number of range errors */
15413
  int realign = 0;        /* "do we need to fix input data alignment?" */
15414
  long cxp = (long) *((char**)xpp);
15415
15416
  realign = (cxp & 7) % SIZEOF_FLOAT;
15417
  /* sjl: manually stripmine so we can limit amount of
15418
   * vector work space reserved to LOOPCNT elements. Also
15419
   * makes vectorisation easy */
15420
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15421
    ni=Min(nelems-j,LOOPCNT);
15422
    if (realign) {
15423
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15424
      xp = tmp;
15425
    } else {
15426
      xp = (float *) *xpp;
15427
    }
15428
   /* copy the next block */
15429
#pragma cdir loopcnt=LOOPCNT
15430
#pragma cdir shortloop
15431
    for (i=0; i<ni; i++) {
15432
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
15433
     /* test for range errors (not always needed but do it anyway) */
15434
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15435
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15436
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
15437
    }
15438
   /* update xpp and tp */
15439
    if (realign) xp = (float *) *xpp;
15440
    xp += ni;
15441
    tp += ni;
15442
    *xpp = (void*)xp;
15443
  }
15444
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15445
15446
#else   /* not SX */
15447
0
  const char *xp = (const char *) *xpp;
15448
0
  int status = NC_NOERR;
15449
15450
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15451
0
  {
15452
0
    const int lstatus = ncx_get_float_ushort(xp, tp);
15453
0
    if (status == NC_NOERR) /* report the first encountered error */
15454
0
      status = lstatus;
15455
0
  }
15456
15457
0
  *xpp = (const void *)xp;
15458
0
  return status;
15459
0
#endif
15460
0
}
15461
15462
int
15463
ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
15464
0
{
15465
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15466
15467
 /* basic algorithm is:
15468
  *   - ensure sane alignment of input data
15469
  *   - copy (conversion happens automatically) input data
15470
  *     to output
15471
  *   - update xpp to point at next unconverted input, and tp to point
15472
  *     at next location for converted output
15473
  */
15474
  long i, j, ni;
15475
  float tmp[LOOPCNT];        /* in case input is misaligned */
15476
  float *xp;
15477
  int nrange = 0;         /* number of range errors */
15478
  int realign = 0;        /* "do we need to fix input data alignment?" */
15479
  long cxp = (long) *((char**)xpp);
15480
15481
  realign = (cxp & 7) % SIZEOF_FLOAT;
15482
  /* sjl: manually stripmine so we can limit amount of
15483
   * vector work space reserved to LOOPCNT elements. Also
15484
   * makes vectorisation easy */
15485
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15486
    ni=Min(nelems-j,LOOPCNT);
15487
    if (realign) {
15488
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15489
      xp = tmp;
15490
    } else {
15491
      xp = (float *) *xpp;
15492
    }
15493
   /* copy the next block */
15494
#pragma cdir loopcnt=LOOPCNT
15495
#pragma cdir shortloop
15496
    for (i=0; i<ni; i++) {
15497
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
15498
     /* test for range errors (not always needed but do it anyway) */
15499
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15500
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15501
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
15502
    }
15503
   /* update xpp and tp */
15504
    if (realign) xp = (float *) *xpp;
15505
    xp += ni;
15506
    tp += ni;
15507
    *xpp = (void*)xp;
15508
  }
15509
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15510
15511
#else   /* not SX */
15512
0
  const char *xp = (const char *) *xpp;
15513
0
  int status = NC_NOERR;
15514
15515
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15516
0
  {
15517
0
    const int lstatus = ncx_get_float_uchar(xp, tp);
15518
0
    if (status == NC_NOERR) /* report the first encountered error */
15519
0
      status = lstatus;
15520
0
  }
15521
15522
0
  *xpp = (const void *)xp;
15523
0
  return status;
15524
0
#endif
15525
0
}
15526
15527
int
15528
ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp)
15529
0
{
15530
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15531
15532
 /* basic algorithm is:
15533
  *   - ensure sane alignment of input data
15534
  *   - copy (conversion happens automatically) input data
15535
  *     to output
15536
  *   - update xpp to point at next unconverted input, and tp to point
15537
  *     at next location for converted output
15538
  */
15539
  long i, j, ni;
15540
  float tmp[LOOPCNT];        /* in case input is misaligned */
15541
  float *xp;
15542
  int nrange = 0;         /* number of range errors */
15543
  int realign = 0;        /* "do we need to fix input data alignment?" */
15544
  long cxp = (long) *((char**)xpp);
15545
15546
  realign = (cxp & 7) % SIZEOF_FLOAT;
15547
  /* sjl: manually stripmine so we can limit amount of
15548
   * vector work space reserved to LOOPCNT elements. Also
15549
   * makes vectorisation easy */
15550
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15551
    ni=Min(nelems-j,LOOPCNT);
15552
    if (realign) {
15553
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15554
      xp = tmp;
15555
    } else {
15556
      xp = (float *) *xpp;
15557
    }
15558
   /* copy the next block */
15559
#pragma cdir loopcnt=LOOPCNT
15560
#pragma cdir shortloop
15561
    for (i=0; i<ni; i++) {
15562
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
15563
     /* test for range errors (not always needed but do it anyway) */
15564
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15565
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15566
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
15567
    }
15568
   /* update xpp and tp */
15569
    if (realign) xp = (float *) *xpp;
15570
    xp += ni;
15571
    tp += ni;
15572
    *xpp = (void*)xp;
15573
  }
15574
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15575
15576
#else   /* not SX */
15577
0
  const char *xp = (const char *) *xpp;
15578
0
  int status = NC_NOERR;
15579
15580
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15581
0
  {
15582
0
    const int lstatus = ncx_get_float_uint(xp, tp);
15583
0
    if (status == NC_NOERR) /* report the first encountered error */
15584
0
      status = lstatus;
15585
0
  }
15586
15587
0
  *xpp = (const void *)xp;
15588
0
  return status;
15589
0
#endif
15590
0
}
15591
15592
int
15593
ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
15594
0
{
15595
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15596
15597
 /* basic algorithm is:
15598
  *   - ensure sane alignment of input data
15599
  *   - copy (conversion happens automatically) input data
15600
  *     to output
15601
  *   - update xpp to point at next unconverted input, and tp to point
15602
  *     at next location for converted output
15603
  */
15604
  long i, j, ni;
15605
  float tmp[LOOPCNT];        /* in case input is misaligned */
15606
  float *xp;
15607
  int nrange = 0;         /* number of range errors */
15608
  int realign = 0;        /* "do we need to fix input data alignment?" */
15609
  long cxp = (long) *((char**)xpp);
15610
15611
  realign = (cxp & 7) % SIZEOF_FLOAT;
15612
  /* sjl: manually stripmine so we can limit amount of
15613
   * vector work space reserved to LOOPCNT elements. Also
15614
   * makes vectorisation easy */
15615
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15616
    ni=Min(nelems-j,LOOPCNT);
15617
    if (realign) {
15618
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15619
      xp = tmp;
15620
    } else {
15621
      xp = (float *) *xpp;
15622
    }
15623
   /* copy the next block */
15624
#pragma cdir loopcnt=LOOPCNT
15625
#pragma cdir shortloop
15626
    for (i=0; i<ni; i++) {
15627
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
15628
     /* test for range errors (not always needed but do it anyway) */
15629
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15630
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15631
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
15632
    }
15633
   /* update xpp and tp */
15634
    if (realign) xp = (float *) *xpp;
15635
    xp += ni;
15636
    tp += ni;
15637
    *xpp = (void*)xp;
15638
  }
15639
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15640
15641
#else   /* not SX */
15642
0
  const char *xp = (const char *) *xpp;
15643
0
  int status = NC_NOERR;
15644
15645
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15646
0
  {
15647
0
    const int lstatus = ncx_get_float_ulonglong(xp, tp);
15648
0
    if (status == NC_NOERR) /* report the first encountered error */
15649
0
      status = lstatus;
15650
0
  }
15651
15652
0
  *xpp = (const void *)xp;
15653
0
  return status;
15654
0
#endif
15655
0
}
15656
15657
15658
int
15659
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
15660
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
15661
/* optimized version */
15662
0
{
15663
#ifdef WORDS_BIGENDIAN
15664
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
15665
# else
15666
0
  swapn4b(*xpp, tp, nelems);
15667
0
# endif
15668
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
15669
0
  return NC_NOERR;
15670
0
}
15671
#elif defined(vax) && vax != 0
15672
{
15673
  const float *const end = tp + nelems;
15674
15675
  while (tp < end) {
15676
        const struct vax_single *const vsp =
15677
       (const struct vax_single *)ip;
15678
    struct ieee_single *const isp = (struct ieee_single *) (*xpp);
15679
15680
    switch(vsp->exp){
15681
    case 0 :
15682
      /* all vax float with zero exponent map to zero */
15683
      *isp = min.ieee;
15684
      break;
15685
    case 2 :
15686
    case 1 :
15687
    {
15688
      /* These will map to subnormals */
15689
      unsigned mantissa = (vsp->mantissa1 << 16)
15690
           | vsp->mantissa2;
15691
      mantissa >>= 3 - vsp->exp;
15692
      mantissa += (1 << (20 + vsp->exp));
15693
      isp->mant_lo_lo = mantissa;
15694
      isp->mant_lo_hi = mantissa >> 8;
15695
      isp->mant_hi = mantissa >> 16;
15696
      isp->exp_lo = 0;
15697
      isp->exp_hi = 0;
15698
    }
15699
      break;
15700
    case 0xff : /* max.s.exp */
15701
      if (vsp->mantissa2 == max.s.mantissa2 &&
15702
          vsp->mantissa1 == max.s.mantissa1)
15703
      {
15704
        /* map largest vax float to ieee infinity */
15705
        *isp = max.ieee;
15706
        break;
15707
      } /* else, fall thru */
15708
    default :
15709
    {
15710
      unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
15711
      isp->exp_hi = exp >> 1;
15712
      isp->exp_lo = exp;
15713
      isp->mant_lo_lo = vsp->mantissa2;
15714
      isp->mant_lo_hi = vsp->mantissa2 >> 8;
15715
      isp->mant_hi = vsp->mantissa1;
15716
    }
15717
    }
15718
15719
    isp->sign = vsp->sign;
15720
15721
    tp++;
15722
    *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
15723
  }
15724
  return NC_NOERR;
15725
}
15726
#else
15727
{
15728
  char *xp = *xpp;
15729
  int status = NC_NOERR;
15730
15731
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
15732
    int lstatus = ncx_put_float_float(xp, tp, fillp);
15733
    if (status == NC_NOERR) /* report the first encountered error */
15734
      status = lstatus;
15735
  }
15736
15737
  *xpp = (void *)xp;
15738
  return status;
15739
}
15740
#endif
15741
int
15742
ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
15743
0
{
15744
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15745
15746
 /* basic algorithm is:
15747
  *   - ensure sane alignment of output data
15748
  *   - copy (conversion happens automatically) input data
15749
  *     to output
15750
  *   - update tp to point at next unconverted input, and xpp to point
15751
  *     at next location for converted output
15752
  */
15753
  long i, j, ni;
15754
  float tmp[LOOPCNT];        /* in case input is misaligned */
15755
  float *xp;
15756
  int nrange = 0;         /* number of range errors */
15757
  int realign = 0;        /* "do we need to fix input data alignment?" */
15758
  long cxp = (long) *((char**)xpp);
15759
15760
  realign = (cxp & 7) % SIZEOF_FLOAT;
15761
  /* sjl: manually stripmine so we can limit amount of
15762
   * vector work space reserved to LOOPCNT elements. Also
15763
   * makes vectorisation easy */
15764
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15765
    ni=Min(nelems-j,LOOPCNT);
15766
    if (realign) {
15767
      xp = tmp;
15768
    } else {
15769
      xp = (float *) *xpp;
15770
    }
15771
   /* copy the next block */
15772
#pragma cdir loopcnt=LOOPCNT
15773
#pragma cdir shortloop
15774
    for (i=0; i<ni; i++) {
15775
      /* the normal case: */
15776
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15777
     /* test for range errors (not always needed but do it anyway) */
15778
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15779
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15780
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15781
    }
15782
   /* copy workspace back if necessary */
15783
    if (realign) {
15784
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15785
      xp = (float *) *xpp;
15786
    }
15787
   /* update xpp and tp */
15788
    xp += ni;
15789
    tp += ni;
15790
    *xpp = (void*)xp;
15791
  }
15792
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15793
15794
#else   /* not SX */
15795
15796
0
  char *xp = (char *) *xpp;
15797
0
  int status = NC_NOERR;
15798
15799
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15800
0
  {
15801
0
    int lstatus = ncx_put_float_schar(xp, tp, fillp);
15802
0
    if (status == NC_NOERR) /* report the first encountered error */
15803
0
      status = lstatus;
15804
0
  }
15805
15806
0
  *xpp = (void *)xp;
15807
0
  return status;
15808
0
#endif
15809
0
}
15810
15811
int
15812
ncx_putn_float_short(void **xpp, size_t nelems, const short *tp, void *fillp)
15813
0
{
15814
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15815
15816
 /* basic algorithm is:
15817
  *   - ensure sane alignment of output data
15818
  *   - copy (conversion happens automatically) input data
15819
  *     to output
15820
  *   - update tp to point at next unconverted input, and xpp to point
15821
  *     at next location for converted output
15822
  */
15823
  long i, j, ni;
15824
  float tmp[LOOPCNT];        /* in case input is misaligned */
15825
  float *xp;
15826
  int nrange = 0;         /* number of range errors */
15827
  int realign = 0;        /* "do we need to fix input data alignment?" */
15828
  long cxp = (long) *((char**)xpp);
15829
15830
  realign = (cxp & 7) % SIZEOF_FLOAT;
15831
  /* sjl: manually stripmine so we can limit amount of
15832
   * vector work space reserved to LOOPCNT elements. Also
15833
   * makes vectorisation easy */
15834
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15835
    ni=Min(nelems-j,LOOPCNT);
15836
    if (realign) {
15837
      xp = tmp;
15838
    } else {
15839
      xp = (float *) *xpp;
15840
    }
15841
   /* copy the next block */
15842
#pragma cdir loopcnt=LOOPCNT
15843
#pragma cdir shortloop
15844
    for (i=0; i<ni; i++) {
15845
      /* the normal case: */
15846
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15847
     /* test for range errors (not always needed but do it anyway) */
15848
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15849
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15850
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15851
    }
15852
   /* copy workspace back if necessary */
15853
    if (realign) {
15854
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15855
      xp = (float *) *xpp;
15856
    }
15857
   /* update xpp and tp */
15858
    xp += ni;
15859
    tp += ni;
15860
    *xpp = (void*)xp;
15861
  }
15862
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15863
15864
#else   /* not SX */
15865
15866
0
  char *xp = (char *) *xpp;
15867
0
  int status = NC_NOERR;
15868
15869
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15870
0
  {
15871
0
    int lstatus = ncx_put_float_short(xp, tp, fillp);
15872
0
    if (status == NC_NOERR) /* report the first encountered error */
15873
0
      status = lstatus;
15874
0
  }
15875
15876
0
  *xpp = (void *)xp;
15877
0
  return status;
15878
0
#endif
15879
0
}
15880
15881
int
15882
ncx_putn_float_int(void **xpp, size_t nelems, const int *tp, void *fillp)
15883
0
{
15884
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15885
15886
 /* basic algorithm is:
15887
  *   - ensure sane alignment of output data
15888
  *   - copy (conversion happens automatically) input data
15889
  *     to output
15890
  *   - update tp to point at next unconverted input, and xpp to point
15891
  *     at next location for converted output
15892
  */
15893
  long i, j, ni;
15894
  float tmp[LOOPCNT];        /* in case input is misaligned */
15895
  float *xp;
15896
  int nrange = 0;         /* number of range errors */
15897
  int realign = 0;        /* "do we need to fix input data alignment?" */
15898
  long cxp = (long) *((char**)xpp);
15899
15900
  realign = (cxp & 7) % SIZEOF_FLOAT;
15901
  /* sjl: manually stripmine so we can limit amount of
15902
   * vector work space reserved to LOOPCNT elements. Also
15903
   * makes vectorisation easy */
15904
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15905
    ni=Min(nelems-j,LOOPCNT);
15906
    if (realign) {
15907
      xp = tmp;
15908
    } else {
15909
      xp = (float *) *xpp;
15910
    }
15911
   /* copy the next block */
15912
#pragma cdir loopcnt=LOOPCNT
15913
#pragma cdir shortloop
15914
    for (i=0; i<ni; i++) {
15915
      /* the normal case: */
15916
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15917
     /* test for range errors (not always needed but do it anyway) */
15918
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15919
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15920
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15921
    }
15922
   /* copy workspace back if necessary */
15923
    if (realign) {
15924
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15925
      xp = (float *) *xpp;
15926
    }
15927
   /* update xpp and tp */
15928
    xp += ni;
15929
    tp += ni;
15930
    *xpp = (void*)xp;
15931
  }
15932
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
15933
15934
#else   /* not SX */
15935
15936
0
  char *xp = (char *) *xpp;
15937
0
  int status = NC_NOERR;
15938
15939
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15940
0
  {
15941
0
    int lstatus = ncx_put_float_int(xp, tp, fillp);
15942
0
    if (status == NC_NOERR) /* report the first encountered error */
15943
0
      status = lstatus;
15944
0
  }
15945
15946
0
  *xpp = (void *)xp;
15947
0
  return status;
15948
0
#endif
15949
0
}
15950
15951
int
15952
ncx_putn_float_long(void **xpp, size_t nelems, const long *tp, void *fillp)
15953
0
{
15954
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15955
15956
 /* basic algorithm is:
15957
  *   - ensure sane alignment of output data
15958
  *   - copy (conversion happens automatically) input data
15959
  *     to output
15960
  *   - update tp to point at next unconverted input, and xpp to point
15961
  *     at next location for converted output
15962
  */
15963
  long i, j, ni;
15964
  float tmp[LOOPCNT];        /* in case input is misaligned */
15965
  float *xp;
15966
  int nrange = 0;         /* number of range errors */
15967
  int realign = 0;        /* "do we need to fix input data alignment?" */
15968
  long cxp = (long) *((char**)xpp);
15969
15970
  realign = (cxp & 7) % SIZEOF_FLOAT;
15971
  /* sjl: manually stripmine so we can limit amount of
15972
   * vector work space reserved to LOOPCNT elements. Also
15973
   * makes vectorisation easy */
15974
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15975
    ni=Min(nelems-j,LOOPCNT);
15976
    if (realign) {
15977
      xp = tmp;
15978
    } else {
15979
      xp = (float *) *xpp;
15980
    }
15981
   /* copy the next block */
15982
#pragma cdir loopcnt=LOOPCNT
15983
#pragma cdir shortloop
15984
    for (i=0; i<ni; i++) {
15985
      /* the normal case: */
15986
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15987
     /* test for range errors (not always needed but do it anyway) */
15988
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15989
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15990
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15991
    }
15992
   /* copy workspace back if necessary */
15993
    if (realign) {
15994
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15995
      xp = (float *) *xpp;
15996
    }
15997
   /* update xpp and tp */
15998
    xp += ni;
15999
    tp += ni;
16000
    *xpp = (void*)xp;
16001
  }
16002
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16003
16004
#else   /* not SX */
16005
16006
0
  char *xp = (char *) *xpp;
16007
0
  int status = NC_NOERR;
16008
16009
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16010
0
  {
16011
0
    int lstatus = ncx_put_float_long(xp, tp, fillp);
16012
0
    if (status == NC_NOERR) /* report the first encountered error */
16013
0
      status = lstatus;
16014
0
  }
16015
16016
0
  *xpp = (void *)xp;
16017
0
  return status;
16018
0
#endif
16019
0
}
16020
16021
int
16022
ncx_putn_float_double(void **xpp, size_t nelems, const double *tp, void *fillp)
16023
0
{
16024
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16025
16026
 /* basic algorithm is:
16027
  *   - ensure sane alignment of output data
16028
  *   - copy (conversion happens automatically) input data
16029
  *     to output
16030
  *   - update tp to point at next unconverted input, and xpp to point
16031
  *     at next location for converted output
16032
  */
16033
  long i, j, ni;
16034
  float tmp[LOOPCNT];        /* in case input is misaligned */
16035
  float *xp;
16036
  int nrange = 0;         /* number of range errors */
16037
  int realign = 0;        /* "do we need to fix input data alignment?" */
16038
  long cxp = (long) *((char**)xpp);
16039
16040
  realign = (cxp & 7) % SIZEOF_FLOAT;
16041
  /* sjl: manually stripmine so we can limit amount of
16042
   * vector work space reserved to LOOPCNT elements. Also
16043
   * makes vectorisation easy */
16044
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16045
    ni=Min(nelems-j,LOOPCNT);
16046
    if (realign) {
16047
      xp = tmp;
16048
    } else {
16049
      xp = (float *) *xpp;
16050
    }
16051
   /* copy the next block */
16052
#pragma cdir loopcnt=LOOPCNT
16053
#pragma cdir shortloop
16054
    for (i=0; i<ni; i++) {
16055
      /* the normal case: */
16056
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16057
     /* test for range errors (not always needed but do it anyway) */
16058
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16059
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16060
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
16061
    }
16062
   /* copy workspace back if necessary */
16063
    if (realign) {
16064
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16065
      xp = (float *) *xpp;
16066
    }
16067
   /* update xpp and tp */
16068
    xp += ni;
16069
    tp += ni;
16070
    *xpp = (void*)xp;
16071
  }
16072
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16073
16074
#else   /* not SX */
16075
16076
0
  char *xp = (char *) *xpp;
16077
0
  int status = NC_NOERR;
16078
16079
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16080
0
  {
16081
0
    int lstatus = ncx_put_float_double(xp, tp, fillp);
16082
0
    if (status == NC_NOERR) /* report the first encountered error */
16083
0
      status = lstatus;
16084
0
  }
16085
16086
0
  *xpp = (void *)xp;
16087
0
  return status;
16088
0
#endif
16089
0
}
16090
16091
int
16092
ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
16093
0
{
16094
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16095
16096
 /* basic algorithm is:
16097
  *   - ensure sane alignment of output data
16098
  *   - copy (conversion happens automatically) input data
16099
  *     to output
16100
  *   - update tp to point at next unconverted input, and xpp to point
16101
  *     at next location for converted output
16102
  */
16103
  long i, j, ni;
16104
  float tmp[LOOPCNT];        /* in case input is misaligned */
16105
  float *xp;
16106
  int nrange = 0;         /* number of range errors */
16107
  int realign = 0;        /* "do we need to fix input data alignment?" */
16108
  long cxp = (long) *((char**)xpp);
16109
16110
  realign = (cxp & 7) % SIZEOF_FLOAT;
16111
  /* sjl: manually stripmine so we can limit amount of
16112
   * vector work space reserved to LOOPCNT elements. Also
16113
   * makes vectorisation easy */
16114
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16115
    ni=Min(nelems-j,LOOPCNT);
16116
    if (realign) {
16117
      xp = tmp;
16118
    } else {
16119
      xp = (float *) *xpp;
16120
    }
16121
   /* copy the next block */
16122
#pragma cdir loopcnt=LOOPCNT
16123
#pragma cdir shortloop
16124
    for (i=0; i<ni; i++) {
16125
      /* the normal case: */
16126
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16127
     /* test for range errors (not always needed but do it anyway) */
16128
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16129
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16130
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
16131
    }
16132
   /* copy workspace back if necessary */
16133
    if (realign) {
16134
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16135
      xp = (float *) *xpp;
16136
    }
16137
   /* update xpp and tp */
16138
    xp += ni;
16139
    tp += ni;
16140
    *xpp = (void*)xp;
16141
  }
16142
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16143
16144
#else   /* not SX */
16145
16146
0
  char *xp = (char *) *xpp;
16147
0
  int status = NC_NOERR;
16148
16149
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16150
0
  {
16151
0
    int lstatus = ncx_put_float_longlong(xp, tp, fillp);
16152
0
    if (status == NC_NOERR) /* report the first encountered error */
16153
0
      status = lstatus;
16154
0
  }
16155
16156
0
  *xpp = (void *)xp;
16157
0
  return status;
16158
0
#endif
16159
0
}
16160
16161
int
16162
ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
16163
0
{
16164
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16165
16166
 /* basic algorithm is:
16167
  *   - ensure sane alignment of output data
16168
  *   - copy (conversion happens automatically) input data
16169
  *     to output
16170
  *   - update tp to point at next unconverted input, and xpp to point
16171
  *     at next location for converted output
16172
  */
16173
  long i, j, ni;
16174
  float tmp[LOOPCNT];        /* in case input is misaligned */
16175
  float *xp;
16176
  int nrange = 0;         /* number of range errors */
16177
  int realign = 0;        /* "do we need to fix input data alignment?" */
16178
  long cxp = (long) *((char**)xpp);
16179
16180
  realign = (cxp & 7) % SIZEOF_FLOAT;
16181
  /* sjl: manually stripmine so we can limit amount of
16182
   * vector work space reserved to LOOPCNT elements. Also
16183
   * makes vectorisation easy */
16184
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16185
    ni=Min(nelems-j,LOOPCNT);
16186
    if (realign) {
16187
      xp = tmp;
16188
    } else {
16189
      xp = (float *) *xpp;
16190
    }
16191
   /* copy the next block */
16192
#pragma cdir loopcnt=LOOPCNT
16193
#pragma cdir shortloop
16194
    for (i=0; i<ni; i++) {
16195
      /* the normal case: */
16196
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16197
     /* test for range errors (not always needed but do it anyway) */
16198
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16199
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16200
      nrange += tp[i] > X_FLOAT_MAX ;
16201
    }
16202
   /* copy workspace back if necessary */
16203
    if (realign) {
16204
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16205
      xp = (float *) *xpp;
16206
    }
16207
   /* update xpp and tp */
16208
    xp += ni;
16209
    tp += ni;
16210
    *xpp = (void*)xp;
16211
  }
16212
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16213
16214
#else   /* not SX */
16215
16216
0
  char *xp = (char *) *xpp;
16217
0
  int status = NC_NOERR;
16218
16219
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16220
0
  {
16221
0
    int lstatus = ncx_put_float_uchar(xp, tp, fillp);
16222
0
    if (status == NC_NOERR) /* report the first encountered error */
16223
0
      status = lstatus;
16224
0
  }
16225
16226
0
  *xpp = (void *)xp;
16227
0
  return status;
16228
0
#endif
16229
0
}
16230
16231
int
16232
ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
16233
0
{
16234
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16235
16236
 /* basic algorithm is:
16237
  *   - ensure sane alignment of output data
16238
  *   - copy (conversion happens automatically) input data
16239
  *     to output
16240
  *   - update tp to point at next unconverted input, and xpp to point
16241
  *     at next location for converted output
16242
  */
16243
  long i, j, ni;
16244
  float tmp[LOOPCNT];        /* in case input is misaligned */
16245
  float *xp;
16246
  int nrange = 0;         /* number of range errors */
16247
  int realign = 0;        /* "do we need to fix input data alignment?" */
16248
  long cxp = (long) *((char**)xpp);
16249
16250
  realign = (cxp & 7) % SIZEOF_FLOAT;
16251
  /* sjl: manually stripmine so we can limit amount of
16252
   * vector work space reserved to LOOPCNT elements. Also
16253
   * makes vectorisation easy */
16254
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16255
    ni=Min(nelems-j,LOOPCNT);
16256
    if (realign) {
16257
      xp = tmp;
16258
    } else {
16259
      xp = (float *) *xpp;
16260
    }
16261
   /* copy the next block */
16262
#pragma cdir loopcnt=LOOPCNT
16263
#pragma cdir shortloop
16264
    for (i=0; i<ni; i++) {
16265
      /* the normal case: */
16266
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16267
     /* test for range errors (not always needed but do it anyway) */
16268
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16269
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16270
      nrange += tp[i] > X_FLOAT_MAX ;
16271
    }
16272
   /* copy workspace back if necessary */
16273
    if (realign) {
16274
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16275
      xp = (float *) *xpp;
16276
    }
16277
   /* update xpp and tp */
16278
    xp += ni;
16279
    tp += ni;
16280
    *xpp = (void*)xp;
16281
  }
16282
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16283
16284
#else   /* not SX */
16285
16286
0
  char *xp = (char *) *xpp;
16287
0
  int status = NC_NOERR;
16288
16289
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16290
0
  {
16291
0
    int lstatus = ncx_put_float_ushort(xp, tp, fillp);
16292
0
    if (status == NC_NOERR) /* report the first encountered error */
16293
0
      status = lstatus;
16294
0
  }
16295
16296
0
  *xpp = (void *)xp;
16297
0
  return status;
16298
0
#endif
16299
0
}
16300
16301
int
16302
ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
16303
0
{
16304
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16305
16306
 /* basic algorithm is:
16307
  *   - ensure sane alignment of output data
16308
  *   - copy (conversion happens automatically) input data
16309
  *     to output
16310
  *   - update tp to point at next unconverted input, and xpp to point
16311
  *     at next location for converted output
16312
  */
16313
  long i, j, ni;
16314
  float tmp[LOOPCNT];        /* in case input is misaligned */
16315
  float *xp;
16316
  int nrange = 0;         /* number of range errors */
16317
  int realign = 0;        /* "do we need to fix input data alignment?" */
16318
  long cxp = (long) *((char**)xpp);
16319
16320
  realign = (cxp & 7) % SIZEOF_FLOAT;
16321
  /* sjl: manually stripmine so we can limit amount of
16322
   * vector work space reserved to LOOPCNT elements. Also
16323
   * makes vectorisation easy */
16324
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16325
    ni=Min(nelems-j,LOOPCNT);
16326
    if (realign) {
16327
      xp = tmp;
16328
    } else {
16329
      xp = (float *) *xpp;
16330
    }
16331
   /* copy the next block */
16332
#pragma cdir loopcnt=LOOPCNT
16333
#pragma cdir shortloop
16334
    for (i=0; i<ni; i++) {
16335
      /* the normal case: */
16336
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16337
     /* test for range errors (not always needed but do it anyway) */
16338
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16339
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16340
      nrange += tp[i] > X_FLOAT_MAX ;
16341
    }
16342
   /* copy workspace back if necessary */
16343
    if (realign) {
16344
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16345
      xp = (float *) *xpp;
16346
    }
16347
   /* update xpp and tp */
16348
    xp += ni;
16349
    tp += ni;
16350
    *xpp = (void*)xp;
16351
  }
16352
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16353
16354
#else   /* not SX */
16355
16356
0
  char *xp = (char *) *xpp;
16357
0
  int status = NC_NOERR;
16358
16359
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16360
0
  {
16361
0
    int lstatus = ncx_put_float_uint(xp, tp, fillp);
16362
0
    if (status == NC_NOERR) /* report the first encountered error */
16363
0
      status = lstatus;
16364
0
  }
16365
16366
0
  *xpp = (void *)xp;
16367
0
  return status;
16368
0
#endif
16369
0
}
16370
16371
int
16372
ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
16373
0
{
16374
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16375
16376
 /* basic algorithm is:
16377
  *   - ensure sane alignment of output data
16378
  *   - copy (conversion happens automatically) input data
16379
  *     to output
16380
  *   - update tp to point at next unconverted input, and xpp to point
16381
  *     at next location for converted output
16382
  */
16383
  long i, j, ni;
16384
  float tmp[LOOPCNT];        /* in case input is misaligned */
16385
  float *xp;
16386
  int nrange = 0;         /* number of range errors */
16387
  int realign = 0;        /* "do we need to fix input data alignment?" */
16388
  long cxp = (long) *((char**)xpp);
16389
16390
  realign = (cxp & 7) % SIZEOF_FLOAT;
16391
  /* sjl: manually stripmine so we can limit amount of
16392
   * vector work space reserved to LOOPCNT elements. Also
16393
   * makes vectorisation easy */
16394
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16395
    ni=Min(nelems-j,LOOPCNT);
16396
    if (realign) {
16397
      xp = tmp;
16398
    } else {
16399
      xp = (float *) *xpp;
16400
    }
16401
   /* copy the next block */
16402
#pragma cdir loopcnt=LOOPCNT
16403
#pragma cdir shortloop
16404
    for (i=0; i<ni; i++) {
16405
      /* the normal case: */
16406
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16407
     /* test for range errors (not always needed but do it anyway) */
16408
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16409
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16410
      nrange += tp[i] > X_FLOAT_MAX ;
16411
    }
16412
   /* copy workspace back if necessary */
16413
    if (realign) {
16414
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16415
      xp = (float *) *xpp;
16416
    }
16417
   /* update xpp and tp */
16418
    xp += ni;
16419
    tp += ni;
16420
    *xpp = (void*)xp;
16421
  }
16422
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16423
16424
#else   /* not SX */
16425
16426
0
  char *xp = (char *) *xpp;
16427
0
  int status = NC_NOERR;
16428
16429
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16430
0
  {
16431
0
    int lstatus = ncx_put_float_ulonglong(xp, tp, fillp);
16432
0
    if (status == NC_NOERR) /* report the first encountered error */
16433
0
      status = lstatus;
16434
0
  }
16435
16436
0
  *xpp = (void *)xp;
16437
0
  return status;
16438
0
#endif
16439
0
}
16440
16441
16442
/* double --------------------------------------------------------------------*/
16443
16444
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16445
/* optimized version */
16446
int
16447
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16448
0
{
16449
#ifdef WORDS_BIGENDIAN
16450
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
16451
# else
16452
0
  swapn8b(tp, *xpp, nelems);
16453
0
# endif
16454
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16455
0
  return NC_NOERR;
16456
0
}
16457
#elif defined(vax) && vax != 0
16458
int
16459
ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
16460
{
16461
  double *const end = ip + ndoubles;
16462
16463
  while (ip < end)
16464
  {
16465
  struct vax_double *const vdp =
16466
       (struct vax_double *)ip;
16467
  const struct ieee_double *const idp =
16468
       (const struct ieee_double *) (*xpp);
16469
  {
16470
    const struct dbl_limits *lim;
16471
    int ii;
16472
    for (ii = 0, lim = dbl_limits;
16473
      ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
16474
      ii++, lim++)
16475
    {
16476
      if ((idp->mant_lo == lim->ieee.mant_lo)
16477
        && (idp->mant_4 == lim->ieee.mant_4)
16478
        && (idp->mant_5 == lim->ieee.mant_5)
16479
        && (idp->mant_6 == lim->ieee.mant_6)
16480
        && (idp->exp_lo == lim->ieee.exp_lo)
16481
        && (idp->exp_hi == lim->ieee.exp_hi)
16482
        )
16483
      {
16484
        *vdp = lim->d;
16485
        goto doneit;
16486
      }
16487
    }
16488
  }
16489
  {
16490
    unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
16491
    vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
16492
  }
16493
  {
16494
    unsigned mant_hi = ((idp->mant_6 << 16)
16495
         | (idp->mant_5 << 8)
16496
         | idp->mant_4);
16497
    unsigned mant_lo = SWAP4(idp->mant_lo);
16498
    vdp->mantissa1 = (mant_hi >> 13);
16499
    vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
16500
        | (mant_lo >> 29);
16501
    vdp->mantissa3 = (mant_lo >> 13);
16502
    vdp->mantissa4 = (mant_lo << 3);
16503
  }
16504
  doneit:
16505
    vdp->sign = idp->sign;
16506
16507
    ip++;
16508
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
16509
  }
16510
  return NC_NOERR;
16511
}
16512
  /* vax */
16513
#else
16514
int
16515
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16516
{
16517
  const char *xp = *xpp;
16518
  int status = NC_NOERR;
16519
16520
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16521
  {
16522
    const int lstatus = ncx_get_double_double(xp, tp, fillp);
16523
    if (status == NC_NOERR) /* report the first encountered error */
16524
      status = lstatus;
16525
  }
16526
16527
  *xpp = (const void *)xp;
16528
  return status;
16529
}
16530
#endif
16531
int
16532
ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
16533
0
{
16534
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16535
16536
 /* basic algorithm is:
16537
  *   - ensure sane alignment of input data
16538
  *   - copy (conversion happens automatically) input data
16539
  *     to output
16540
  *   - update xpp to point at next unconverted input, and tp to point
16541
  *     at next location for converted output
16542
  */
16543
  long i, j, ni;
16544
  double tmp[LOOPCNT];        /* in case input is misaligned */
16545
  double *xp;
16546
  int nrange = 0;         /* number of range errors */
16547
  int realign = 0;        /* "do we need to fix input data alignment?" */
16548
  long cxp = (long) *((char**)xpp);
16549
16550
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16551
  /* sjl: manually stripmine so we can limit amount of
16552
   * vector work space reserved to LOOPCNT elements. Also
16553
   * makes vectorisation easy */
16554
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16555
    ni=Min(nelems-j,LOOPCNT);
16556
    if (realign) {
16557
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16558
      xp = tmp;
16559
    } else {
16560
      xp = (double *) *xpp;
16561
    }
16562
   /* copy the next block */
16563
#pragma cdir loopcnt=LOOPCNT
16564
#pragma cdir shortloop
16565
    for (i=0; i<ni; i++) {
16566
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
16567
     /* test for range errors (not always needed but do it anyway) */
16568
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16569
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16570
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
16571
    }
16572
   /* update xpp and tp */
16573
    if (realign) xp = (double *) *xpp;
16574
    xp += ni;
16575
    tp += ni;
16576
    *xpp = (void*)xp;
16577
  }
16578
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16579
16580
#else   /* not SX */
16581
0
  const char *xp = (const char *) *xpp;
16582
0
  int status = NC_NOERR;
16583
16584
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16585
0
  {
16586
0
    const int lstatus = ncx_get_double_schar(xp, tp);
16587
0
    if (status == NC_NOERR) /* report the first encountered error */
16588
0
      status = lstatus;
16589
0
  }
16590
16591
0
  *xpp = (const void *)xp;
16592
0
  return status;
16593
0
#endif
16594
0
}
16595
16596
int
16597
ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
16598
0
{
16599
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16600
16601
 /* basic algorithm is:
16602
  *   - ensure sane alignment of input data
16603
  *   - copy (conversion happens automatically) input data
16604
  *     to output
16605
  *   - update xpp to point at next unconverted input, and tp to point
16606
  *     at next location for converted output
16607
  */
16608
  long i, j, ni;
16609
  double tmp[LOOPCNT];        /* in case input is misaligned */
16610
  double *xp;
16611
  int nrange = 0;         /* number of range errors */
16612
  int realign = 0;        /* "do we need to fix input data alignment?" */
16613
  long cxp = (long) *((char**)xpp);
16614
16615
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16616
  /* sjl: manually stripmine so we can limit amount of
16617
   * vector work space reserved to LOOPCNT elements. Also
16618
   * makes vectorisation easy */
16619
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16620
    ni=Min(nelems-j,LOOPCNT);
16621
    if (realign) {
16622
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16623
      xp = tmp;
16624
    } else {
16625
      xp = (double *) *xpp;
16626
    }
16627
   /* copy the next block */
16628
#pragma cdir loopcnt=LOOPCNT
16629
#pragma cdir shortloop
16630
    for (i=0; i<ni; i++) {
16631
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
16632
     /* test for range errors (not always needed but do it anyway) */
16633
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16634
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16635
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
16636
    }
16637
   /* update xpp and tp */
16638
    if (realign) xp = (double *) *xpp;
16639
    xp += ni;
16640
    tp += ni;
16641
    *xpp = (void*)xp;
16642
  }
16643
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16644
16645
#else   /* not SX */
16646
0
  const char *xp = (const char *) *xpp;
16647
0
  int status = NC_NOERR;
16648
16649
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16650
0
  {
16651
0
    const int lstatus = ncx_get_double_short(xp, tp);
16652
0
    if (status == NC_NOERR) /* report the first encountered error */
16653
0
      status = lstatus;
16654
0
  }
16655
16656
0
  *xpp = (const void *)xp;
16657
0
  return status;
16658
0
#endif
16659
0
}
16660
16661
int
16662
ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
16663
0
{
16664
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16665
16666
 /* basic algorithm is:
16667
  *   - ensure sane alignment of input data
16668
  *   - copy (conversion happens automatically) input data
16669
  *     to output
16670
  *   - update xpp to point at next unconverted input, and tp to point
16671
  *     at next location for converted output
16672
  */
16673
  long i, j, ni;
16674
  double tmp[LOOPCNT];        /* in case input is misaligned */
16675
  double *xp;
16676
  int nrange = 0;         /* number of range errors */
16677
  int realign = 0;        /* "do we need to fix input data alignment?" */
16678
  long cxp = (long) *((char**)xpp);
16679
16680
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16681
  /* sjl: manually stripmine so we can limit amount of
16682
   * vector work space reserved to LOOPCNT elements. Also
16683
   * makes vectorisation easy */
16684
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16685
    ni=Min(nelems-j,LOOPCNT);
16686
    if (realign) {
16687
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16688
      xp = tmp;
16689
    } else {
16690
      xp = (double *) *xpp;
16691
    }
16692
   /* copy the next block */
16693
#pragma cdir loopcnt=LOOPCNT
16694
#pragma cdir shortloop
16695
    for (i=0; i<ni; i++) {
16696
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
16697
     /* test for range errors (not always needed but do it anyway) */
16698
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16699
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16700
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
16701
    }
16702
   /* update xpp and tp */
16703
    if (realign) xp = (double *) *xpp;
16704
    xp += ni;
16705
    tp += ni;
16706
    *xpp = (void*)xp;
16707
  }
16708
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16709
16710
#else   /* not SX */
16711
0
  const char *xp = (const char *) *xpp;
16712
0
  int status = NC_NOERR;
16713
16714
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16715
0
  {
16716
0
    const int lstatus = ncx_get_double_int(xp, tp);
16717
0
    if (status == NC_NOERR) /* report the first encountered error */
16718
0
      status = lstatus;
16719
0
  }
16720
16721
0
  *xpp = (const void *)xp;
16722
0
  return status;
16723
0
#endif
16724
0
}
16725
16726
int
16727
ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
16728
0
{
16729
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16730
16731
 /* basic algorithm is:
16732
  *   - ensure sane alignment of input data
16733
  *   - copy (conversion happens automatically) input data
16734
  *     to output
16735
  *   - update xpp to point at next unconverted input, and tp to point
16736
  *     at next location for converted output
16737
  */
16738
  long i, j, ni;
16739
  double tmp[LOOPCNT];        /* in case input is misaligned */
16740
  double *xp;
16741
  int nrange = 0;         /* number of range errors */
16742
  int realign = 0;        /* "do we need to fix input data alignment?" */
16743
  long cxp = (long) *((char**)xpp);
16744
16745
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16746
  /* sjl: manually stripmine so we can limit amount of
16747
   * vector work space reserved to LOOPCNT elements. Also
16748
   * makes vectorisation easy */
16749
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16750
    ni=Min(nelems-j,LOOPCNT);
16751
    if (realign) {
16752
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16753
      xp = tmp;
16754
    } else {
16755
      xp = (double *) *xpp;
16756
    }
16757
   /* copy the next block */
16758
#pragma cdir loopcnt=LOOPCNT
16759
#pragma cdir shortloop
16760
    for (i=0; i<ni; i++) {
16761
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
16762
     /* test for range errors (not always needed but do it anyway) */
16763
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16764
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16765
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
16766
    }
16767
   /* update xpp and tp */
16768
    if (realign) xp = (double *) *xpp;
16769
    xp += ni;
16770
    tp += ni;
16771
    *xpp = (void*)xp;
16772
  }
16773
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16774
16775
#else   /* not SX */
16776
0
  const char *xp = (const char *) *xpp;
16777
0
  int status = NC_NOERR;
16778
16779
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16780
0
  {
16781
0
    const int lstatus = ncx_get_double_long(xp, tp);
16782
0
    if (status == NC_NOERR) /* report the first encountered error */
16783
0
      status = lstatus;
16784
0
  }
16785
16786
0
  *xpp = (const void *)xp;
16787
0
  return status;
16788
0
#endif
16789
0
}
16790
16791
int
16792
ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
16793
0
{
16794
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16795
16796
 /* basic algorithm is:
16797
  *   - ensure sane alignment of input data
16798
  *   - copy (conversion happens automatically) input data
16799
  *     to output
16800
  *   - update xpp to point at next unconverted input, and tp to point
16801
  *     at next location for converted output
16802
  */
16803
  long i, j, ni;
16804
  double tmp[LOOPCNT];        /* in case input is misaligned */
16805
  double *xp;
16806
  int nrange = 0;         /* number of range errors */
16807
  int realign = 0;        /* "do we need to fix input data alignment?" */
16808
  long cxp = (long) *((char**)xpp);
16809
16810
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16811
  /* sjl: manually stripmine so we can limit amount of
16812
   * vector work space reserved to LOOPCNT elements. Also
16813
   * makes vectorisation easy */
16814
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16815
    ni=Min(nelems-j,LOOPCNT);
16816
    if (realign) {
16817
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16818
      xp = tmp;
16819
    } else {
16820
      xp = (double *) *xpp;
16821
    }
16822
   /* copy the next block */
16823
#pragma cdir loopcnt=LOOPCNT
16824
#pragma cdir shortloop
16825
    for (i=0; i<ni; i++) {
16826
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
16827
     /* test for range errors (not always needed but do it anyway) */
16828
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16829
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16830
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
16831
    }
16832
   /* update xpp and tp */
16833
    if (realign) xp = (double *) *xpp;
16834
    xp += ni;
16835
    tp += ni;
16836
    *xpp = (void*)xp;
16837
  }
16838
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16839
16840
#else   /* not SX */
16841
0
  const char *xp = (const char *) *xpp;
16842
0
  int status = NC_NOERR;
16843
16844
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16845
0
  {
16846
0
    const int lstatus = ncx_get_double_float(xp, tp);
16847
0
    if (status == NC_NOERR) /* report the first encountered error */
16848
0
      status = lstatus;
16849
0
  }
16850
16851
0
  *xpp = (const void *)xp;
16852
0
  return status;
16853
0
#endif
16854
0
}
16855
16856
int
16857
ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp)
16858
0
{
16859
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16860
16861
 /* basic algorithm is:
16862
  *   - ensure sane alignment of input data
16863
  *   - copy (conversion happens automatically) input data
16864
  *     to output
16865
  *   - update xpp to point at next unconverted input, and tp to point
16866
  *     at next location for converted output
16867
  */
16868
  long i, j, ni;
16869
  double tmp[LOOPCNT];        /* in case input is misaligned */
16870
  double *xp;
16871
  int nrange = 0;         /* number of range errors */
16872
  int realign = 0;        /* "do we need to fix input data alignment?" */
16873
  long cxp = (long) *((char**)xpp);
16874
16875
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16876
  /* sjl: manually stripmine so we can limit amount of
16877
   * vector work space reserved to LOOPCNT elements. Also
16878
   * makes vectorisation easy */
16879
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16880
    ni=Min(nelems-j,LOOPCNT);
16881
    if (realign) {
16882
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16883
      xp = tmp;
16884
    } else {
16885
      xp = (double *) *xpp;
16886
    }
16887
   /* copy the next block */
16888
#pragma cdir loopcnt=LOOPCNT
16889
#pragma cdir shortloop
16890
    for (i=0; i<ni; i++) {
16891
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
16892
     /* test for range errors (not always needed but do it anyway) */
16893
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16894
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16895
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
16896
    }
16897
   /* update xpp and tp */
16898
    if (realign) xp = (double *) *xpp;
16899
    xp += ni;
16900
    tp += ni;
16901
    *xpp = (void*)xp;
16902
  }
16903
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16904
16905
#else   /* not SX */
16906
0
  const char *xp = (const char *) *xpp;
16907
0
  int status = NC_NOERR;
16908
16909
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16910
0
  {
16911
0
    const int lstatus = ncx_get_double_longlong(xp, tp);
16912
0
    if (status == NC_NOERR) /* report the first encountered error */
16913
0
      status = lstatus;
16914
0
  }
16915
16916
0
  *xpp = (const void *)xp;
16917
0
  return status;
16918
0
#endif
16919
0
}
16920
16921
int
16922
ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
16923
0
{
16924
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16925
16926
 /* basic algorithm is:
16927
  *   - ensure sane alignment of input data
16928
  *   - copy (conversion happens automatically) input data
16929
  *     to output
16930
  *   - update xpp to point at next unconverted input, and tp to point
16931
  *     at next location for converted output
16932
  */
16933
  long i, j, ni;
16934
  double tmp[LOOPCNT];        /* in case input is misaligned */
16935
  double *xp;
16936
  int nrange = 0;         /* number of range errors */
16937
  int realign = 0;        /* "do we need to fix input data alignment?" */
16938
  long cxp = (long) *((char**)xpp);
16939
16940
  realign = (cxp & 7) % SIZEOF_DOUBLE;
16941
  /* sjl: manually stripmine so we can limit amount of
16942
   * vector work space reserved to LOOPCNT elements. Also
16943
   * makes vectorisation easy */
16944
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16945
    ni=Min(nelems-j,LOOPCNT);
16946
    if (realign) {
16947
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16948
      xp = tmp;
16949
    } else {
16950
      xp = (double *) *xpp;
16951
    }
16952
   /* copy the next block */
16953
#pragma cdir loopcnt=LOOPCNT
16954
#pragma cdir shortloop
16955
    for (i=0; i<ni; i++) {
16956
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
16957
     /* test for range errors (not always needed but do it anyway) */
16958
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16959
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16960
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
16961
    }
16962
   /* update xpp and tp */
16963
    if (realign) xp = (double *) *xpp;
16964
    xp += ni;
16965
    tp += ni;
16966
    *xpp = (void*)xp;
16967
  }
16968
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
16969
16970
#else   /* not SX */
16971
0
  const char *xp = (const char *) *xpp;
16972
0
  int status = NC_NOERR;
16973
16974
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16975
0
  {
16976
0
    const int lstatus = ncx_get_double_uchar(xp, tp);
16977
0
    if (status == NC_NOERR) /* report the first encountered error */
16978
0
      status = lstatus;
16979
0
  }
16980
16981
0
  *xpp = (const void *)xp;
16982
0
  return status;
16983
0
#endif
16984
0
}
16985
16986
int
16987
ncx_getn_double_ushort(const void **xpp, size_t nelems, ushort *tp)
16988
0
{
16989
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16990
16991
 /* basic algorithm is:
16992
  *   - ensure sane alignment of input data
16993
  *   - copy (conversion happens automatically) input data
16994
  *     to output
16995
  *   - update xpp to point at next unconverted input, and tp to point
16996
  *     at next location for converted output
16997
  */
16998
  long i, j, ni;
16999
  double tmp[LOOPCNT];        /* in case input is misaligned */
17000
  double *xp;
17001
  int nrange = 0;         /* number of range errors */
17002
  int realign = 0;        /* "do we need to fix input data alignment?" */
17003
  long cxp = (long) *((char**)xpp);
17004
17005
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17006
  /* sjl: manually stripmine so we can limit amount of
17007
   * vector work space reserved to LOOPCNT elements. Also
17008
   * makes vectorisation easy */
17009
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17010
    ni=Min(nelems-j,LOOPCNT);
17011
    if (realign) {
17012
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17013
      xp = tmp;
17014
    } else {
17015
      xp = (double *) *xpp;
17016
    }
17017
   /* copy the next block */
17018
#pragma cdir loopcnt=LOOPCNT
17019
#pragma cdir shortloop
17020
    for (i=0; i<ni; i++) {
17021
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
17022
     /* test for range errors (not always needed but do it anyway) */
17023
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17024
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17025
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
17026
    }
17027
   /* update xpp and tp */
17028
    if (realign) xp = (double *) *xpp;
17029
    xp += ni;
17030
    tp += ni;
17031
    *xpp = (void*)xp;
17032
  }
17033
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17034
17035
#else   /* not SX */
17036
0
  const char *xp = (const char *) *xpp;
17037
0
  int status = NC_NOERR;
17038
17039
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17040
0
  {
17041
0
    const int lstatus = ncx_get_double_ushort(xp, tp);
17042
0
    if (status == NC_NOERR) /* report the first encountered error */
17043
0
      status = lstatus;
17044
0
  }
17045
17046
0
  *xpp = (const void *)xp;
17047
0
  return status;
17048
0
#endif
17049
0
}
17050
17051
int
17052
ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp)
17053
0
{
17054
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17055
17056
 /* basic algorithm is:
17057
  *   - ensure sane alignment of input data
17058
  *   - copy (conversion happens automatically) input data
17059
  *     to output
17060
  *   - update xpp to point at next unconverted input, and tp to point
17061
  *     at next location for converted output
17062
  */
17063
  long i, j, ni;
17064
  double tmp[LOOPCNT];        /* in case input is misaligned */
17065
  double *xp;
17066
  int nrange = 0;         /* number of range errors */
17067
  int realign = 0;        /* "do we need to fix input data alignment?" */
17068
  long cxp = (long) *((char**)xpp);
17069
17070
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17071
  /* sjl: manually stripmine so we can limit amount of
17072
   * vector work space reserved to LOOPCNT elements. Also
17073
   * makes vectorisation easy */
17074
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17075
    ni=Min(nelems-j,LOOPCNT);
17076
    if (realign) {
17077
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17078
      xp = tmp;
17079
    } else {
17080
      xp = (double *) *xpp;
17081
    }
17082
   /* copy the next block */
17083
#pragma cdir loopcnt=LOOPCNT
17084
#pragma cdir shortloop
17085
    for (i=0; i<ni; i++) {
17086
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
17087
     /* test for range errors (not always needed but do it anyway) */
17088
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17089
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17090
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
17091
    }
17092
   /* update xpp and tp */
17093
    if (realign) xp = (double *) *xpp;
17094
    xp += ni;
17095
    tp += ni;
17096
    *xpp = (void*)xp;
17097
  }
17098
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17099
17100
#else   /* not SX */
17101
0
  const char *xp = (const char *) *xpp;
17102
0
  int status = NC_NOERR;
17103
17104
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17105
0
  {
17106
0
    const int lstatus = ncx_get_double_uint(xp, tp);
17107
0
    if (status == NC_NOERR) /* report the first encountered error */
17108
0
      status = lstatus;
17109
0
  }
17110
17111
0
  *xpp = (const void *)xp;
17112
0
  return status;
17113
0
#endif
17114
0
}
17115
17116
int
17117
ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
17118
0
{
17119
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17120
17121
 /* basic algorithm is:
17122
  *   - ensure sane alignment of input data
17123
  *   - copy (conversion happens automatically) input data
17124
  *     to output
17125
  *   - update xpp to point at next unconverted input, and tp to point
17126
  *     at next location for converted output
17127
  */
17128
  long i, j, ni;
17129
  double tmp[LOOPCNT];        /* in case input is misaligned */
17130
  double *xp;
17131
  int nrange = 0;         /* number of range errors */
17132
  int realign = 0;        /* "do we need to fix input data alignment?" */
17133
  long cxp = (long) *((char**)xpp);
17134
17135
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17136
  /* sjl: manually stripmine so we can limit amount of
17137
   * vector work space reserved to LOOPCNT elements. Also
17138
   * makes vectorisation easy */
17139
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17140
    ni=Min(nelems-j,LOOPCNT);
17141
    if (realign) {
17142
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17143
      xp = tmp;
17144
    } else {
17145
      xp = (double *) *xpp;
17146
    }
17147
   /* copy the next block */
17148
#pragma cdir loopcnt=LOOPCNT
17149
#pragma cdir shortloop
17150
    for (i=0; i<ni; i++) {
17151
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
17152
     /* test for range errors (not always needed but do it anyway) */
17153
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17154
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17155
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
17156
    }
17157
   /* update xpp and tp */
17158
    if (realign) xp = (double *) *xpp;
17159
    xp += ni;
17160
    tp += ni;
17161
    *xpp = (void*)xp;
17162
  }
17163
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17164
17165
#else   /* not SX */
17166
0
  const char *xp = (const char *) *xpp;
17167
0
  int status = NC_NOERR;
17168
17169
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17170
0
  {
17171
0
    const int lstatus = ncx_get_double_ulonglong(xp, tp);
17172
0
    if (status == NC_NOERR) /* report the first encountered error */
17173
0
      status = lstatus;
17174
0
  }
17175
17176
0
  *xpp = (const void *)xp;
17177
0
  return status;
17178
0
#endif
17179
0
}
17180
17181
17182
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
17183
/* optimized version */
17184
int
17185
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17186
0
{
17187
#ifdef WORDS_BIGENDIAN
17188
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
17189
# else
17190
0
  swapn8b(*xpp, tp, nelems);
17191
0
# endif
17192
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
17193
0
  return NC_NOERR;
17194
0
}
17195
#elif defined(vax) && vax != 0
17196
int
17197
ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip, void *fillp)
17198
{
17199
  const double *const end = ip + ndoubles;
17200
17201
  while (ip < end)
17202
  {
17203
  const struct vax_double *const vdp =
17204
      (const struct vax_double *)ip;
17205
  struct ieee_double *const idp =
17206
       (struct ieee_double *) (*xpp);
17207
17208
  if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
17209
    (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
17210
    (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
17211
    (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
17212
    (vdp->exp == dbl_limits[0].d.exp))
17213
  {
17214
    *idp = dbl_limits[0].ieee;
17215
    goto shipit;
17216
  }
17217
  if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
17218
    (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
17219
    (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
17220
    (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
17221
    (vdp->exp == dbl_limits[1].d.exp))
17222
  {
17223
    *idp = dbl_limits[1].ieee;
17224
    goto shipit;
17225
  }
17226
17227
  {
17228
    unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
17229
17230
    unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
17231
      (vdp->mantissa3 << 13) |
17232
      ((vdp->mantissa4 >> 3) & MASK(13));
17233
17234
    unsigned mant_hi = (vdp->mantissa1 << 13)
17235
         | (vdp->mantissa2 >> 3);
17236
17237
    if ((vdp->mantissa4 & 7) > 4)
17238
    {
17239
      /* round up */
17240
      mant_lo++;
17241
      if (mant_lo == 0)
17242
      {
17243
        mant_hi++;
17244
        if (mant_hi > 0xffffff)
17245
        {
17246
          mant_hi = 0;
17247
          exp++;
17248
        }
17249
      }
17250
    }
17251
17252
    idp->mant_lo = SWAP4(mant_lo);
17253
    idp->mant_6 = mant_hi >> 16;
17254
    idp->mant_5 = (mant_hi & 0xff00) >> 8;
17255
    idp->mant_4 = mant_hi;
17256
    idp->exp_hi = exp >> 4;
17257
    idp->exp_lo = exp;
17258
  }
17259
17260
  shipit:
17261
    idp->sign = vdp->sign;
17262
17263
    ip++;
17264
    *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
17265
  }
17266
  return NC_NOERR;
17267
}
17268
  /* vax */
17269
#else
17270
int
17271
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17272
{
17273
  char *xp = *xpp;
17274
  int status = NC_NOERR;
17275
17276
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17277
  {
17278
    int lstatus = ncx_put_double_double(xp, tp, fillp);
17279
    if (status == NC_NOERR) /* report the first encountered error */
17280
      status = lstatus;
17281
  }
17282
17283
  *xpp = (void *)xp;
17284
  return status;
17285
}
17286
#endif
17287
int
17288
ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
17289
0
{
17290
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17291
17292
 /* basic algorithm is:
17293
  *   - ensure sane alignment of output data
17294
  *   - copy (conversion happens automatically) input data
17295
  *     to output
17296
  *   - update tp to point at next unconverted input, and xpp to point
17297
  *     at next location for converted output
17298
  */
17299
  long i, j, ni;
17300
  double tmp[LOOPCNT];        /* in case input is misaligned */
17301
  double *xp;
17302
  int nrange = 0;         /* number of range errors */
17303
  int realign = 0;        /* "do we need to fix input data alignment?" */
17304
  long cxp = (long) *((char**)xpp);
17305
17306
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17307
  /* sjl: manually stripmine so we can limit amount of
17308
   * vector work space reserved to LOOPCNT elements. Also
17309
   * makes vectorisation easy */
17310
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17311
    ni=Min(nelems-j,LOOPCNT);
17312
    if (realign) {
17313
      xp = tmp;
17314
    } else {
17315
      xp = (double *) *xpp;
17316
    }
17317
   /* copy the next block */
17318
#pragma cdir loopcnt=LOOPCNT
17319
#pragma cdir shortloop
17320
    for (i=0; i<ni; i++) {
17321
      /* the normal case: */
17322
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17323
     /* test for range errors (not always needed but do it anyway) */
17324
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17325
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17326
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17327
    }
17328
   /* copy workspace back if necessary */
17329
    if (realign) {
17330
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17331
      xp = (double *) *xpp;
17332
    }
17333
   /* update xpp and tp */
17334
    xp += ni;
17335
    tp += ni;
17336
    *xpp = (void*)xp;
17337
  }
17338
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17339
17340
#else   /* not SX */
17341
17342
0
  char *xp = (char *) *xpp;
17343
0
  int status = NC_NOERR;
17344
17345
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17346
0
  {
17347
0
    int lstatus = ncx_put_double_schar(xp, tp, fillp);
17348
0
    if (status == NC_NOERR) /* report the first encountered error */
17349
0
      status = lstatus;
17350
0
  }
17351
17352
0
  *xpp = (void *)xp;
17353
0
  return status;
17354
0
#endif
17355
0
}
17356
17357
int
17358
ncx_putn_double_short(void **xpp, size_t nelems, const short *tp, void *fillp)
17359
0
{
17360
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17361
17362
 /* basic algorithm is:
17363
  *   - ensure sane alignment of output data
17364
  *   - copy (conversion happens automatically) input data
17365
  *     to output
17366
  *   - update tp to point at next unconverted input, and xpp to point
17367
  *     at next location for converted output
17368
  */
17369
  long i, j, ni;
17370
  double tmp[LOOPCNT];        /* in case input is misaligned */
17371
  double *xp;
17372
  int nrange = 0;         /* number of range errors */
17373
  int realign = 0;        /* "do we need to fix input data alignment?" */
17374
  long cxp = (long) *((char**)xpp);
17375
17376
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17377
  /* sjl: manually stripmine so we can limit amount of
17378
   * vector work space reserved to LOOPCNT elements. Also
17379
   * makes vectorisation easy */
17380
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17381
    ni=Min(nelems-j,LOOPCNT);
17382
    if (realign) {
17383
      xp = tmp;
17384
    } else {
17385
      xp = (double *) *xpp;
17386
    }
17387
   /* copy the next block */
17388
#pragma cdir loopcnt=LOOPCNT
17389
#pragma cdir shortloop
17390
    for (i=0; i<ni; i++) {
17391
      /* the normal case: */
17392
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17393
     /* test for range errors (not always needed but do it anyway) */
17394
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17395
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17396
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17397
    }
17398
   /* copy workspace back if necessary */
17399
    if (realign) {
17400
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17401
      xp = (double *) *xpp;
17402
    }
17403
   /* update xpp and tp */
17404
    xp += ni;
17405
    tp += ni;
17406
    *xpp = (void*)xp;
17407
  }
17408
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17409
17410
#else   /* not SX */
17411
17412
0
  char *xp = (char *) *xpp;
17413
0
  int status = NC_NOERR;
17414
17415
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17416
0
  {
17417
0
    int lstatus = ncx_put_double_short(xp, tp, fillp);
17418
0
    if (status == NC_NOERR) /* report the first encountered error */
17419
0
      status = lstatus;
17420
0
  }
17421
17422
0
  *xpp = (void *)xp;
17423
0
  return status;
17424
0
#endif
17425
0
}
17426
17427
int
17428
ncx_putn_double_int(void **xpp, size_t nelems, const int *tp, void *fillp)
17429
0
{
17430
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17431
17432
 /* basic algorithm is:
17433
  *   - ensure sane alignment of output data
17434
  *   - copy (conversion happens automatically) input data
17435
  *     to output
17436
  *   - update tp to point at next unconverted input, and xpp to point
17437
  *     at next location for converted output
17438
  */
17439
  long i, j, ni;
17440
  double tmp[LOOPCNT];        /* in case input is misaligned */
17441
  double *xp;
17442
  int nrange = 0;         /* number of range errors */
17443
  int realign = 0;        /* "do we need to fix input data alignment?" */
17444
  long cxp = (long) *((char**)xpp);
17445
17446
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17447
  /* sjl: manually stripmine so we can limit amount of
17448
   * vector work space reserved to LOOPCNT elements. Also
17449
   * makes vectorisation easy */
17450
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17451
    ni=Min(nelems-j,LOOPCNT);
17452
    if (realign) {
17453
      xp = tmp;
17454
    } else {
17455
      xp = (double *) *xpp;
17456
    }
17457
   /* copy the next block */
17458
#pragma cdir loopcnt=LOOPCNT
17459
#pragma cdir shortloop
17460
    for (i=0; i<ni; i++) {
17461
      /* the normal case: */
17462
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17463
     /* test for range errors (not always needed but do it anyway) */
17464
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17465
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17466
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17467
    }
17468
   /* copy workspace back if necessary */
17469
    if (realign) {
17470
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17471
      xp = (double *) *xpp;
17472
    }
17473
   /* update xpp and tp */
17474
    xp += ni;
17475
    tp += ni;
17476
    *xpp = (void*)xp;
17477
  }
17478
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17479
17480
#else   /* not SX */
17481
17482
0
  char *xp = (char *) *xpp;
17483
0
  int status = NC_NOERR;
17484
17485
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17486
0
  {
17487
0
    int lstatus = ncx_put_double_int(xp, tp, fillp);
17488
0
    if (status == NC_NOERR) /* report the first encountered error */
17489
0
      status = lstatus;
17490
0
  }
17491
17492
0
  *xpp = (void *)xp;
17493
0
  return status;
17494
0
#endif
17495
0
}
17496
17497
int
17498
ncx_putn_double_long(void **xpp, size_t nelems, const long *tp, void *fillp)
17499
0
{
17500
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17501
17502
 /* basic algorithm is:
17503
  *   - ensure sane alignment of output data
17504
  *   - copy (conversion happens automatically) input data
17505
  *     to output
17506
  *   - update tp to point at next unconverted input, and xpp to point
17507
  *     at next location for converted output
17508
  */
17509
  long i, j, ni;
17510
  double tmp[LOOPCNT];        /* in case input is misaligned */
17511
  double *xp;
17512
  int nrange = 0;         /* number of range errors */
17513
  int realign = 0;        /* "do we need to fix input data alignment?" */
17514
  long cxp = (long) *((char**)xpp);
17515
17516
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17517
  /* sjl: manually stripmine so we can limit amount of
17518
   * vector work space reserved to LOOPCNT elements. Also
17519
   * makes vectorisation easy */
17520
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17521
    ni=Min(nelems-j,LOOPCNT);
17522
    if (realign) {
17523
      xp = tmp;
17524
    } else {
17525
      xp = (double *) *xpp;
17526
    }
17527
   /* copy the next block */
17528
#pragma cdir loopcnt=LOOPCNT
17529
#pragma cdir shortloop
17530
    for (i=0; i<ni; i++) {
17531
      /* the normal case: */
17532
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17533
     /* test for range errors (not always needed but do it anyway) */
17534
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17535
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17536
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17537
    }
17538
   /* copy workspace back if necessary */
17539
    if (realign) {
17540
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17541
      xp = (double *) *xpp;
17542
    }
17543
   /* update xpp and tp */
17544
    xp += ni;
17545
    tp += ni;
17546
    *xpp = (void*)xp;
17547
  }
17548
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17549
17550
#else   /* not SX */
17551
17552
0
  char *xp = (char *) *xpp;
17553
0
  int status = NC_NOERR;
17554
17555
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17556
0
  {
17557
0
    int lstatus = ncx_put_double_long(xp, tp, fillp);
17558
0
    if (status == NC_NOERR) /* report the first encountered error */
17559
0
      status = lstatus;
17560
0
  }
17561
17562
0
  *xpp = (void *)xp;
17563
0
  return status;
17564
0
#endif
17565
0
}
17566
17567
int
17568
ncx_putn_double_float(void **xpp, size_t nelems, const float *tp, void *fillp)
17569
0
{
17570
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17571
17572
 /* basic algorithm is:
17573
  *   - ensure sane alignment of output data
17574
  *   - copy (conversion happens automatically) input data
17575
  *     to output
17576
  *   - update tp to point at next unconverted input, and xpp to point
17577
  *     at next location for converted output
17578
  */
17579
  long i, j, ni;
17580
  double tmp[LOOPCNT];        /* in case input is misaligned */
17581
  double *xp;
17582
  int nrange = 0;         /* number of range errors */
17583
  int realign = 0;        /* "do we need to fix input data alignment?" */
17584
  long cxp = (long) *((char**)xpp);
17585
17586
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17587
  /* sjl: manually stripmine so we can limit amount of
17588
   * vector work space reserved to LOOPCNT elements. Also
17589
   * makes vectorisation easy */
17590
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17591
    ni=Min(nelems-j,LOOPCNT);
17592
    if (realign) {
17593
      xp = tmp;
17594
    } else {
17595
      xp = (double *) *xpp;
17596
    }
17597
   /* copy the next block */
17598
#pragma cdir loopcnt=LOOPCNT
17599
#pragma cdir shortloop
17600
    for (i=0; i<ni; i++) {
17601
      /* the normal case: */
17602
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17603
     /* test for range errors (not always needed but do it anyway) */
17604
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17605
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17606
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17607
    }
17608
   /* copy workspace back if necessary */
17609
    if (realign) {
17610
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17611
      xp = (double *) *xpp;
17612
    }
17613
   /* update xpp and tp */
17614
    xp += ni;
17615
    tp += ni;
17616
    *xpp = (void*)xp;
17617
  }
17618
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17619
17620
#else   /* not SX */
17621
17622
0
  char *xp = (char *) *xpp;
17623
0
  int status = NC_NOERR;
17624
17625
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17626
0
  {
17627
0
    int lstatus = ncx_put_double_float(xp, tp, fillp);
17628
0
    if (status == NC_NOERR) /* report the first encountered error */
17629
0
      status = lstatus;
17630
0
  }
17631
17632
0
  *xpp = (void *)xp;
17633
0
  return status;
17634
0
#endif
17635
0
}
17636
17637
int
17638
ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
17639
0
{
17640
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17641
17642
 /* basic algorithm is:
17643
  *   - ensure sane alignment of output data
17644
  *   - copy (conversion happens automatically) input data
17645
  *     to output
17646
  *   - update tp to point at next unconverted input, and xpp to point
17647
  *     at next location for converted output
17648
  */
17649
  long i, j, ni;
17650
  double tmp[LOOPCNT];        /* in case input is misaligned */
17651
  double *xp;
17652
  int nrange = 0;         /* number of range errors */
17653
  int realign = 0;        /* "do we need to fix input data alignment?" */
17654
  long cxp = (long) *((char**)xpp);
17655
17656
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17657
  /* sjl: manually stripmine so we can limit amount of
17658
   * vector work space reserved to LOOPCNT elements. Also
17659
   * makes vectorisation easy */
17660
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17661
    ni=Min(nelems-j,LOOPCNT);
17662
    if (realign) {
17663
      xp = tmp;
17664
    } else {
17665
      xp = (double *) *xpp;
17666
    }
17667
   /* copy the next block */
17668
#pragma cdir loopcnt=LOOPCNT
17669
#pragma cdir shortloop
17670
    for (i=0; i<ni; i++) {
17671
      /* the normal case: */
17672
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17673
     /* test for range errors (not always needed but do it anyway) */
17674
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17675
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17676
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17677
    }
17678
   /* copy workspace back if necessary */
17679
    if (realign) {
17680
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17681
      xp = (double *) *xpp;
17682
    }
17683
   /* update xpp and tp */
17684
    xp += ni;
17685
    tp += ni;
17686
    *xpp = (void*)xp;
17687
  }
17688
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17689
17690
#else   /* not SX */
17691
17692
0
  char *xp = (char *) *xpp;
17693
0
  int status = NC_NOERR;
17694
17695
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17696
0
  {
17697
0
    int lstatus = ncx_put_double_longlong(xp, tp, fillp);
17698
0
    if (status == NC_NOERR) /* report the first encountered error */
17699
0
      status = lstatus;
17700
0
  }
17701
17702
0
  *xpp = (void *)xp;
17703
0
  return status;
17704
0
#endif
17705
0
}
17706
17707
int
17708
ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
17709
0
{
17710
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17711
17712
 /* basic algorithm is:
17713
  *   - ensure sane alignment of output data
17714
  *   - copy (conversion happens automatically) input data
17715
  *     to output
17716
  *   - update tp to point at next unconverted input, and xpp to point
17717
  *     at next location for converted output
17718
  */
17719
  long i, j, ni;
17720
  double tmp[LOOPCNT];        /* in case input is misaligned */
17721
  double *xp;
17722
  int nrange = 0;         /* number of range errors */
17723
  int realign = 0;        /* "do we need to fix input data alignment?" */
17724
  long cxp = (long) *((char**)xpp);
17725
17726
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17727
  /* sjl: manually stripmine so we can limit amount of
17728
   * vector work space reserved to LOOPCNT elements. Also
17729
   * makes vectorisation easy */
17730
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17731
    ni=Min(nelems-j,LOOPCNT);
17732
    if (realign) {
17733
      xp = tmp;
17734
    } else {
17735
      xp = (double *) *xpp;
17736
    }
17737
   /* copy the next block */
17738
#pragma cdir loopcnt=LOOPCNT
17739
#pragma cdir shortloop
17740
    for (i=0; i<ni; i++) {
17741
      /* the normal case: */
17742
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17743
     /* test for range errors (not always needed but do it anyway) */
17744
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17745
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17746
      nrange += tp[i] > X_DOUBLE_MAX ;
17747
    }
17748
   /* copy workspace back if necessary */
17749
    if (realign) {
17750
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17751
      xp = (double *) *xpp;
17752
    }
17753
   /* update xpp and tp */
17754
    xp += ni;
17755
    tp += ni;
17756
    *xpp = (void*)xp;
17757
  }
17758
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17759
17760
#else   /* not SX */
17761
17762
0
  char *xp = (char *) *xpp;
17763
0
  int status = NC_NOERR;
17764
17765
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17766
0
  {
17767
0
    int lstatus = ncx_put_double_uchar(xp, tp, fillp);
17768
0
    if (status == NC_NOERR) /* report the first encountered error */
17769
0
      status = lstatus;
17770
0
  }
17771
17772
0
  *xpp = (void *)xp;
17773
0
  return status;
17774
0
#endif
17775
0
}
17776
17777
int
17778
ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
17779
0
{
17780
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17781
17782
 /* basic algorithm is:
17783
  *   - ensure sane alignment of output data
17784
  *   - copy (conversion happens automatically) input data
17785
  *     to output
17786
  *   - update tp to point at next unconverted input, and xpp to point
17787
  *     at next location for converted output
17788
  */
17789
  long i, j, ni;
17790
  double tmp[LOOPCNT];        /* in case input is misaligned */
17791
  double *xp;
17792
  int nrange = 0;         /* number of range errors */
17793
  int realign = 0;        /* "do we need to fix input data alignment?" */
17794
  long cxp = (long) *((char**)xpp);
17795
17796
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17797
  /* sjl: manually stripmine so we can limit amount of
17798
   * vector work space reserved to LOOPCNT elements. Also
17799
   * makes vectorisation easy */
17800
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17801
    ni=Min(nelems-j,LOOPCNT);
17802
    if (realign) {
17803
      xp = tmp;
17804
    } else {
17805
      xp = (double *) *xpp;
17806
    }
17807
   /* copy the next block */
17808
#pragma cdir loopcnt=LOOPCNT
17809
#pragma cdir shortloop
17810
    for (i=0; i<ni; i++) {
17811
      /* the normal case: */
17812
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17813
     /* test for range errors (not always needed but do it anyway) */
17814
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17815
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17816
      nrange += tp[i] > X_DOUBLE_MAX ;
17817
    }
17818
   /* copy workspace back if necessary */
17819
    if (realign) {
17820
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17821
      xp = (double *) *xpp;
17822
    }
17823
   /* update xpp and tp */
17824
    xp += ni;
17825
    tp += ni;
17826
    *xpp = (void*)xp;
17827
  }
17828
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17829
17830
#else   /* not SX */
17831
17832
0
  char *xp = (char *) *xpp;
17833
0
  int status = NC_NOERR;
17834
17835
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17836
0
  {
17837
0
    int lstatus = ncx_put_double_ushort(xp, tp, fillp);
17838
0
    if (status == NC_NOERR) /* report the first encountered error */
17839
0
      status = lstatus;
17840
0
  }
17841
17842
0
  *xpp = (void *)xp;
17843
0
  return status;
17844
0
#endif
17845
0
}
17846
17847
int
17848
ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
17849
0
{
17850
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17851
17852
 /* basic algorithm is:
17853
  *   - ensure sane alignment of output data
17854
  *   - copy (conversion happens automatically) input data
17855
  *     to output
17856
  *   - update tp to point at next unconverted input, and xpp to point
17857
  *     at next location for converted output
17858
  */
17859
  long i, j, ni;
17860
  double tmp[LOOPCNT];        /* in case input is misaligned */
17861
  double *xp;
17862
  int nrange = 0;         /* number of range errors */
17863
  int realign = 0;        /* "do we need to fix input data alignment?" */
17864
  long cxp = (long) *((char**)xpp);
17865
17866
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17867
  /* sjl: manually stripmine so we can limit amount of
17868
   * vector work space reserved to LOOPCNT elements. Also
17869
   * makes vectorisation easy */
17870
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17871
    ni=Min(nelems-j,LOOPCNT);
17872
    if (realign) {
17873
      xp = tmp;
17874
    } else {
17875
      xp = (double *) *xpp;
17876
    }
17877
   /* copy the next block */
17878
#pragma cdir loopcnt=LOOPCNT
17879
#pragma cdir shortloop
17880
    for (i=0; i<ni; i++) {
17881
      /* the normal case: */
17882
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17883
     /* test for range errors (not always needed but do it anyway) */
17884
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17885
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17886
      nrange += tp[i] > X_DOUBLE_MAX ;
17887
    }
17888
   /* copy workspace back if necessary */
17889
    if (realign) {
17890
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17891
      xp = (double *) *xpp;
17892
    }
17893
   /* update xpp and tp */
17894
    xp += ni;
17895
    tp += ni;
17896
    *xpp = (void*)xp;
17897
  }
17898
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17899
17900
#else   /* not SX */
17901
17902
0
  char *xp = (char *) *xpp;
17903
0
  int status = NC_NOERR;
17904
17905
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17906
0
  {
17907
0
    int lstatus = ncx_put_double_uint(xp, tp, fillp);
17908
0
    if (status == NC_NOERR) /* report the first encountered error */
17909
0
      status = lstatus;
17910
0
  }
17911
17912
0
  *xpp = (void *)xp;
17913
0
  return status;
17914
0
#endif
17915
0
}
17916
17917
int
17918
ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
17919
0
{
17920
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17921
17922
 /* basic algorithm is:
17923
  *   - ensure sane alignment of output data
17924
  *   - copy (conversion happens automatically) input data
17925
  *     to output
17926
  *   - update tp to point at next unconverted input, and xpp to point
17927
  *     at next location for converted output
17928
  */
17929
  long i, j, ni;
17930
  double tmp[LOOPCNT];        /* in case input is misaligned */
17931
  double *xp;
17932
  int nrange = 0;         /* number of range errors */
17933
  int realign = 0;        /* "do we need to fix input data alignment?" */
17934
  long cxp = (long) *((char**)xpp);
17935
17936
  realign = (cxp & 7) % SIZEOF_DOUBLE;
17937
  /* sjl: manually stripmine so we can limit amount of
17938
   * vector work space reserved to LOOPCNT elements. Also
17939
   * makes vectorisation easy */
17940
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17941
    ni=Min(nelems-j,LOOPCNT);
17942
    if (realign) {
17943
      xp = tmp;
17944
    } else {
17945
      xp = (double *) *xpp;
17946
    }
17947
   /* copy the next block */
17948
#pragma cdir loopcnt=LOOPCNT
17949
#pragma cdir shortloop
17950
    for (i=0; i<ni; i++) {
17951
      /* the normal case: */
17952
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17953
     /* test for range errors (not always needed but do it anyway) */
17954
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17955
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17956
      nrange += tp[i] > X_DOUBLE_MAX ;
17957
    }
17958
   /* copy workspace back if necessary */
17959
    if (realign) {
17960
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17961
      xp = (double *) *xpp;
17962
    }
17963
   /* update xpp and tp */
17964
    xp += ni;
17965
    tp += ni;
17966
    *xpp = (void*)xp;
17967
  }
17968
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
17969
17970
#else   /* not SX */
17971
17972
0
  char *xp = (char *) *xpp;
17973
0
  int status = NC_NOERR;
17974
17975
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17976
0
  {
17977
0
    int lstatus = ncx_put_double_ulonglong(xp, tp, fillp);
17978
0
    if (status == NC_NOERR) /* report the first encountered error */
17979
0
      status = lstatus;
17980
0
  }
17981
17982
0
  *xpp = (void *)xp;
17983
0
  return status;
17984
0
#endif
17985
0
}
17986
17987
17988
17989
/* longlong ------------------------------------------------------------------*/
17990
17991
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
17992
/* optimized version */
17993
int
17994
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
17995
0
{
17996
#ifdef WORDS_BIGENDIAN
17997
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
17998
# else
17999
0
  swapn8b(tp, *xpp, nelems);
18000
0
# endif
18001
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
18002
0
  return NC_NOERR;
18003
0
}
18004
#else
18005
int
18006
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, longlong *tp)
18007
{
18008
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18009
18010
 /* basic algorithm is:
18011
  *   - ensure sane alignment of input data
18012
  *   - copy (conversion happens automatically) input data
18013
  *     to output
18014
  *   - update xpp to point at next unconverted input, and tp to point
18015
  *     at next location for converted output
18016
  */
18017
  long i, j, ni;
18018
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18019
  int64 *xp;
18020
  int nrange = 0;         /* number of range errors */
18021
  int realign = 0;        /* "do we need to fix input data alignment?" */
18022
  long cxp = (long) *((char**)xpp);
18023
18024
  realign = (cxp & 7) % SIZEOF_INT64;
18025
  /* sjl: manually stripmine so we can limit amount of
18026
   * vector work space reserved to LOOPCNT elements. Also
18027
   * makes vectorisation easy */
18028
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18029
    ni=Min(nelems-j,LOOPCNT);
18030
    if (realign) {
18031
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18032
      xp = tmp;
18033
    } else {
18034
      xp = (int64 *) *xpp;
18035
    }
18036
   /* copy the next block */
18037
#pragma cdir loopcnt=LOOPCNT
18038
#pragma cdir shortloop
18039
    for (i=0; i<ni; i++) {
18040
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
18041
     /* test for range errors (not always needed but do it anyway) */
18042
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18043
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18044
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
18045
    }
18046
   /* update xpp and tp */
18047
    if (realign) xp = (int64 *) *xpp;
18048
    xp += ni;
18049
    tp += ni;
18050
    *xpp = (void*)xp;
18051
  }
18052
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18053
18054
#else   /* not SX */
18055
  const char *xp = (const char *) *xpp;
18056
  int status = NC_NOERR;
18057
18058
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18059
  {
18060
    const int lstatus = ncx_get_longlong_longlong(xp, tp);
18061
    if (status == NC_NOERR) /* report the first encountered error */
18062
      status = lstatus;
18063
  }
18064
18065
  *xpp = (const void *)xp;
18066
  return status;
18067
#endif
18068
}
18069
18070
#endif
18071
int
18072
ncx_getn_longlong_schar(const void **xpp, size_t nelems, schar *tp)
18073
0
{
18074
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18075
18076
 /* basic algorithm is:
18077
  *   - ensure sane alignment of input data
18078
  *   - copy (conversion happens automatically) input data
18079
  *     to output
18080
  *   - update xpp to point at next unconverted input, and tp to point
18081
  *     at next location for converted output
18082
  */
18083
  long i, j, ni;
18084
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18085
  int64 *xp;
18086
  int nrange = 0;         /* number of range errors */
18087
  int realign = 0;        /* "do we need to fix input data alignment?" */
18088
  long cxp = (long) *((char**)xpp);
18089
18090
  realign = (cxp & 7) % SIZEOF_INT64;
18091
  /* sjl: manually stripmine so we can limit amount of
18092
   * vector work space reserved to LOOPCNT elements. Also
18093
   * makes vectorisation easy */
18094
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18095
    ni=Min(nelems-j,LOOPCNT);
18096
    if (realign) {
18097
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18098
      xp = tmp;
18099
    } else {
18100
      xp = (int64 *) *xpp;
18101
    }
18102
   /* copy the next block */
18103
#pragma cdir loopcnt=LOOPCNT
18104
#pragma cdir shortloop
18105
    for (i=0; i<ni; i++) {
18106
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
18107
     /* test for range errors (not always needed but do it anyway) */
18108
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18109
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18110
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
18111
    }
18112
   /* update xpp and tp */
18113
    if (realign) xp = (int64 *) *xpp;
18114
    xp += ni;
18115
    tp += ni;
18116
    *xpp = (void*)xp;
18117
  }
18118
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18119
18120
#else   /* not SX */
18121
0
  const char *xp = (const char *) *xpp;
18122
0
  int status = NC_NOERR;
18123
18124
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18125
0
  {
18126
0
    const int lstatus = ncx_get_longlong_schar(xp, tp);
18127
0
    if (status == NC_NOERR) /* report the first encountered error */
18128
0
      status = lstatus;
18129
0
  }
18130
18131
0
  *xpp = (const void *)xp;
18132
0
  return status;
18133
0
#endif
18134
0
}
18135
18136
int
18137
ncx_getn_longlong_short(const void **xpp, size_t nelems, short *tp)
18138
0
{
18139
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18140
18141
 /* basic algorithm is:
18142
  *   - ensure sane alignment of input data
18143
  *   - copy (conversion happens automatically) input data
18144
  *     to output
18145
  *   - update xpp to point at next unconverted input, and tp to point
18146
  *     at next location for converted output
18147
  */
18148
  long i, j, ni;
18149
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18150
  int64 *xp;
18151
  int nrange = 0;         /* number of range errors */
18152
  int realign = 0;        /* "do we need to fix input data alignment?" */
18153
  long cxp = (long) *((char**)xpp);
18154
18155
  realign = (cxp & 7) % SIZEOF_INT64;
18156
  /* sjl: manually stripmine so we can limit amount of
18157
   * vector work space reserved to LOOPCNT elements. Also
18158
   * makes vectorisation easy */
18159
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18160
    ni=Min(nelems-j,LOOPCNT);
18161
    if (realign) {
18162
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18163
      xp = tmp;
18164
    } else {
18165
      xp = (int64 *) *xpp;
18166
    }
18167
   /* copy the next block */
18168
#pragma cdir loopcnt=LOOPCNT
18169
#pragma cdir shortloop
18170
    for (i=0; i<ni; i++) {
18171
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
18172
     /* test for range errors (not always needed but do it anyway) */
18173
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18174
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18175
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
18176
    }
18177
   /* update xpp and tp */
18178
    if (realign) xp = (int64 *) *xpp;
18179
    xp += ni;
18180
    tp += ni;
18181
    *xpp = (void*)xp;
18182
  }
18183
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18184
18185
#else   /* not SX */
18186
0
  const char *xp = (const char *) *xpp;
18187
0
  int status = NC_NOERR;
18188
18189
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18190
0
  {
18191
0
    const int lstatus = ncx_get_longlong_short(xp, tp);
18192
0
    if (status == NC_NOERR) /* report the first encountered error */
18193
0
      status = lstatus;
18194
0
  }
18195
18196
0
  *xpp = (const void *)xp;
18197
0
  return status;
18198
0
#endif
18199
0
}
18200
18201
int
18202
ncx_getn_longlong_int(const void **xpp, size_t nelems, int *tp)
18203
6.82k
{
18204
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18205
18206
 /* basic algorithm is:
18207
  *   - ensure sane alignment of input data
18208
  *   - copy (conversion happens automatically) input data
18209
  *     to output
18210
  *   - update xpp to point at next unconverted input, and tp to point
18211
  *     at next location for converted output
18212
  */
18213
  long i, j, ni;
18214
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18215
  int64 *xp;
18216
  int nrange = 0;         /* number of range errors */
18217
  int realign = 0;        /* "do we need to fix input data alignment?" */
18218
  long cxp = (long) *((char**)xpp);
18219
18220
  realign = (cxp & 7) % SIZEOF_INT64;
18221
  /* sjl: manually stripmine so we can limit amount of
18222
   * vector work space reserved to LOOPCNT elements. Also
18223
   * makes vectorisation easy */
18224
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18225
    ni=Min(nelems-j,LOOPCNT);
18226
    if (realign) {
18227
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18228
      xp = tmp;
18229
    } else {
18230
      xp = (int64 *) *xpp;
18231
    }
18232
   /* copy the next block */
18233
#pragma cdir loopcnt=LOOPCNT
18234
#pragma cdir shortloop
18235
    for (i=0; i<ni; i++) {
18236
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
18237
     /* test for range errors (not always needed but do it anyway) */
18238
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18239
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18240
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
18241
    }
18242
   /* update xpp and tp */
18243
    if (realign) xp = (int64 *) *xpp;
18244
    xp += ni;
18245
    tp += ni;
18246
    *xpp = (void*)xp;
18247
  }
18248
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18249
18250
#else   /* not SX */
18251
6.82k
  const char *xp = (const char *) *xpp;
18252
6.82k
  int status = NC_NOERR;
18253
18254
86.0k
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18255
79.1k
  {
18256
79.1k
    const int lstatus = ncx_get_longlong_int(xp, tp);
18257
79.1k
    if (status == NC_NOERR) /* report the first encountered error */
18258
13.6k
      status = lstatus;
18259
79.1k
  }
18260
18261
6.82k
  *xpp = (const void *)xp;
18262
6.82k
  return status;
18263
6.82k
#endif
18264
6.82k
}
18265
18266
int
18267
ncx_getn_longlong_long(const void **xpp, size_t nelems, long *tp)
18268
0
{
18269
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18270
18271
 /* basic algorithm is:
18272
  *   - ensure sane alignment of input data
18273
  *   - copy (conversion happens automatically) input data
18274
  *     to output
18275
  *   - update xpp to point at next unconverted input, and tp to point
18276
  *     at next location for converted output
18277
  */
18278
  long i, j, ni;
18279
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18280
  int64 *xp;
18281
  int nrange = 0;         /* number of range errors */
18282
  int realign = 0;        /* "do we need to fix input data alignment?" */
18283
  long cxp = (long) *((char**)xpp);
18284
18285
  realign = (cxp & 7) % SIZEOF_INT64;
18286
  /* sjl: manually stripmine so we can limit amount of
18287
   * vector work space reserved to LOOPCNT elements. Also
18288
   * makes vectorisation easy */
18289
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18290
    ni=Min(nelems-j,LOOPCNT);
18291
    if (realign) {
18292
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18293
      xp = tmp;
18294
    } else {
18295
      xp = (int64 *) *xpp;
18296
    }
18297
   /* copy the next block */
18298
#pragma cdir loopcnt=LOOPCNT
18299
#pragma cdir shortloop
18300
    for (i=0; i<ni; i++) {
18301
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
18302
     /* test for range errors (not always needed but do it anyway) */
18303
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18304
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18305
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
18306
    }
18307
   /* update xpp and tp */
18308
    if (realign) xp = (int64 *) *xpp;
18309
    xp += ni;
18310
    tp += ni;
18311
    *xpp = (void*)xp;
18312
  }
18313
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18314
18315
#else   /* not SX */
18316
0
  const char *xp = (const char *) *xpp;
18317
0
  int status = NC_NOERR;
18318
18319
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18320
0
  {
18321
0
    const int lstatus = ncx_get_longlong_long(xp, tp);
18322
0
    if (status == NC_NOERR) /* report the first encountered error */
18323
0
      status = lstatus;
18324
0
  }
18325
18326
0
  *xpp = (const void *)xp;
18327
0
  return status;
18328
0
#endif
18329
0
}
18330
18331
int
18332
ncx_getn_longlong_float(const void **xpp, size_t nelems, float *tp)
18333
0
{
18334
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18335
18336
 /* basic algorithm is:
18337
  *   - ensure sane alignment of input data
18338
  *   - copy (conversion happens automatically) input data
18339
  *     to output
18340
  *   - update xpp to point at next unconverted input, and tp to point
18341
  *     at next location for converted output
18342
  */
18343
  long i, j, ni;
18344
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18345
  int64 *xp;
18346
  int nrange = 0;         /* number of range errors */
18347
  int realign = 0;        /* "do we need to fix input data alignment?" */
18348
  long cxp = (long) *((char**)xpp);
18349
18350
  realign = (cxp & 7) % SIZEOF_INT64;
18351
  /* sjl: manually stripmine so we can limit amount of
18352
   * vector work space reserved to LOOPCNT elements. Also
18353
   * makes vectorisation easy */
18354
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18355
    ni=Min(nelems-j,LOOPCNT);
18356
    if (realign) {
18357
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18358
      xp = tmp;
18359
    } else {
18360
      xp = (int64 *) *xpp;
18361
    }
18362
   /* copy the next block */
18363
#pragma cdir loopcnt=LOOPCNT
18364
#pragma cdir shortloop
18365
    for (i=0; i<ni; i++) {
18366
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
18367
     /* test for range errors (not always needed but do it anyway) */
18368
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18369
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18370
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
18371
    }
18372
   /* update xpp and tp */
18373
    if (realign) xp = (int64 *) *xpp;
18374
    xp += ni;
18375
    tp += ni;
18376
    *xpp = (void*)xp;
18377
  }
18378
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18379
18380
#else   /* not SX */
18381
0
  const char *xp = (const char *) *xpp;
18382
0
  int status = NC_NOERR;
18383
18384
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18385
0
  {
18386
0
    const int lstatus = ncx_get_longlong_float(xp, tp);
18387
0
    if (status == NC_NOERR) /* report the first encountered error */
18388
0
      status = lstatus;
18389
0
  }
18390
18391
0
  *xpp = (const void *)xp;
18392
0
  return status;
18393
0
#endif
18394
0
}
18395
18396
int
18397
ncx_getn_longlong_double(const void **xpp, size_t nelems, double *tp)
18398
0
{
18399
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18400
18401
 /* basic algorithm is:
18402
  *   - ensure sane alignment of input data
18403
  *   - copy (conversion happens automatically) input data
18404
  *     to output
18405
  *   - update xpp to point at next unconverted input, and tp to point
18406
  *     at next location for converted output
18407
  */
18408
  long i, j, ni;
18409
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18410
  int64 *xp;
18411
  int nrange = 0;         /* number of range errors */
18412
  int realign = 0;        /* "do we need to fix input data alignment?" */
18413
  long cxp = (long) *((char**)xpp);
18414
18415
  realign = (cxp & 7) % SIZEOF_INT64;
18416
  /* sjl: manually stripmine so we can limit amount of
18417
   * vector work space reserved to LOOPCNT elements. Also
18418
   * makes vectorisation easy */
18419
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18420
    ni=Min(nelems-j,LOOPCNT);
18421
    if (realign) {
18422
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18423
      xp = tmp;
18424
    } else {
18425
      xp = (int64 *) *xpp;
18426
    }
18427
   /* copy the next block */
18428
#pragma cdir loopcnt=LOOPCNT
18429
#pragma cdir shortloop
18430
    for (i=0; i<ni; i++) {
18431
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
18432
     /* test for range errors (not always needed but do it anyway) */
18433
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18434
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18435
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
18436
    }
18437
   /* update xpp and tp */
18438
    if (realign) xp = (int64 *) *xpp;
18439
    xp += ni;
18440
    tp += ni;
18441
    *xpp = (void*)xp;
18442
  }
18443
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18444
18445
#else   /* not SX */
18446
0
  const char *xp = (const char *) *xpp;
18447
0
  int status = NC_NOERR;
18448
18449
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18450
0
  {
18451
0
    const int lstatus = ncx_get_longlong_double(xp, tp);
18452
0
    if (status == NC_NOERR) /* report the first encountered error */
18453
0
      status = lstatus;
18454
0
  }
18455
18456
0
  *xpp = (const void *)xp;
18457
0
  return status;
18458
0
#endif
18459
0
}
18460
18461
int
18462
ncx_getn_longlong_uchar(const void **xpp, size_t nelems, uchar *tp)
18463
0
{
18464
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18465
18466
 /* basic algorithm is:
18467
  *   - ensure sane alignment of input data
18468
  *   - copy (conversion happens automatically) input data
18469
  *     to output
18470
  *   - update xpp to point at next unconverted input, and tp to point
18471
  *     at next location for converted output
18472
  */
18473
  long i, j, ni;
18474
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18475
  int64 *xp;
18476
  int nrange = 0;         /* number of range errors */
18477
  int realign = 0;        /* "do we need to fix input data alignment?" */
18478
  long cxp = (long) *((char**)xpp);
18479
18480
  realign = (cxp & 7) % SIZEOF_INT64;
18481
  /* sjl: manually stripmine so we can limit amount of
18482
   * vector work space reserved to LOOPCNT elements. Also
18483
   * makes vectorisation easy */
18484
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18485
    ni=Min(nelems-j,LOOPCNT);
18486
    if (realign) {
18487
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18488
      xp = tmp;
18489
    } else {
18490
      xp = (int64 *) *xpp;
18491
    }
18492
   /* copy the next block */
18493
#pragma cdir loopcnt=LOOPCNT
18494
#pragma cdir shortloop
18495
    for (i=0; i<ni; i++) {
18496
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
18497
     /* test for range errors (not always needed but do it anyway) */
18498
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18499
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18500
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
18501
    }
18502
   /* update xpp and tp */
18503
    if (realign) xp = (int64 *) *xpp;
18504
    xp += ni;
18505
    tp += ni;
18506
    *xpp = (void*)xp;
18507
  }
18508
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18509
18510
#else   /* not SX */
18511
0
  const char *xp = (const char *) *xpp;
18512
0
  int status = NC_NOERR;
18513
18514
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18515
0
  {
18516
0
    const int lstatus = ncx_get_longlong_uchar(xp, tp);
18517
0
    if (status == NC_NOERR) /* report the first encountered error */
18518
0
      status = lstatus;
18519
0
  }
18520
18521
0
  *xpp = (const void *)xp;
18522
0
  return status;
18523
0
#endif
18524
0
}
18525
18526
int
18527
ncx_getn_longlong_ushort(const void **xpp, size_t nelems, ushort *tp)
18528
0
{
18529
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18530
18531
 /* basic algorithm is:
18532
  *   - ensure sane alignment of input data
18533
  *   - copy (conversion happens automatically) input data
18534
  *     to output
18535
  *   - update xpp to point at next unconverted input, and tp to point
18536
  *     at next location for converted output
18537
  */
18538
  long i, j, ni;
18539
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18540
  int64 *xp;
18541
  int nrange = 0;         /* number of range errors */
18542
  int realign = 0;        /* "do we need to fix input data alignment?" */
18543
  long cxp = (long) *((char**)xpp);
18544
18545
  realign = (cxp & 7) % SIZEOF_INT64;
18546
  /* sjl: manually stripmine so we can limit amount of
18547
   * vector work space reserved to LOOPCNT elements. Also
18548
   * makes vectorisation easy */
18549
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18550
    ni=Min(nelems-j,LOOPCNT);
18551
    if (realign) {
18552
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18553
      xp = tmp;
18554
    } else {
18555
      xp = (int64 *) *xpp;
18556
    }
18557
   /* copy the next block */
18558
#pragma cdir loopcnt=LOOPCNT
18559
#pragma cdir shortloop
18560
    for (i=0; i<ni; i++) {
18561
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
18562
     /* test for range errors (not always needed but do it anyway) */
18563
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18564
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18565
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
18566
    }
18567
   /* update xpp and tp */
18568
    if (realign) xp = (int64 *) *xpp;
18569
    xp += ni;
18570
    tp += ni;
18571
    *xpp = (void*)xp;
18572
  }
18573
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18574
18575
#else   /* not SX */
18576
0
  const char *xp = (const char *) *xpp;
18577
0
  int status = NC_NOERR;
18578
18579
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18580
0
  {
18581
0
    const int lstatus = ncx_get_longlong_ushort(xp, tp);
18582
0
    if (status == NC_NOERR) /* report the first encountered error */
18583
0
      status = lstatus;
18584
0
  }
18585
18586
0
  *xpp = (const void *)xp;
18587
0
  return status;
18588
0
#endif
18589
0
}
18590
18591
int
18592
ncx_getn_longlong_uint(const void **xpp, size_t nelems, uint *tp)
18593
0
{
18594
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18595
18596
 /* basic algorithm is:
18597
  *   - ensure sane alignment of input data
18598
  *   - copy (conversion happens automatically) input data
18599
  *     to output
18600
  *   - update xpp to point at next unconverted input, and tp to point
18601
  *     at next location for converted output
18602
  */
18603
  long i, j, ni;
18604
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18605
  int64 *xp;
18606
  int nrange = 0;         /* number of range errors */
18607
  int realign = 0;        /* "do we need to fix input data alignment?" */
18608
  long cxp = (long) *((char**)xpp);
18609
18610
  realign = (cxp & 7) % SIZEOF_INT64;
18611
  /* sjl: manually stripmine so we can limit amount of
18612
   * vector work space reserved to LOOPCNT elements. Also
18613
   * makes vectorisation easy */
18614
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18615
    ni=Min(nelems-j,LOOPCNT);
18616
    if (realign) {
18617
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18618
      xp = tmp;
18619
    } else {
18620
      xp = (int64 *) *xpp;
18621
    }
18622
   /* copy the next block */
18623
#pragma cdir loopcnt=LOOPCNT
18624
#pragma cdir shortloop
18625
    for (i=0; i<ni; i++) {
18626
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
18627
     /* test for range errors (not always needed but do it anyway) */
18628
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18629
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18630
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
18631
    }
18632
   /* update xpp and tp */
18633
    if (realign) xp = (int64 *) *xpp;
18634
    xp += ni;
18635
    tp += ni;
18636
    *xpp = (void*)xp;
18637
  }
18638
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18639
18640
#else   /* not SX */
18641
0
  const char *xp = (const char *) *xpp;
18642
0
  int status = NC_NOERR;
18643
18644
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18645
0
  {
18646
0
    const int lstatus = ncx_get_longlong_uint(xp, tp);
18647
0
    if (status == NC_NOERR) /* report the first encountered error */
18648
0
      status = lstatus;
18649
0
  }
18650
18651
0
  *xpp = (const void *)xp;
18652
0
  return status;
18653
0
#endif
18654
0
}
18655
18656
int
18657
ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
18658
0
{
18659
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18660
18661
 /* basic algorithm is:
18662
  *   - ensure sane alignment of input data
18663
  *   - copy (conversion happens automatically) input data
18664
  *     to output
18665
  *   - update xpp to point at next unconverted input, and tp to point
18666
  *     at next location for converted output
18667
  */
18668
  long i, j, ni;
18669
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18670
  int64 *xp;
18671
  int nrange = 0;         /* number of range errors */
18672
  int realign = 0;        /* "do we need to fix input data alignment?" */
18673
  long cxp = (long) *((char**)xpp);
18674
18675
  realign = (cxp & 7) % SIZEOF_INT64;
18676
  /* sjl: manually stripmine so we can limit amount of
18677
   * vector work space reserved to LOOPCNT elements. Also
18678
   * makes vectorisation easy */
18679
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18680
    ni=Min(nelems-j,LOOPCNT);
18681
    if (realign) {
18682
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18683
      xp = tmp;
18684
    } else {
18685
      xp = (int64 *) *xpp;
18686
    }
18687
   /* copy the next block */
18688
#pragma cdir loopcnt=LOOPCNT
18689
#pragma cdir shortloop
18690
    for (i=0; i<ni; i++) {
18691
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
18692
     /* test for range errors (not always needed but do it anyway) */
18693
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18694
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18695
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
18696
    }
18697
   /* update xpp and tp */
18698
    if (realign) xp = (int64 *) *xpp;
18699
    xp += ni;
18700
    tp += ni;
18701
    *xpp = (void*)xp;
18702
  }
18703
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18704
18705
#else   /* not SX */
18706
0
  const char *xp = (const char *) *xpp;
18707
0
  int status = NC_NOERR;
18708
18709
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18710
0
  {
18711
0
    const int lstatus = ncx_get_longlong_ulonglong(xp, tp);
18712
0
    if (status == NC_NOERR) /* report the first encountered error */
18713
0
      status = lstatus;
18714
0
  }
18715
18716
0
  *xpp = (const void *)xp;
18717
0
  return status;
18718
0
#endif
18719
0
}
18720
18721
18722
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
18723
/* optimized version */
18724
int
18725
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp, void *fillp)
18726
0
{
18727
#ifdef WORDS_BIGENDIAN
18728
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
18729
# else
18730
0
  swapn8b(*xpp, tp, nelems);
18731
0
# endif
18732
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
18733
0
  return NC_NOERR;
18734
0
}
18735
#else
18736
int
18737
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
18738
{
18739
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18740
18741
 /* basic algorithm is:
18742
  *   - ensure sane alignment of output data
18743
  *   - copy (conversion happens automatically) input data
18744
  *     to output
18745
  *   - update tp to point at next unconverted input, and xpp to point
18746
  *     at next location for converted output
18747
  */
18748
  long i, j, ni;
18749
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18750
  int64 *xp;
18751
  int nrange = 0;         /* number of range errors */
18752
  int realign = 0;        /* "do we need to fix input data alignment?" */
18753
  long cxp = (long) *((char**)xpp);
18754
18755
  realign = (cxp & 7) % SIZEOF_INT64;
18756
  /* sjl: manually stripmine so we can limit amount of
18757
   * vector work space reserved to LOOPCNT elements. Also
18758
   * makes vectorisation easy */
18759
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18760
    ni=Min(nelems-j,LOOPCNT);
18761
    if (realign) {
18762
      xp = tmp;
18763
    } else {
18764
      xp = (int64 *) *xpp;
18765
    }
18766
   /* copy the next block */
18767
#pragma cdir loopcnt=LOOPCNT
18768
#pragma cdir shortloop
18769
    for (i=0; i<ni; i++) {
18770
      /* the normal case: */
18771
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18772
     /* test for range errors (not always needed but do it anyway) */
18773
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18774
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18775
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18776
    }
18777
   /* copy workspace back if necessary */
18778
    if (realign) {
18779
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18780
      xp = (int64 *) *xpp;
18781
    }
18782
   /* update xpp and tp */
18783
    xp += ni;
18784
    tp += ni;
18785
    *xpp = (void*)xp;
18786
  }
18787
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18788
18789
#else   /* not SX */
18790
18791
  char *xp = (char *) *xpp;
18792
  int status = NC_NOERR;
18793
18794
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18795
  {
18796
    int lstatus = ncx_put_longlong_longlong(xp, tp, fillp);
18797
    if (status == NC_NOERR) /* report the first encountered error */
18798
      status = lstatus;
18799
  }
18800
18801
  *xpp = (void *)xp;
18802
  return status;
18803
#endif
18804
}
18805
18806
#endif
18807
int
18808
ncx_putn_longlong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
18809
0
{
18810
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18811
18812
 /* basic algorithm is:
18813
  *   - ensure sane alignment of output data
18814
  *   - copy (conversion happens automatically) input data
18815
  *     to output
18816
  *   - update tp to point at next unconverted input, and xpp to point
18817
  *     at next location for converted output
18818
  */
18819
  long i, j, ni;
18820
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18821
  int64 *xp;
18822
  int nrange = 0;         /* number of range errors */
18823
  int realign = 0;        /* "do we need to fix input data alignment?" */
18824
  long cxp = (long) *((char**)xpp);
18825
18826
  realign = (cxp & 7) % SIZEOF_INT64;
18827
  /* sjl: manually stripmine so we can limit amount of
18828
   * vector work space reserved to LOOPCNT elements. Also
18829
   * makes vectorisation easy */
18830
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18831
    ni=Min(nelems-j,LOOPCNT);
18832
    if (realign) {
18833
      xp = tmp;
18834
    } else {
18835
      xp = (int64 *) *xpp;
18836
    }
18837
   /* copy the next block */
18838
#pragma cdir loopcnt=LOOPCNT
18839
#pragma cdir shortloop
18840
    for (i=0; i<ni; i++) {
18841
      /* the normal case: */
18842
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18843
     /* test for range errors (not always needed but do it anyway) */
18844
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18845
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18846
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18847
    }
18848
   /* copy workspace back if necessary */
18849
    if (realign) {
18850
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18851
      xp = (int64 *) *xpp;
18852
    }
18853
   /* update xpp and tp */
18854
    xp += ni;
18855
    tp += ni;
18856
    *xpp = (void*)xp;
18857
  }
18858
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18859
18860
#else   /* not SX */
18861
18862
0
  char *xp = (char *) *xpp;
18863
0
  int status = NC_NOERR;
18864
18865
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18866
0
  {
18867
0
    int lstatus = ncx_put_longlong_schar(xp, tp, fillp);
18868
0
    if (status == NC_NOERR) /* report the first encountered error */
18869
0
      status = lstatus;
18870
0
  }
18871
18872
0
  *xpp = (void *)xp;
18873
0
  return status;
18874
0
#endif
18875
0
}
18876
18877
int
18878
ncx_putn_longlong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
18879
0
{
18880
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18881
18882
 /* basic algorithm is:
18883
  *   - ensure sane alignment of output data
18884
  *   - copy (conversion happens automatically) input data
18885
  *     to output
18886
  *   - update tp to point at next unconverted input, and xpp to point
18887
  *     at next location for converted output
18888
  */
18889
  long i, j, ni;
18890
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18891
  int64 *xp;
18892
  int nrange = 0;         /* number of range errors */
18893
  int realign = 0;        /* "do we need to fix input data alignment?" */
18894
  long cxp = (long) *((char**)xpp);
18895
18896
  realign = (cxp & 7) % SIZEOF_INT64;
18897
  /* sjl: manually stripmine so we can limit amount of
18898
   * vector work space reserved to LOOPCNT elements. Also
18899
   * makes vectorisation easy */
18900
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18901
    ni=Min(nelems-j,LOOPCNT);
18902
    if (realign) {
18903
      xp = tmp;
18904
    } else {
18905
      xp = (int64 *) *xpp;
18906
    }
18907
   /* copy the next block */
18908
#pragma cdir loopcnt=LOOPCNT
18909
#pragma cdir shortloop
18910
    for (i=0; i<ni; i++) {
18911
      /* the normal case: */
18912
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18913
     /* test for range errors (not always needed but do it anyway) */
18914
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18915
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18916
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18917
    }
18918
   /* copy workspace back if necessary */
18919
    if (realign) {
18920
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18921
      xp = (int64 *) *xpp;
18922
    }
18923
   /* update xpp and tp */
18924
    xp += ni;
18925
    tp += ni;
18926
    *xpp = (void*)xp;
18927
  }
18928
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18929
18930
#else   /* not SX */
18931
18932
0
  char *xp = (char *) *xpp;
18933
0
  int status = NC_NOERR;
18934
18935
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18936
0
  {
18937
0
    int lstatus = ncx_put_longlong_short(xp, tp, fillp);
18938
0
    if (status == NC_NOERR) /* report the first encountered error */
18939
0
      status = lstatus;
18940
0
  }
18941
18942
0
  *xpp = (void *)xp;
18943
0
  return status;
18944
0
#endif
18945
0
}
18946
18947
int
18948
ncx_putn_longlong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
18949
0
{
18950
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18951
18952
 /* basic algorithm is:
18953
  *   - ensure sane alignment of output data
18954
  *   - copy (conversion happens automatically) input data
18955
  *     to output
18956
  *   - update tp to point at next unconverted input, and xpp to point
18957
  *     at next location for converted output
18958
  */
18959
  long i, j, ni;
18960
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
18961
  int64 *xp;
18962
  int nrange = 0;         /* number of range errors */
18963
  int realign = 0;        /* "do we need to fix input data alignment?" */
18964
  long cxp = (long) *((char**)xpp);
18965
18966
  realign = (cxp & 7) % SIZEOF_INT64;
18967
  /* sjl: manually stripmine so we can limit amount of
18968
   * vector work space reserved to LOOPCNT elements. Also
18969
   * makes vectorisation easy */
18970
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18971
    ni=Min(nelems-j,LOOPCNT);
18972
    if (realign) {
18973
      xp = tmp;
18974
    } else {
18975
      xp = (int64 *) *xpp;
18976
    }
18977
   /* copy the next block */
18978
#pragma cdir loopcnt=LOOPCNT
18979
#pragma cdir shortloop
18980
    for (i=0; i<ni; i++) {
18981
      /* the normal case: */
18982
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18983
     /* test for range errors (not always needed but do it anyway) */
18984
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18985
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18986
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18987
    }
18988
   /* copy workspace back if necessary */
18989
    if (realign) {
18990
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18991
      xp = (int64 *) *xpp;
18992
    }
18993
   /* update xpp and tp */
18994
    xp += ni;
18995
    tp += ni;
18996
    *xpp = (void*)xp;
18997
  }
18998
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
18999
19000
#else   /* not SX */
19001
19002
0
  char *xp = (char *) *xpp;
19003
0
  int status = NC_NOERR;
19004
19005
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19006
0
  {
19007
0
    int lstatus = ncx_put_longlong_int(xp, tp, fillp);
19008
0
    if (status == NC_NOERR) /* report the first encountered error */
19009
0
      status = lstatus;
19010
0
  }
19011
19012
0
  *xpp = (void *)xp;
19013
0
  return status;
19014
0
#endif
19015
0
}
19016
19017
int
19018
ncx_putn_longlong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
19019
0
{
19020
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19021
19022
 /* basic algorithm is:
19023
  *   - ensure sane alignment of output data
19024
  *   - copy (conversion happens automatically) input data
19025
  *     to output
19026
  *   - update tp to point at next unconverted input, and xpp to point
19027
  *     at next location for converted output
19028
  */
19029
  long i, j, ni;
19030
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19031
  int64 *xp;
19032
  int nrange = 0;         /* number of range errors */
19033
  int realign = 0;        /* "do we need to fix input data alignment?" */
19034
  long cxp = (long) *((char**)xpp);
19035
19036
  realign = (cxp & 7) % SIZEOF_INT64;
19037
  /* sjl: manually stripmine so we can limit amount of
19038
   * vector work space reserved to LOOPCNT elements. Also
19039
   * makes vectorisation easy */
19040
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19041
    ni=Min(nelems-j,LOOPCNT);
19042
    if (realign) {
19043
      xp = tmp;
19044
    } else {
19045
      xp = (int64 *) *xpp;
19046
    }
19047
   /* copy the next block */
19048
#pragma cdir loopcnt=LOOPCNT
19049
#pragma cdir shortloop
19050
    for (i=0; i<ni; i++) {
19051
      /* the normal case: */
19052
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19053
     /* test for range errors (not always needed but do it anyway) */
19054
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19055
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19056
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19057
    }
19058
   /* copy workspace back if necessary */
19059
    if (realign) {
19060
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19061
      xp = (int64 *) *xpp;
19062
    }
19063
   /* update xpp and tp */
19064
    xp += ni;
19065
    tp += ni;
19066
    *xpp = (void*)xp;
19067
  }
19068
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19069
19070
#else   /* not SX */
19071
19072
0
  char *xp = (char *) *xpp;
19073
0
  int status = NC_NOERR;
19074
19075
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19076
0
  {
19077
0
    int lstatus = ncx_put_longlong_long(xp, tp, fillp);
19078
0
    if (status == NC_NOERR) /* report the first encountered error */
19079
0
      status = lstatus;
19080
0
  }
19081
19082
0
  *xpp = (void *)xp;
19083
0
  return status;
19084
0
#endif
19085
0
}
19086
19087
int
19088
ncx_putn_longlong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
19089
0
{
19090
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19091
19092
 /* basic algorithm is:
19093
  *   - ensure sane alignment of output data
19094
  *   - copy (conversion happens automatically) input data
19095
  *     to output
19096
  *   - update tp to point at next unconverted input, and xpp to point
19097
  *     at next location for converted output
19098
  */
19099
  long i, j, ni;
19100
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19101
  int64 *xp;
19102
  int nrange = 0;         /* number of range errors */
19103
  int realign = 0;        /* "do we need to fix input data alignment?" */
19104
  long cxp = (long) *((char**)xpp);
19105
19106
  realign = (cxp & 7) % SIZEOF_INT64;
19107
  /* sjl: manually stripmine so we can limit amount of
19108
   * vector work space reserved to LOOPCNT elements. Also
19109
   * makes vectorisation easy */
19110
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19111
    ni=Min(nelems-j,LOOPCNT);
19112
    if (realign) {
19113
      xp = tmp;
19114
    } else {
19115
      xp = (int64 *) *xpp;
19116
    }
19117
   /* copy the next block */
19118
#pragma cdir loopcnt=LOOPCNT
19119
#pragma cdir shortloop
19120
    for (i=0; i<ni; i++) {
19121
      /* the normal case: */
19122
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19123
     /* test for range errors (not always needed but do it anyway) */
19124
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19125
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19126
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19127
    }
19128
   /* copy workspace back if necessary */
19129
    if (realign) {
19130
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19131
      xp = (int64 *) *xpp;
19132
    }
19133
   /* update xpp and tp */
19134
    xp += ni;
19135
    tp += ni;
19136
    *xpp = (void*)xp;
19137
  }
19138
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19139
19140
#else   /* not SX */
19141
19142
0
  char *xp = (char *) *xpp;
19143
0
  int status = NC_NOERR;
19144
19145
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19146
0
  {
19147
0
    int lstatus = ncx_put_longlong_float(xp, tp, fillp);
19148
0
    if (status == NC_NOERR) /* report the first encountered error */
19149
0
      status = lstatus;
19150
0
  }
19151
19152
0
  *xpp = (void *)xp;
19153
0
  return status;
19154
0
#endif
19155
0
}
19156
19157
int
19158
ncx_putn_longlong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
19159
0
{
19160
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19161
19162
 /* basic algorithm is:
19163
  *   - ensure sane alignment of output data
19164
  *   - copy (conversion happens automatically) input data
19165
  *     to output
19166
  *   - update tp to point at next unconverted input, and xpp to point
19167
  *     at next location for converted output
19168
  */
19169
  long i, j, ni;
19170
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19171
  int64 *xp;
19172
  int nrange = 0;         /* number of range errors */
19173
  int realign = 0;        /* "do we need to fix input data alignment?" */
19174
  long cxp = (long) *((char**)xpp);
19175
19176
  realign = (cxp & 7) % SIZEOF_INT64;
19177
  /* sjl: manually stripmine so we can limit amount of
19178
   * vector work space reserved to LOOPCNT elements. Also
19179
   * makes vectorisation easy */
19180
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19181
    ni=Min(nelems-j,LOOPCNT);
19182
    if (realign) {
19183
      xp = tmp;
19184
    } else {
19185
      xp = (int64 *) *xpp;
19186
    }
19187
   /* copy the next block */
19188
#pragma cdir loopcnt=LOOPCNT
19189
#pragma cdir shortloop
19190
    for (i=0; i<ni; i++) {
19191
      /* the normal case: */
19192
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19193
     /* test for range errors (not always needed but do it anyway) */
19194
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19195
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19196
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19197
    }
19198
   /* copy workspace back if necessary */
19199
    if (realign) {
19200
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19201
      xp = (int64 *) *xpp;
19202
    }
19203
   /* update xpp and tp */
19204
    xp += ni;
19205
    tp += ni;
19206
    *xpp = (void*)xp;
19207
  }
19208
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19209
19210
#else   /* not SX */
19211
19212
0
  char *xp = (char *) *xpp;
19213
0
  int status = NC_NOERR;
19214
19215
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19216
0
  {
19217
0
    int lstatus = ncx_put_longlong_double(xp, tp, fillp);
19218
0
    if (status == NC_NOERR) /* report the first encountered error */
19219
0
      status = lstatus;
19220
0
  }
19221
19222
0
  *xpp = (void *)xp;
19223
0
  return status;
19224
0
#endif
19225
0
}
19226
19227
int
19228
ncx_putn_longlong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
19229
0
{
19230
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19231
19232
 /* basic algorithm is:
19233
  *   - ensure sane alignment of output data
19234
  *   - copy (conversion happens automatically) input data
19235
  *     to output
19236
  *   - update tp to point at next unconverted input, and xpp to point
19237
  *     at next location for converted output
19238
  */
19239
  long i, j, ni;
19240
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19241
  int64 *xp;
19242
  int nrange = 0;         /* number of range errors */
19243
  int realign = 0;        /* "do we need to fix input data alignment?" */
19244
  long cxp = (long) *((char**)xpp);
19245
19246
  realign = (cxp & 7) % SIZEOF_INT64;
19247
  /* sjl: manually stripmine so we can limit amount of
19248
   * vector work space reserved to LOOPCNT elements. Also
19249
   * makes vectorisation easy */
19250
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19251
    ni=Min(nelems-j,LOOPCNT);
19252
    if (realign) {
19253
      xp = tmp;
19254
    } else {
19255
      xp = (int64 *) *xpp;
19256
    }
19257
   /* copy the next block */
19258
#pragma cdir loopcnt=LOOPCNT
19259
#pragma cdir shortloop
19260
    for (i=0; i<ni; i++) {
19261
      /* the normal case: */
19262
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19263
     /* test for range errors (not always needed but do it anyway) */
19264
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19265
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19266
      nrange += tp[i] > X_INT64_MAX ;
19267
    }
19268
   /* copy workspace back if necessary */
19269
    if (realign) {
19270
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19271
      xp = (int64 *) *xpp;
19272
    }
19273
   /* update xpp and tp */
19274
    xp += ni;
19275
    tp += ni;
19276
    *xpp = (void*)xp;
19277
  }
19278
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19279
19280
#else   /* not SX */
19281
19282
0
  char *xp = (char *) *xpp;
19283
0
  int status = NC_NOERR;
19284
19285
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19286
0
  {
19287
0
    int lstatus = ncx_put_longlong_uchar(xp, tp, fillp);
19288
0
    if (status == NC_NOERR) /* report the first encountered error */
19289
0
      status = lstatus;
19290
0
  }
19291
19292
0
  *xpp = (void *)xp;
19293
0
  return status;
19294
0
#endif
19295
0
}
19296
19297
int
19298
ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
19299
0
{
19300
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19301
19302
 /* basic algorithm is:
19303
  *   - ensure sane alignment of output data
19304
  *   - copy (conversion happens automatically) input data
19305
  *     to output
19306
  *   - update tp to point at next unconverted input, and xpp to point
19307
  *     at next location for converted output
19308
  */
19309
  long i, j, ni;
19310
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19311
  int64 *xp;
19312
  int nrange = 0;         /* number of range errors */
19313
  int realign = 0;        /* "do we need to fix input data alignment?" */
19314
  long cxp = (long) *((char**)xpp);
19315
19316
  realign = (cxp & 7) % SIZEOF_INT64;
19317
  /* sjl: manually stripmine so we can limit amount of
19318
   * vector work space reserved to LOOPCNT elements. Also
19319
   * makes vectorisation easy */
19320
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19321
    ni=Min(nelems-j,LOOPCNT);
19322
    if (realign) {
19323
      xp = tmp;
19324
    } else {
19325
      xp = (int64 *) *xpp;
19326
    }
19327
   /* copy the next block */
19328
#pragma cdir loopcnt=LOOPCNT
19329
#pragma cdir shortloop
19330
    for (i=0; i<ni; i++) {
19331
      /* the normal case: */
19332
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19333
     /* test for range errors (not always needed but do it anyway) */
19334
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19335
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19336
      nrange += tp[i] > X_INT64_MAX ;
19337
    }
19338
   /* copy workspace back if necessary */
19339
    if (realign) {
19340
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19341
      xp = (int64 *) *xpp;
19342
    }
19343
   /* update xpp and tp */
19344
    xp += ni;
19345
    tp += ni;
19346
    *xpp = (void*)xp;
19347
  }
19348
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19349
19350
#else   /* not SX */
19351
19352
0
  char *xp = (char *) *xpp;
19353
0
  int status = NC_NOERR;
19354
19355
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19356
0
  {
19357
0
    int lstatus = ncx_put_longlong_ushort(xp, tp, fillp);
19358
0
    if (status == NC_NOERR) /* report the first encountered error */
19359
0
      status = lstatus;
19360
0
  }
19361
19362
0
  *xpp = (void *)xp;
19363
0
  return status;
19364
0
#endif
19365
0
}
19366
19367
int
19368
ncx_putn_longlong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
19369
0
{
19370
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19371
19372
 /* basic algorithm is:
19373
  *   - ensure sane alignment of output data
19374
  *   - copy (conversion happens automatically) input data
19375
  *     to output
19376
  *   - update tp to point at next unconverted input, and xpp to point
19377
  *     at next location for converted output
19378
  */
19379
  long i, j, ni;
19380
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19381
  int64 *xp;
19382
  int nrange = 0;         /* number of range errors */
19383
  int realign = 0;        /* "do we need to fix input data alignment?" */
19384
  long cxp = (long) *((char**)xpp);
19385
19386
  realign = (cxp & 7) % SIZEOF_INT64;
19387
  /* sjl: manually stripmine so we can limit amount of
19388
   * vector work space reserved to LOOPCNT elements. Also
19389
   * makes vectorisation easy */
19390
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19391
    ni=Min(nelems-j,LOOPCNT);
19392
    if (realign) {
19393
      xp = tmp;
19394
    } else {
19395
      xp = (int64 *) *xpp;
19396
    }
19397
   /* copy the next block */
19398
#pragma cdir loopcnt=LOOPCNT
19399
#pragma cdir shortloop
19400
    for (i=0; i<ni; i++) {
19401
      /* the normal case: */
19402
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19403
     /* test for range errors (not always needed but do it anyway) */
19404
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19405
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19406
      nrange += tp[i] > X_INT64_MAX ;
19407
    }
19408
   /* copy workspace back if necessary */
19409
    if (realign) {
19410
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19411
      xp = (int64 *) *xpp;
19412
    }
19413
   /* update xpp and tp */
19414
    xp += ni;
19415
    tp += ni;
19416
    *xpp = (void*)xp;
19417
  }
19418
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19419
19420
#else   /* not SX */
19421
19422
0
  char *xp = (char *) *xpp;
19423
0
  int status = NC_NOERR;
19424
19425
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19426
0
  {
19427
0
    int lstatus = ncx_put_longlong_uint(xp, tp, fillp);
19428
0
    if (status == NC_NOERR) /* report the first encountered error */
19429
0
      status = lstatus;
19430
0
  }
19431
19432
0
  *xpp = (void *)xp;
19433
0
  return status;
19434
0
#endif
19435
0
}
19436
19437
int
19438
ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
19439
0
{
19440
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19441
19442
 /* basic algorithm is:
19443
  *   - ensure sane alignment of output data
19444
  *   - copy (conversion happens automatically) input data
19445
  *     to output
19446
  *   - update tp to point at next unconverted input, and xpp to point
19447
  *     at next location for converted output
19448
  */
19449
  long i, j, ni;
19450
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
19451
  int64 *xp;
19452
  int nrange = 0;         /* number of range errors */
19453
  int realign = 0;        /* "do we need to fix input data alignment?" */
19454
  long cxp = (long) *((char**)xpp);
19455
19456
  realign = (cxp & 7) % SIZEOF_INT64;
19457
  /* sjl: manually stripmine so we can limit amount of
19458
   * vector work space reserved to LOOPCNT elements. Also
19459
   * makes vectorisation easy */
19460
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19461
    ni=Min(nelems-j,LOOPCNT);
19462
    if (realign) {
19463
      xp = tmp;
19464
    } else {
19465
      xp = (int64 *) *xpp;
19466
    }
19467
   /* copy the next block */
19468
#pragma cdir loopcnt=LOOPCNT
19469
#pragma cdir shortloop
19470
    for (i=0; i<ni; i++) {
19471
      /* the normal case: */
19472
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19473
     /* test for range errors (not always needed but do it anyway) */
19474
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19475
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19476
      nrange += tp[i] > X_INT64_MAX ;
19477
    }
19478
   /* copy workspace back if necessary */
19479
    if (realign) {
19480
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19481
      xp = (int64 *) *xpp;
19482
    }
19483
   /* update xpp and tp */
19484
    xp += ni;
19485
    tp += ni;
19486
    *xpp = (void*)xp;
19487
  }
19488
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19489
19490
#else   /* not SX */
19491
19492
0
  char *xp = (char *) *xpp;
19493
0
  int status = NC_NOERR;
19494
19495
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19496
0
  {
19497
0
    int lstatus = ncx_put_longlong_ulonglong(xp, tp, fillp);
19498
0
    if (status == NC_NOERR) /* report the first encountered error */
19499
0
      status = lstatus;
19500
0
  }
19501
19502
0
  *xpp = (void *)xp;
19503
0
  return status;
19504
0
#endif
19505
0
}
19506
19507
19508
/* uint64 --------------------------------------------------------------------*/
19509
19510
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
19511
/* optimized version */
19512
int
19513
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp)
19514
0
{
19515
#ifdef WORDS_BIGENDIAN
19516
  (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
19517
# else
19518
0
  swapn8b(tp, *xpp, nelems);
19519
0
# endif
19520
0
  *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
19521
0
  return NC_NOERR;
19522
0
}
19523
#else
19524
int
19525
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
19526
{
19527
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19528
19529
 /* basic algorithm is:
19530
  *   - ensure sane alignment of input data
19531
  *   - copy (conversion happens automatically) input data
19532
  *     to output
19533
  *   - update xpp to point at next unconverted input, and tp to point
19534
  *     at next location for converted output
19535
  */
19536
  long i, j, ni;
19537
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19538
  uint64 *xp;
19539
  int nrange = 0;         /* number of range errors */
19540
  int realign = 0;        /* "do we need to fix input data alignment?" */
19541
  long cxp = (long) *((char**)xpp);
19542
19543
  realign = (cxp & 7) % SIZEOF_UINT64;
19544
  /* sjl: manually stripmine so we can limit amount of
19545
   * vector work space reserved to LOOPCNT elements. Also
19546
   * makes vectorisation easy */
19547
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19548
    ni=Min(nelems-j,LOOPCNT);
19549
    if (realign) {
19550
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19551
      xp = tmp;
19552
    } else {
19553
      xp = (uint64 *) *xpp;
19554
    }
19555
   /* copy the next block */
19556
#pragma cdir loopcnt=LOOPCNT
19557
#pragma cdir shortloop
19558
    for (i=0; i<ni; i++) {
19559
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
19560
     /* test for range errors (not always needed but do it anyway) */
19561
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19562
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19563
      nrange += xp[i] > ULONGLONG_MAX ;
19564
    }
19565
   /* update xpp and tp */
19566
    if (realign) xp = (uint64 *) *xpp;
19567
    xp += ni;
19568
    tp += ni;
19569
    *xpp = (void*)xp;
19570
  }
19571
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19572
19573
#else   /* not SX */
19574
  const char *xp = (const char *) *xpp;
19575
  int status = NC_NOERR;
19576
19577
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19578
  {
19579
    const int lstatus = ncx_get_ulonglong_ulonglong(xp, tp);
19580
    if (status == NC_NOERR) /* report the first encountered error */
19581
      status = lstatus;
19582
  }
19583
19584
  *xpp = (const void *)xp;
19585
  return status;
19586
#endif
19587
}
19588
19589
#endif
19590
int
19591
ncx_getn_ulonglong_schar(const void **xpp, size_t nelems, schar *tp)
19592
0
{
19593
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19594
19595
 /* basic algorithm is:
19596
  *   - ensure sane alignment of input data
19597
  *   - copy (conversion happens automatically) input data
19598
  *     to output
19599
  *   - update xpp to point at next unconverted input, and tp to point
19600
  *     at next location for converted output
19601
  */
19602
  long i, j, ni;
19603
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19604
  uint64 *xp;
19605
  int nrange = 0;         /* number of range errors */
19606
  int realign = 0;        /* "do we need to fix input data alignment?" */
19607
  long cxp = (long) *((char**)xpp);
19608
19609
  realign = (cxp & 7) % SIZEOF_UINT64;
19610
  /* sjl: manually stripmine so we can limit amount of
19611
   * vector work space reserved to LOOPCNT elements. Also
19612
   * makes vectorisation easy */
19613
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19614
    ni=Min(nelems-j,LOOPCNT);
19615
    if (realign) {
19616
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19617
      xp = tmp;
19618
    } else {
19619
      xp = (uint64 *) *xpp;
19620
    }
19621
   /* copy the next block */
19622
#pragma cdir loopcnt=LOOPCNT
19623
#pragma cdir shortloop
19624
    for (i=0; i<ni; i++) {
19625
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
19626
     /* test for range errors (not always needed but do it anyway) */
19627
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19628
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19629
      nrange += xp[i] > SCHAR_MAX ;
19630
    }
19631
   /* update xpp and tp */
19632
    if (realign) xp = (uint64 *) *xpp;
19633
    xp += ni;
19634
    tp += ni;
19635
    *xpp = (void*)xp;
19636
  }
19637
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19638
19639
#else   /* not SX */
19640
0
  const char *xp = (const char *) *xpp;
19641
0
  int status = NC_NOERR;
19642
19643
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19644
0
  {
19645
0
    const int lstatus = ncx_get_ulonglong_schar(xp, tp);
19646
0
    if (status == NC_NOERR) /* report the first encountered error */
19647
0
      status = lstatus;
19648
0
  }
19649
19650
0
  *xpp = (const void *)xp;
19651
0
  return status;
19652
0
#endif
19653
0
}
19654
19655
int
19656
ncx_getn_ulonglong_short(const void **xpp, size_t nelems, short *tp)
19657
0
{
19658
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19659
19660
 /* basic algorithm is:
19661
  *   - ensure sane alignment of input data
19662
  *   - copy (conversion happens automatically) input data
19663
  *     to output
19664
  *   - update xpp to point at next unconverted input, and tp to point
19665
  *     at next location for converted output
19666
  */
19667
  long i, j, ni;
19668
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19669
  uint64 *xp;
19670
  int nrange = 0;         /* number of range errors */
19671
  int realign = 0;        /* "do we need to fix input data alignment?" */
19672
  long cxp = (long) *((char**)xpp);
19673
19674
  realign = (cxp & 7) % SIZEOF_UINT64;
19675
  /* sjl: manually stripmine so we can limit amount of
19676
   * vector work space reserved to LOOPCNT elements. Also
19677
   * makes vectorisation easy */
19678
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19679
    ni=Min(nelems-j,LOOPCNT);
19680
    if (realign) {
19681
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19682
      xp = tmp;
19683
    } else {
19684
      xp = (uint64 *) *xpp;
19685
    }
19686
   /* copy the next block */
19687
#pragma cdir loopcnt=LOOPCNT
19688
#pragma cdir shortloop
19689
    for (i=0; i<ni; i++) {
19690
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
19691
     /* test for range errors (not always needed but do it anyway) */
19692
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19693
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19694
      nrange += xp[i] > SHORT_MAX ;
19695
    }
19696
   /* update xpp and tp */
19697
    if (realign) xp = (uint64 *) *xpp;
19698
    xp += ni;
19699
    tp += ni;
19700
    *xpp = (void*)xp;
19701
  }
19702
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19703
19704
#else   /* not SX */
19705
0
  const char *xp = (const char *) *xpp;
19706
0
  int status = NC_NOERR;
19707
19708
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19709
0
  {
19710
0
    const int lstatus = ncx_get_ulonglong_short(xp, tp);
19711
0
    if (status == NC_NOERR) /* report the first encountered error */
19712
0
      status = lstatus;
19713
0
  }
19714
19715
0
  *xpp = (const void *)xp;
19716
0
  return status;
19717
0
#endif
19718
0
}
19719
19720
int
19721
ncx_getn_ulonglong_int(const void **xpp, size_t nelems, int *tp)
19722
0
{
19723
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19724
19725
 /* basic algorithm is:
19726
  *   - ensure sane alignment of input data
19727
  *   - copy (conversion happens automatically) input data
19728
  *     to output
19729
  *   - update xpp to point at next unconverted input, and tp to point
19730
  *     at next location for converted output
19731
  */
19732
  long i, j, ni;
19733
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19734
  uint64 *xp;
19735
  int nrange = 0;         /* number of range errors */
19736
  int realign = 0;        /* "do we need to fix input data alignment?" */
19737
  long cxp = (long) *((char**)xpp);
19738
19739
  realign = (cxp & 7) % SIZEOF_UINT64;
19740
  /* sjl: manually stripmine so we can limit amount of
19741
   * vector work space reserved to LOOPCNT elements. Also
19742
   * makes vectorisation easy */
19743
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19744
    ni=Min(nelems-j,LOOPCNT);
19745
    if (realign) {
19746
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19747
      xp = tmp;
19748
    } else {
19749
      xp = (uint64 *) *xpp;
19750
    }
19751
   /* copy the next block */
19752
#pragma cdir loopcnt=LOOPCNT
19753
#pragma cdir shortloop
19754
    for (i=0; i<ni; i++) {
19755
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
19756
     /* test for range errors (not always needed but do it anyway) */
19757
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19758
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19759
      nrange += xp[i] > INT_MAX ;
19760
    }
19761
   /* update xpp and tp */
19762
    if (realign) xp = (uint64 *) *xpp;
19763
    xp += ni;
19764
    tp += ni;
19765
    *xpp = (void*)xp;
19766
  }
19767
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19768
19769
#else   /* not SX */
19770
0
  const char *xp = (const char *) *xpp;
19771
0
  int status = NC_NOERR;
19772
19773
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19774
0
  {
19775
0
    const int lstatus = ncx_get_ulonglong_int(xp, tp);
19776
0
    if (status == NC_NOERR) /* report the first encountered error */
19777
0
      status = lstatus;
19778
0
  }
19779
19780
0
  *xpp = (const void *)xp;
19781
0
  return status;
19782
0
#endif
19783
0
}
19784
19785
int
19786
ncx_getn_ulonglong_long(const void **xpp, size_t nelems, long *tp)
19787
0
{
19788
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19789
19790
 /* basic algorithm is:
19791
  *   - ensure sane alignment of input data
19792
  *   - copy (conversion happens automatically) input data
19793
  *     to output
19794
  *   - update xpp to point at next unconverted input, and tp to point
19795
  *     at next location for converted output
19796
  */
19797
  long i, j, ni;
19798
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19799
  uint64 *xp;
19800
  int nrange = 0;         /* number of range errors */
19801
  int realign = 0;        /* "do we need to fix input data alignment?" */
19802
  long cxp = (long) *((char**)xpp);
19803
19804
  realign = (cxp & 7) % SIZEOF_UINT64;
19805
  /* sjl: manually stripmine so we can limit amount of
19806
   * vector work space reserved to LOOPCNT elements. Also
19807
   * makes vectorisation easy */
19808
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19809
    ni=Min(nelems-j,LOOPCNT);
19810
    if (realign) {
19811
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19812
      xp = tmp;
19813
    } else {
19814
      xp = (uint64 *) *xpp;
19815
    }
19816
   /* copy the next block */
19817
#pragma cdir loopcnt=LOOPCNT
19818
#pragma cdir shortloop
19819
    for (i=0; i<ni; i++) {
19820
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
19821
     /* test for range errors (not always needed but do it anyway) */
19822
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19823
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19824
      nrange += xp[i] > LONG_MAX ;
19825
    }
19826
   /* update xpp and tp */
19827
    if (realign) xp = (uint64 *) *xpp;
19828
    xp += ni;
19829
    tp += ni;
19830
    *xpp = (void*)xp;
19831
  }
19832
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19833
19834
#else   /* not SX */
19835
0
  const char *xp = (const char *) *xpp;
19836
0
  int status = NC_NOERR;
19837
19838
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19839
0
  {
19840
0
    const int lstatus = ncx_get_ulonglong_long(xp, tp);
19841
0
    if (status == NC_NOERR) /* report the first encountered error */
19842
0
      status = lstatus;
19843
0
  }
19844
19845
0
  *xpp = (const void *)xp;
19846
0
  return status;
19847
0
#endif
19848
0
}
19849
19850
int
19851
ncx_getn_ulonglong_float(const void **xpp, size_t nelems, float *tp)
19852
0
{
19853
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19854
19855
 /* basic algorithm is:
19856
  *   - ensure sane alignment of input data
19857
  *   - copy (conversion happens automatically) input data
19858
  *     to output
19859
  *   - update xpp to point at next unconverted input, and tp to point
19860
  *     at next location for converted output
19861
  */
19862
  long i, j, ni;
19863
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19864
  uint64 *xp;
19865
  int nrange = 0;         /* number of range errors */
19866
  int realign = 0;        /* "do we need to fix input data alignment?" */
19867
  long cxp = (long) *((char**)xpp);
19868
19869
  realign = (cxp & 7) % SIZEOF_UINT64;
19870
  /* sjl: manually stripmine so we can limit amount of
19871
   * vector work space reserved to LOOPCNT elements. Also
19872
   * makes vectorisation easy */
19873
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19874
    ni=Min(nelems-j,LOOPCNT);
19875
    if (realign) {
19876
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19877
      xp = tmp;
19878
    } else {
19879
      xp = (uint64 *) *xpp;
19880
    }
19881
   /* copy the next block */
19882
#pragma cdir loopcnt=LOOPCNT
19883
#pragma cdir shortloop
19884
    for (i=0; i<ni; i++) {
19885
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
19886
     /* test for range errors (not always needed but do it anyway) */
19887
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19888
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19889
      nrange += xp[i] > FLOAT_MAX ;
19890
    }
19891
   /* update xpp and tp */
19892
    if (realign) xp = (uint64 *) *xpp;
19893
    xp += ni;
19894
    tp += ni;
19895
    *xpp = (void*)xp;
19896
  }
19897
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19898
19899
#else   /* not SX */
19900
0
  const char *xp = (const char *) *xpp;
19901
0
  int status = NC_NOERR;
19902
19903
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19904
0
  {
19905
0
    const int lstatus = ncx_get_ulonglong_float(xp, tp);
19906
0
    if (status == NC_NOERR) /* report the first encountered error */
19907
0
      status = lstatus;
19908
0
  }
19909
19910
0
  *xpp = (const void *)xp;
19911
0
  return status;
19912
0
#endif
19913
0
}
19914
19915
int
19916
ncx_getn_ulonglong_double(const void **xpp, size_t nelems, double *tp)
19917
0
{
19918
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19919
19920
 /* basic algorithm is:
19921
  *   - ensure sane alignment of input data
19922
  *   - copy (conversion happens automatically) input data
19923
  *     to output
19924
  *   - update xpp to point at next unconverted input, and tp to point
19925
  *     at next location for converted output
19926
  */
19927
  long i, j, ni;
19928
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19929
  uint64 *xp;
19930
  int nrange = 0;         /* number of range errors */
19931
  int realign = 0;        /* "do we need to fix input data alignment?" */
19932
  long cxp = (long) *((char**)xpp);
19933
19934
  realign = (cxp & 7) % SIZEOF_UINT64;
19935
  /* sjl: manually stripmine so we can limit amount of
19936
   * vector work space reserved to LOOPCNT elements. Also
19937
   * makes vectorisation easy */
19938
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19939
    ni=Min(nelems-j,LOOPCNT);
19940
    if (realign) {
19941
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19942
      xp = tmp;
19943
    } else {
19944
      xp = (uint64 *) *xpp;
19945
    }
19946
   /* copy the next block */
19947
#pragma cdir loopcnt=LOOPCNT
19948
#pragma cdir shortloop
19949
    for (i=0; i<ni; i++) {
19950
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
19951
     /* test for range errors (not always needed but do it anyway) */
19952
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19953
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19954
      nrange += xp[i] > DOUBLE_MAX ;
19955
    }
19956
   /* update xpp and tp */
19957
    if (realign) xp = (uint64 *) *xpp;
19958
    xp += ni;
19959
    tp += ni;
19960
    *xpp = (void*)xp;
19961
  }
19962
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
19963
19964
#else   /* not SX */
19965
0
  const char *xp = (const char *) *xpp;
19966
0
  int status = NC_NOERR;
19967
19968
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19969
0
  {
19970
0
    const int lstatus = ncx_get_ulonglong_double(xp, tp);
19971
0
    if (status == NC_NOERR) /* report the first encountered error */
19972
0
      status = lstatus;
19973
0
  }
19974
19975
0
  *xpp = (const void *)xp;
19976
0
  return status;
19977
0
#endif
19978
0
}
19979
19980
int
19981
ncx_getn_ulonglong_longlong(const void **xpp, size_t nelems, longlong *tp)
19982
0
{
19983
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19984
19985
 /* basic algorithm is:
19986
  *   - ensure sane alignment of input data
19987
  *   - copy (conversion happens automatically) input data
19988
  *     to output
19989
  *   - update xpp to point at next unconverted input, and tp to point
19990
  *     at next location for converted output
19991
  */
19992
  long i, j, ni;
19993
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19994
  uint64 *xp;
19995
  int nrange = 0;         /* number of range errors */
19996
  int realign = 0;        /* "do we need to fix input data alignment?" */
19997
  long cxp = (long) *((char**)xpp);
19998
19999
  realign = (cxp & 7) % SIZEOF_UINT64;
20000
  /* sjl: manually stripmine so we can limit amount of
20001
   * vector work space reserved to LOOPCNT elements. Also
20002
   * makes vectorisation easy */
20003
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20004
    ni=Min(nelems-j,LOOPCNT);
20005
    if (realign) {
20006
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20007
      xp = tmp;
20008
    } else {
20009
      xp = (uint64 *) *xpp;
20010
    }
20011
   /* copy the next block */
20012
#pragma cdir loopcnt=LOOPCNT
20013
#pragma cdir shortloop
20014
    for (i=0; i<ni; i++) {
20015
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
20016
     /* test for range errors (not always needed but do it anyway) */
20017
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20018
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20019
      nrange += xp[i] > LONGLONG_MAX ;
20020
    }
20021
   /* update xpp and tp */
20022
    if (realign) xp = (uint64 *) *xpp;
20023
    xp += ni;
20024
    tp += ni;
20025
    *xpp = (void*)xp;
20026
  }
20027
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20028
20029
#else   /* not SX */
20030
0
  const char *xp = (const char *) *xpp;
20031
0
  int status = NC_NOERR;
20032
20033
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20034
0
  {
20035
0
    const int lstatus = ncx_get_ulonglong_longlong(xp, tp);
20036
0
    if (status == NC_NOERR) /* report the first encountered error */
20037
0
      status = lstatus;
20038
0
  }
20039
20040
0
  *xpp = (const void *)xp;
20041
0
  return status;
20042
0
#endif
20043
0
}
20044
20045
int
20046
ncx_getn_ulonglong_uchar(const void **xpp, size_t nelems, uchar *tp)
20047
0
{
20048
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20049
20050
 /* basic algorithm is:
20051
  *   - ensure sane alignment of input data
20052
  *   - copy (conversion happens automatically) input data
20053
  *     to output
20054
  *   - update xpp to point at next unconverted input, and tp to point
20055
  *     at next location for converted output
20056
  */
20057
  long i, j, ni;
20058
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20059
  uint64 *xp;
20060
  int nrange = 0;         /* number of range errors */
20061
  int realign = 0;        /* "do we need to fix input data alignment?" */
20062
  long cxp = (long) *((char**)xpp);
20063
20064
  realign = (cxp & 7) % SIZEOF_UINT64;
20065
  /* sjl: manually stripmine so we can limit amount of
20066
   * vector work space reserved to LOOPCNT elements. Also
20067
   * makes vectorisation easy */
20068
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20069
    ni=Min(nelems-j,LOOPCNT);
20070
    if (realign) {
20071
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20072
      xp = tmp;
20073
    } else {
20074
      xp = (uint64 *) *xpp;
20075
    }
20076
   /* copy the next block */
20077
#pragma cdir loopcnt=LOOPCNT
20078
#pragma cdir shortloop
20079
    for (i=0; i<ni; i++) {
20080
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
20081
     /* test for range errors (not always needed but do it anyway) */
20082
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20083
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20084
      nrange += xp[i] > UCHAR_MAX ;
20085
    }
20086
   /* update xpp and tp */
20087
    if (realign) xp = (uint64 *) *xpp;
20088
    xp += ni;
20089
    tp += ni;
20090
    *xpp = (void*)xp;
20091
  }
20092
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20093
20094
#else   /* not SX */
20095
0
  const char *xp = (const char *) *xpp;
20096
0
  int status = NC_NOERR;
20097
20098
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20099
0
  {
20100
0
    const int lstatus = ncx_get_ulonglong_uchar(xp, tp);
20101
0
    if (status == NC_NOERR) /* report the first encountered error */
20102
0
      status = lstatus;
20103
0
  }
20104
20105
0
  *xpp = (const void *)xp;
20106
0
  return status;
20107
0
#endif
20108
0
}
20109
20110
int
20111
ncx_getn_ulonglong_ushort(const void **xpp, size_t nelems, ushort *tp)
20112
0
{
20113
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20114
20115
 /* basic algorithm is:
20116
  *   - ensure sane alignment of input data
20117
  *   - copy (conversion happens automatically) input data
20118
  *     to output
20119
  *   - update xpp to point at next unconverted input, and tp to point
20120
  *     at next location for converted output
20121
  */
20122
  long i, j, ni;
20123
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20124
  uint64 *xp;
20125
  int nrange = 0;         /* number of range errors */
20126
  int realign = 0;        /* "do we need to fix input data alignment?" */
20127
  long cxp = (long) *((char**)xpp);
20128
20129
  realign = (cxp & 7) % SIZEOF_UINT64;
20130
  /* sjl: manually stripmine so we can limit amount of
20131
   * vector work space reserved to LOOPCNT elements. Also
20132
   * makes vectorisation easy */
20133
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20134
    ni=Min(nelems-j,LOOPCNT);
20135
    if (realign) {
20136
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20137
      xp = tmp;
20138
    } else {
20139
      xp = (uint64 *) *xpp;
20140
    }
20141
   /* copy the next block */
20142
#pragma cdir loopcnt=LOOPCNT
20143
#pragma cdir shortloop
20144
    for (i=0; i<ni; i++) {
20145
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
20146
     /* test for range errors (not always needed but do it anyway) */
20147
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20148
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20149
      nrange += xp[i] > USHORT_MAX ;
20150
    }
20151
   /* update xpp and tp */
20152
    if (realign) xp = (uint64 *) *xpp;
20153
    xp += ni;
20154
    tp += ni;
20155
    *xpp = (void*)xp;
20156
  }
20157
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20158
20159
#else   /* not SX */
20160
0
  const char *xp = (const char *) *xpp;
20161
0
  int status = NC_NOERR;
20162
20163
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20164
0
  {
20165
0
    const int lstatus = ncx_get_ulonglong_ushort(xp, tp);
20166
0
    if (status == NC_NOERR) /* report the first encountered error */
20167
0
      status = lstatus;
20168
0
  }
20169
20170
0
  *xpp = (const void *)xp;
20171
0
  return status;
20172
0
#endif
20173
0
}
20174
20175
int
20176
ncx_getn_ulonglong_uint(const void **xpp, size_t nelems, uint *tp)
20177
0
{
20178
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20179
20180
 /* basic algorithm is:
20181
  *   - ensure sane alignment of input data
20182
  *   - copy (conversion happens automatically) input data
20183
  *     to output
20184
  *   - update xpp to point at next unconverted input, and tp to point
20185
  *     at next location for converted output
20186
  */
20187
  long i, j, ni;
20188
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20189
  uint64 *xp;
20190
  int nrange = 0;         /* number of range errors */
20191
  int realign = 0;        /* "do we need to fix input data alignment?" */
20192
  long cxp = (long) *((char**)xpp);
20193
20194
  realign = (cxp & 7) % SIZEOF_UINT64;
20195
  /* sjl: manually stripmine so we can limit amount of
20196
   * vector work space reserved to LOOPCNT elements. Also
20197
   * makes vectorisation easy */
20198
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20199
    ni=Min(nelems-j,LOOPCNT);
20200
    if (realign) {
20201
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20202
      xp = tmp;
20203
    } else {
20204
      xp = (uint64 *) *xpp;
20205
    }
20206
   /* copy the next block */
20207
#pragma cdir loopcnt=LOOPCNT
20208
#pragma cdir shortloop
20209
    for (i=0; i<ni; i++) {
20210
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
20211
     /* test for range errors (not always needed but do it anyway) */
20212
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20213
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20214
      nrange += xp[i] > UINT_MAX ;
20215
    }
20216
   /* update xpp and tp */
20217
    if (realign) xp = (uint64 *) *xpp;
20218
    xp += ni;
20219
    tp += ni;
20220
    *xpp = (void*)xp;
20221
  }
20222
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20223
20224
#else   /* not SX */
20225
0
  const char *xp = (const char *) *xpp;
20226
0
  int status = NC_NOERR;
20227
20228
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20229
0
  {
20230
0
    const int lstatus = ncx_get_ulonglong_uint(xp, tp);
20231
0
    if (status == NC_NOERR) /* report the first encountered error */
20232
0
      status = lstatus;
20233
0
  }
20234
20235
0
  *xpp = (const void *)xp;
20236
0
  return status;
20237
0
#endif
20238
0
}
20239
20240
20241
#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
20242
/* optimized version */
20243
int
20244
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp, void *fillp)
20245
0
{
20246
#ifdef WORDS_BIGENDIAN
20247
  (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
20248
# else
20249
0
  swapn8b(*xpp, tp, nelems);
20250
0
# endif
20251
0
  *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
20252
0
  return NC_NOERR;
20253
0
}
20254
#else
20255
int
20256
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
20257
{
20258
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20259
20260
 /* basic algorithm is:
20261
  *   - ensure sane alignment of output data
20262
  *   - copy (conversion happens automatically) input data
20263
  *     to output
20264
  *   - update tp to point at next unconverted input, and xpp to point
20265
  *     at next location for converted output
20266
  */
20267
  long i, j, ni;
20268
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20269
  uint64 *xp;
20270
  int nrange = 0;         /* number of range errors */
20271
  int realign = 0;        /* "do we need to fix input data alignment?" */
20272
  long cxp = (long) *((char**)xpp);
20273
20274
  realign = (cxp & 7) % SIZEOF_UINT64;
20275
  /* sjl: manually stripmine so we can limit amount of
20276
   * vector work space reserved to LOOPCNT elements. Also
20277
   * makes vectorisation easy */
20278
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20279
    ni=Min(nelems-j,LOOPCNT);
20280
    if (realign) {
20281
      xp = tmp;
20282
    } else {
20283
      xp = (uint64 *) *xpp;
20284
    }
20285
   /* copy the next block */
20286
#pragma cdir loopcnt=LOOPCNT
20287
#pragma cdir shortloop
20288
    for (i=0; i<ni; i++) {
20289
      /* the normal case: */
20290
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20291
     /* test for range errors (not always needed but do it anyway) */
20292
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20293
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20294
      nrange += tp[i] > X_UINT64_MAX ;
20295
    }
20296
   /* copy workspace back if necessary */
20297
    if (realign) {
20298
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20299
      xp = (uint64 *) *xpp;
20300
    }
20301
   /* update xpp and tp */
20302
    xp += ni;
20303
    tp += ni;
20304
    *xpp = (void*)xp;
20305
  }
20306
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20307
20308
#else   /* not SX */
20309
20310
  char *xp = (char *) *xpp;
20311
  int status = NC_NOERR;
20312
20313
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20314
  {
20315
    int lstatus = ncx_put_ulonglong_ulonglong(xp, tp, fillp);
20316
    if (status == NC_NOERR) /* report the first encountered error */
20317
      status = lstatus;
20318
  }
20319
20320
  *xpp = (void *)xp;
20321
  return status;
20322
#endif
20323
}
20324
20325
#endif
20326
int
20327
ncx_putn_ulonglong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
20328
0
{
20329
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20330
20331
 /* basic algorithm is:
20332
  *   - ensure sane alignment of output data
20333
  *   - copy (conversion happens automatically) input data
20334
  *     to output
20335
  *   - update tp to point at next unconverted input, and xpp to point
20336
  *     at next location for converted output
20337
  */
20338
  long i, j, ni;
20339
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20340
  uint64 *xp;
20341
  int nrange = 0;         /* number of range errors */
20342
  int realign = 0;        /* "do we need to fix input data alignment?" */
20343
  long cxp = (long) *((char**)xpp);
20344
20345
  realign = (cxp & 7) % SIZEOF_UINT64;
20346
  /* sjl: manually stripmine so we can limit amount of
20347
   * vector work space reserved to LOOPCNT elements. Also
20348
   * makes vectorisation easy */
20349
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20350
    ni=Min(nelems-j,LOOPCNT);
20351
    if (realign) {
20352
      xp = tmp;
20353
    } else {
20354
      xp = (uint64 *) *xpp;
20355
    }
20356
   /* copy the next block */
20357
#pragma cdir loopcnt=LOOPCNT
20358
#pragma cdir shortloop
20359
    for (i=0; i<ni; i++) {
20360
      /* the normal case: */
20361
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20362
     /* test for range errors (not always needed but do it anyway) */
20363
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20364
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20365
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20366
    }
20367
   /* copy workspace back if necessary */
20368
    if (realign) {
20369
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20370
      xp = (uint64 *) *xpp;
20371
    }
20372
   /* update xpp and tp */
20373
    xp += ni;
20374
    tp += ni;
20375
    *xpp = (void*)xp;
20376
  }
20377
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20378
20379
#else   /* not SX */
20380
20381
0
  char *xp = (char *) *xpp;
20382
0
  int status = NC_NOERR;
20383
20384
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20385
0
  {
20386
0
    int lstatus = ncx_put_ulonglong_schar(xp, tp, fillp);
20387
0
    if (status == NC_NOERR) /* report the first encountered error */
20388
0
      status = lstatus;
20389
0
  }
20390
20391
0
  *xpp = (void *)xp;
20392
0
  return status;
20393
0
#endif
20394
0
}
20395
20396
int
20397
ncx_putn_ulonglong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
20398
0
{
20399
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20400
20401
 /* basic algorithm is:
20402
  *   - ensure sane alignment of output data
20403
  *   - copy (conversion happens automatically) input data
20404
  *     to output
20405
  *   - update tp to point at next unconverted input, and xpp to point
20406
  *     at next location for converted output
20407
  */
20408
  long i, j, ni;
20409
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20410
  uint64 *xp;
20411
  int nrange = 0;         /* number of range errors */
20412
  int realign = 0;        /* "do we need to fix input data alignment?" */
20413
  long cxp = (long) *((char**)xpp);
20414
20415
  realign = (cxp & 7) % SIZEOF_UINT64;
20416
  /* sjl: manually stripmine so we can limit amount of
20417
   * vector work space reserved to LOOPCNT elements. Also
20418
   * makes vectorisation easy */
20419
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20420
    ni=Min(nelems-j,LOOPCNT);
20421
    if (realign) {
20422
      xp = tmp;
20423
    } else {
20424
      xp = (uint64 *) *xpp;
20425
    }
20426
   /* copy the next block */
20427
#pragma cdir loopcnt=LOOPCNT
20428
#pragma cdir shortloop
20429
    for (i=0; i<ni; i++) {
20430
      /* the normal case: */
20431
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20432
     /* test for range errors (not always needed but do it anyway) */
20433
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20434
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20435
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20436
    }
20437
   /* copy workspace back if necessary */
20438
    if (realign) {
20439
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20440
      xp = (uint64 *) *xpp;
20441
    }
20442
   /* update xpp and tp */
20443
    xp += ni;
20444
    tp += ni;
20445
    *xpp = (void*)xp;
20446
  }
20447
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20448
20449
#else   /* not SX */
20450
20451
0
  char *xp = (char *) *xpp;
20452
0
  int status = NC_NOERR;
20453
20454
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20455
0
  {
20456
0
    int lstatus = ncx_put_ulonglong_short(xp, tp, fillp);
20457
0
    if (status == NC_NOERR) /* report the first encountered error */
20458
0
      status = lstatus;
20459
0
  }
20460
20461
0
  *xpp = (void *)xp;
20462
0
  return status;
20463
0
#endif
20464
0
}
20465
20466
int
20467
ncx_putn_ulonglong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
20468
0
{
20469
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20470
20471
 /* basic algorithm is:
20472
  *   - ensure sane alignment of output data
20473
  *   - copy (conversion happens automatically) input data
20474
  *     to output
20475
  *   - update tp to point at next unconverted input, and xpp to point
20476
  *     at next location for converted output
20477
  */
20478
  long i, j, ni;
20479
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20480
  uint64 *xp;
20481
  int nrange = 0;         /* number of range errors */
20482
  int realign = 0;        /* "do we need to fix input data alignment?" */
20483
  long cxp = (long) *((char**)xpp);
20484
20485
  realign = (cxp & 7) % SIZEOF_UINT64;
20486
  /* sjl: manually stripmine so we can limit amount of
20487
   * vector work space reserved to LOOPCNT elements. Also
20488
   * makes vectorisation easy */
20489
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20490
    ni=Min(nelems-j,LOOPCNT);
20491
    if (realign) {
20492
      xp = tmp;
20493
    } else {
20494
      xp = (uint64 *) *xpp;
20495
    }
20496
   /* copy the next block */
20497
#pragma cdir loopcnt=LOOPCNT
20498
#pragma cdir shortloop
20499
    for (i=0; i<ni; i++) {
20500
      /* the normal case: */
20501
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20502
     /* test for range errors (not always needed but do it anyway) */
20503
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20504
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20505
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20506
    }
20507
   /* copy workspace back if necessary */
20508
    if (realign) {
20509
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20510
      xp = (uint64 *) *xpp;
20511
    }
20512
   /* update xpp and tp */
20513
    xp += ni;
20514
    tp += ni;
20515
    *xpp = (void*)xp;
20516
  }
20517
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20518
20519
#else   /* not SX */
20520
20521
0
  char *xp = (char *) *xpp;
20522
0
  int status = NC_NOERR;
20523
20524
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20525
0
  {
20526
0
    int lstatus = ncx_put_ulonglong_int(xp, tp, fillp);
20527
0
    if (status == NC_NOERR) /* report the first encountered error */
20528
0
      status = lstatus;
20529
0
  }
20530
20531
0
  *xpp = (void *)xp;
20532
0
  return status;
20533
0
#endif
20534
0
}
20535
20536
int
20537
ncx_putn_ulonglong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
20538
0
{
20539
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20540
20541
 /* basic algorithm is:
20542
  *   - ensure sane alignment of output data
20543
  *   - copy (conversion happens automatically) input data
20544
  *     to output
20545
  *   - update tp to point at next unconverted input, and xpp to point
20546
  *     at next location for converted output
20547
  */
20548
  long i, j, ni;
20549
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20550
  uint64 *xp;
20551
  int nrange = 0;         /* number of range errors */
20552
  int realign = 0;        /* "do we need to fix input data alignment?" */
20553
  long cxp = (long) *((char**)xpp);
20554
20555
  realign = (cxp & 7) % SIZEOF_UINT64;
20556
  /* sjl: manually stripmine so we can limit amount of
20557
   * vector work space reserved to LOOPCNT elements. Also
20558
   * makes vectorisation easy */
20559
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20560
    ni=Min(nelems-j,LOOPCNT);
20561
    if (realign) {
20562
      xp = tmp;
20563
    } else {
20564
      xp = (uint64 *) *xpp;
20565
    }
20566
   /* copy the next block */
20567
#pragma cdir loopcnt=LOOPCNT
20568
#pragma cdir shortloop
20569
    for (i=0; i<ni; i++) {
20570
      /* the normal case: */
20571
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20572
     /* test for range errors (not always needed but do it anyway) */
20573
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20574
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20575
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20576
    }
20577
   /* copy workspace back if necessary */
20578
    if (realign) {
20579
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20580
      xp = (uint64 *) *xpp;
20581
    }
20582
   /* update xpp and tp */
20583
    xp += ni;
20584
    tp += ni;
20585
    *xpp = (void*)xp;
20586
  }
20587
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20588
20589
#else   /* not SX */
20590
20591
0
  char *xp = (char *) *xpp;
20592
0
  int status = NC_NOERR;
20593
20594
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20595
0
  {
20596
0
    int lstatus = ncx_put_ulonglong_long(xp, tp, fillp);
20597
0
    if (status == NC_NOERR) /* report the first encountered error */
20598
0
      status = lstatus;
20599
0
  }
20600
20601
0
  *xpp = (void *)xp;
20602
0
  return status;
20603
0
#endif
20604
0
}
20605
20606
int
20607
ncx_putn_ulonglong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
20608
0
{
20609
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20610
20611
 /* basic algorithm is:
20612
  *   - ensure sane alignment of output data
20613
  *   - copy (conversion happens automatically) input data
20614
  *     to output
20615
  *   - update tp to point at next unconverted input, and xpp to point
20616
  *     at next location for converted output
20617
  */
20618
  long i, j, ni;
20619
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20620
  uint64 *xp;
20621
  int nrange = 0;         /* number of range errors */
20622
  int realign = 0;        /* "do we need to fix input data alignment?" */
20623
  long cxp = (long) *((char**)xpp);
20624
20625
  realign = (cxp & 7) % SIZEOF_UINT64;
20626
  /* sjl: manually stripmine so we can limit amount of
20627
   * vector work space reserved to LOOPCNT elements. Also
20628
   * makes vectorisation easy */
20629
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20630
    ni=Min(nelems-j,LOOPCNT);
20631
    if (realign) {
20632
      xp = tmp;
20633
    } else {
20634
      xp = (uint64 *) *xpp;
20635
    }
20636
   /* copy the next block */
20637
#pragma cdir loopcnt=LOOPCNT
20638
#pragma cdir shortloop
20639
    for (i=0; i<ni; i++) {
20640
      /* the normal case: */
20641
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20642
     /* test for range errors (not always needed but do it anyway) */
20643
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20644
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20645
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20646
    }
20647
   /* copy workspace back if necessary */
20648
    if (realign) {
20649
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20650
      xp = (uint64 *) *xpp;
20651
    }
20652
   /* update xpp and tp */
20653
    xp += ni;
20654
    tp += ni;
20655
    *xpp = (void*)xp;
20656
  }
20657
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20658
20659
#else   /* not SX */
20660
20661
0
  char *xp = (char *) *xpp;
20662
0
  int status = NC_NOERR;
20663
20664
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20665
0
  {
20666
0
    int lstatus = ncx_put_ulonglong_float(xp, tp, fillp);
20667
0
    if (status == NC_NOERR) /* report the first encountered error */
20668
0
      status = lstatus;
20669
0
  }
20670
20671
0
  *xpp = (void *)xp;
20672
0
  return status;
20673
0
#endif
20674
0
}
20675
20676
int
20677
ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
20678
0
{
20679
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20680
20681
 /* basic algorithm is:
20682
  *   - ensure sane alignment of output data
20683
  *   - copy (conversion happens automatically) input data
20684
  *     to output
20685
  *   - update tp to point at next unconverted input, and xpp to point
20686
  *     at next location for converted output
20687
  */
20688
  long i, j, ni;
20689
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20690
  uint64 *xp;
20691
  int nrange = 0;         /* number of range errors */
20692
  int realign = 0;        /* "do we need to fix input data alignment?" */
20693
  long cxp = (long) *((char**)xpp);
20694
20695
  realign = (cxp & 7) % SIZEOF_UINT64;
20696
  /* sjl: manually stripmine so we can limit amount of
20697
   * vector work space reserved to LOOPCNT elements. Also
20698
   * makes vectorisation easy */
20699
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20700
    ni=Min(nelems-j,LOOPCNT);
20701
    if (realign) {
20702
      xp = tmp;
20703
    } else {
20704
      xp = (uint64 *) *xpp;
20705
    }
20706
   /* copy the next block */
20707
#pragma cdir loopcnt=LOOPCNT
20708
#pragma cdir shortloop
20709
    for (i=0; i<ni; i++) {
20710
      /* the normal case: */
20711
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20712
     /* test for range errors (not always needed but do it anyway) */
20713
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20714
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20715
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20716
    }
20717
   /* copy workspace back if necessary */
20718
    if (realign) {
20719
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20720
      xp = (uint64 *) *xpp;
20721
    }
20722
   /* update xpp and tp */
20723
    xp += ni;
20724
    tp += ni;
20725
    *xpp = (void*)xp;
20726
  }
20727
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20728
20729
#else   /* not SX */
20730
20731
0
  char *xp = (char *) *xpp;
20732
0
  int status = NC_NOERR;
20733
20734
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20735
0
  {
20736
0
    int lstatus = ncx_put_ulonglong_double(xp, tp, fillp);
20737
0
    if (status == NC_NOERR) /* report the first encountered error */
20738
0
      status = lstatus;
20739
0
  }
20740
20741
0
  *xpp = (void *)xp;
20742
0
  return status;
20743
0
#endif
20744
0
}
20745
20746
int
20747
ncx_putn_ulonglong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
20748
0
{
20749
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20750
20751
 /* basic algorithm is:
20752
  *   - ensure sane alignment of output data
20753
  *   - copy (conversion happens automatically) input data
20754
  *     to output
20755
  *   - update tp to point at next unconverted input, and xpp to point
20756
  *     at next location for converted output
20757
  */
20758
  long i, j, ni;
20759
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20760
  uint64 *xp;
20761
  int nrange = 0;         /* number of range errors */
20762
  int realign = 0;        /* "do we need to fix input data alignment?" */
20763
  long cxp = (long) *((char**)xpp);
20764
20765
  realign = (cxp & 7) % SIZEOF_UINT64;
20766
  /* sjl: manually stripmine so we can limit amount of
20767
   * vector work space reserved to LOOPCNT elements. Also
20768
   * makes vectorisation easy */
20769
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20770
    ni=Min(nelems-j,LOOPCNT);
20771
    if (realign) {
20772
      xp = tmp;
20773
    } else {
20774
      xp = (uint64 *) *xpp;
20775
    }
20776
   /* copy the next block */
20777
#pragma cdir loopcnt=LOOPCNT
20778
#pragma cdir shortloop
20779
    for (i=0; i<ni; i++) {
20780
      /* the normal case: */
20781
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20782
     /* test for range errors (not always needed but do it anyway) */
20783
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20784
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20785
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20786
    }
20787
   /* copy workspace back if necessary */
20788
    if (realign) {
20789
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20790
      xp = (uint64 *) *xpp;
20791
    }
20792
   /* update xpp and tp */
20793
    xp += ni;
20794
    tp += ni;
20795
    *xpp = (void*)xp;
20796
  }
20797
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20798
20799
#else   /* not SX */
20800
20801
0
  char *xp = (char *) *xpp;
20802
0
  int status = NC_NOERR;
20803
20804
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20805
0
  {
20806
0
    int lstatus = ncx_put_ulonglong_longlong(xp, tp, fillp);
20807
0
    if (status == NC_NOERR) /* report the first encountered error */
20808
0
      status = lstatus;
20809
0
  }
20810
20811
0
  *xpp = (void *)xp;
20812
0
  return status;
20813
0
#endif
20814
0
}
20815
20816
int
20817
ncx_putn_ulonglong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
20818
0
{
20819
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20820
20821
 /* basic algorithm is:
20822
  *   - ensure sane alignment of output data
20823
  *   - copy (conversion happens automatically) input data
20824
  *     to output
20825
  *   - update tp to point at next unconverted input, and xpp to point
20826
  *     at next location for converted output
20827
  */
20828
  long i, j, ni;
20829
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20830
  uint64 *xp;
20831
  int nrange = 0;         /* number of range errors */
20832
  int realign = 0;        /* "do we need to fix input data alignment?" */
20833
  long cxp = (long) *((char**)xpp);
20834
20835
  realign = (cxp & 7) % SIZEOF_UINT64;
20836
  /* sjl: manually stripmine so we can limit amount of
20837
   * vector work space reserved to LOOPCNT elements. Also
20838
   * makes vectorisation easy */
20839
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20840
    ni=Min(nelems-j,LOOPCNT);
20841
    if (realign) {
20842
      xp = tmp;
20843
    } else {
20844
      xp = (uint64 *) *xpp;
20845
    }
20846
   /* copy the next block */
20847
#pragma cdir loopcnt=LOOPCNT
20848
#pragma cdir shortloop
20849
    for (i=0; i<ni; i++) {
20850
      /* the normal case: */
20851
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20852
     /* test for range errors (not always needed but do it anyway) */
20853
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20854
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20855
      nrange += tp[i] > X_UINT64_MAX ;
20856
    }
20857
   /* copy workspace back if necessary */
20858
    if (realign) {
20859
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20860
      xp = (uint64 *) *xpp;
20861
    }
20862
   /* update xpp and tp */
20863
    xp += ni;
20864
    tp += ni;
20865
    *xpp = (void*)xp;
20866
  }
20867
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20868
20869
#else   /* not SX */
20870
20871
0
  char *xp = (char *) *xpp;
20872
0
  int status = NC_NOERR;
20873
20874
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20875
0
  {
20876
0
    int lstatus = ncx_put_ulonglong_uchar(xp, tp, fillp);
20877
0
    if (status == NC_NOERR) /* report the first encountered error */
20878
0
      status = lstatus;
20879
0
  }
20880
20881
0
  *xpp = (void *)xp;
20882
0
  return status;
20883
0
#endif
20884
0
}
20885
20886
int
20887
ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
20888
0
{
20889
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20890
20891
 /* basic algorithm is:
20892
  *   - ensure sane alignment of output data
20893
  *   - copy (conversion happens automatically) input data
20894
  *     to output
20895
  *   - update tp to point at next unconverted input, and xpp to point
20896
  *     at next location for converted output
20897
  */
20898
  long i, j, ni;
20899
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20900
  uint64 *xp;
20901
  int nrange = 0;         /* number of range errors */
20902
  int realign = 0;        /* "do we need to fix input data alignment?" */
20903
  long cxp = (long) *((char**)xpp);
20904
20905
  realign = (cxp & 7) % SIZEOF_UINT64;
20906
  /* sjl: manually stripmine so we can limit amount of
20907
   * vector work space reserved to LOOPCNT elements. Also
20908
   * makes vectorisation easy */
20909
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20910
    ni=Min(nelems-j,LOOPCNT);
20911
    if (realign) {
20912
      xp = tmp;
20913
    } else {
20914
      xp = (uint64 *) *xpp;
20915
    }
20916
   /* copy the next block */
20917
#pragma cdir loopcnt=LOOPCNT
20918
#pragma cdir shortloop
20919
    for (i=0; i<ni; i++) {
20920
      /* the normal case: */
20921
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20922
     /* test for range errors (not always needed but do it anyway) */
20923
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20924
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20925
      nrange += tp[i] > X_UINT64_MAX ;
20926
    }
20927
   /* copy workspace back if necessary */
20928
    if (realign) {
20929
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20930
      xp = (uint64 *) *xpp;
20931
    }
20932
   /* update xpp and tp */
20933
    xp += ni;
20934
    tp += ni;
20935
    *xpp = (void*)xp;
20936
  }
20937
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
20938
20939
#else   /* not SX */
20940
20941
0
  char *xp = (char *) *xpp;
20942
0
  int status = NC_NOERR;
20943
20944
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20945
0
  {
20946
0
    int lstatus = ncx_put_ulonglong_ushort(xp, tp, fillp);
20947
0
    if (status == NC_NOERR) /* report the first encountered error */
20948
0
      status = lstatus;
20949
0
  }
20950
20951
0
  *xpp = (void *)xp;
20952
0
  return status;
20953
0
#endif
20954
0
}
20955
20956
int
20957
ncx_putn_ulonglong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
20958
0
{
20959
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20960
20961
 /* basic algorithm is:
20962
  *   - ensure sane alignment of output data
20963
  *   - copy (conversion happens automatically) input data
20964
  *     to output
20965
  *   - update tp to point at next unconverted input, and xpp to point
20966
  *     at next location for converted output
20967
  */
20968
  long i, j, ni;
20969
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20970
  uint64 *xp;
20971
  int nrange = 0;         /* number of range errors */
20972
  int realign = 0;        /* "do we need to fix input data alignment?" */
20973
  long cxp = (long) *((char**)xpp);
20974
20975
  realign = (cxp & 7) % SIZEOF_UINT64;
20976
  /* sjl: manually stripmine so we can limit amount of
20977
   * vector work space reserved to LOOPCNT elements. Also
20978
   * makes vectorisation easy */
20979
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20980
    ni=Min(nelems-j,LOOPCNT);
20981
    if (realign) {
20982
      xp = tmp;
20983
    } else {
20984
      xp = (uint64 *) *xpp;
20985
    }
20986
   /* copy the next block */
20987
#pragma cdir loopcnt=LOOPCNT
20988
#pragma cdir shortloop
20989
    for (i=0; i<ni; i++) {
20990
      /* the normal case: */
20991
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20992
     /* test for range errors (not always needed but do it anyway) */
20993
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20994
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20995
      nrange += tp[i] > X_UINT64_MAX ;
20996
    }
20997
   /* copy workspace back if necessary */
20998
    if (realign) {
20999
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
21000
      xp = (uint64 *) *xpp;
21001
    }
21002
   /* update xpp and tp */
21003
    xp += ni;
21004
    tp += ni;
21005
    *xpp = (void*)xp;
21006
  }
21007
  return nrange == 0 ? NC_NOERR : NC_ERANGE;
21008
21009
#else   /* not SX */
21010
21011
0
  char *xp = (char *) *xpp;
21012
0
  int status = NC_NOERR;
21013
21014
0
  for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
21015
0
  {
21016
0
    int lstatus = ncx_put_ulonglong_uint(xp, tp, fillp);
21017
0
    if (status == NC_NOERR) /* report the first encountered error */
21018
0
      status = lstatus;
21019
0
  }
21020
21021
0
  *xpp = (void *)xp;
21022
0
  return status;
21023
0
#endif
21024
0
}
21025
21026
21027
21028
/*
21029
 * Other aggregate conversion functions.
21030
 */
21031
21032
/* text */
21033
21034
int
21035
ncx_getn_text(const void **xpp, size_t nelems, char *tp)
21036
0
{
21037
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
21038
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21039
0
  return NC_NOERR;
21040
21041
0
}
21042
21043
int
21044
ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
21045
357k
{
21046
357k
  size_t rndup = nelems % X_ALIGN;
21047
21048
357k
  if (rndup)
21049
1.52k
    rndup = X_ALIGN - rndup;
21050
21051
357k
  (void) memcpy(tp, *xpp, (size_t)nelems);
21052
357k
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
21053
21054
357k
  return NC_NOERR;
21055
21056
357k
}
21057
21058
int
21059
ncx_putn_text(void **xpp, size_t nelems, const char *tp)
21060
0
{
21061
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
21062
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21063
21064
0
  return NC_NOERR;
21065
21066
0
}
21067
21068
int
21069
ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
21070
0
{
21071
0
  size_t rndup = nelems % X_ALIGN;
21072
21073
0
  if (rndup)
21074
0
    rndup = X_ALIGN - rndup;
21075
21076
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
21077
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21078
21079
0
  if (rndup)
21080
0
  {
21081
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
21082
0
    *xpp = (void *)((char *)(*xpp) + rndup);
21083
0
  }
21084
21085
0
  return NC_NOERR;
21086
21087
0
}
21088
21089
21090
/* opaque */
21091
21092
int
21093
ncx_getn_void(const void **xpp, size_t nelems, void *tp)
21094
0
{
21095
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
21096
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21097
0
  return NC_NOERR;
21098
21099
0
}
21100
21101
int
21102
ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
21103
0
{
21104
0
  size_t rndup = nelems % X_ALIGN;
21105
21106
0
  if (rndup)
21107
0
    rndup = X_ALIGN - rndup;
21108
21109
0
  (void) memcpy(tp, *xpp, (size_t)nelems);
21110
0
  *xpp = (void *)((char *)(*xpp) + nelems + rndup);
21111
21112
0
  return NC_NOERR;
21113
21114
0
}
21115
21116
int
21117
ncx_putn_void(void **xpp, size_t nelems, const void *tp)
21118
0
{
21119
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
21120
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21121
21122
0
  return NC_NOERR;
21123
21124
0
}
21125
21126
int
21127
ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
21128
0
{
21129
0
  size_t rndup = nelems % X_ALIGN;
21130
21131
0
  if (rndup)
21132
0
    rndup = X_ALIGN - rndup;
21133
21134
0
  (void) memcpy(*xpp, tp, (size_t)nelems);
21135
0
  *xpp = (void *)((char *)(*xpp) + nelems);
21136
21137
0
  if (rndup)
21138
0
  {
21139
0
    (void) memcpy(*xpp, nada, (size_t)rndup);
21140
0
    *xpp = (void *)((char *)(*xpp) + rndup);
21141
0
  }
21142
21143
0
  return NC_NOERR;
21144
21145
0
}