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 #define  SHORT_MAX  SHRT_MAX
54 #define  SHORT_MIN  SHRT_MIN
55 #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 #define LONG_LONG_MAX LLONG_MAX
63 #endif
64 #ifndef LONGLONG_MAX
65 #define LONGLONG_MAX LONG_LONG_MAX
66 #endif
67 #ifndef LONG_LONG_MIN
68 #define LONG_LONG_MIN LLONG_MIN
69 #endif
70 #ifndef LONGLONG_MIN
71 #define LONGLONG_MIN LONG_LONG_MIN
72 #endif
73 #ifndef ULONG_LONG_MAX
74 #define ULONG_LONG_MAX ULLONG_MAX
75 #endif
76 #ifndef ULONGLONG_MAX
77 #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 #define SWAP2(a) ( (((a) & 0xff) << 8) | \
204                    (((a) >> 8) & 0xff) )
205 
206 #define SWAP4(a) ( ((a) << 24) | \
207                   (((a) <<  8) & 0x00ff0000) | \
208                   (((a) >>  8) & 0x0000ff00) | \
209                   (((a) >> 24) & 0x000000ff) )
210 
211 #define SWAP8(a) ( (((a) & 0x00000000000000FFULL) << 56) | \
212                    (((a) & 0x000000000000FF00ULL) << 40) | \
213                    (((a) & 0x0000000000FF0000ULL) << 24) | \
214                    (((a) & 0x00000000FF000000ULL) <<  8) | \
215                    (((a) & 0x000000FF00000000ULL) >>  8) | \
216                    (((a) & 0x0000FF0000000000ULL) >> 24) | \
217                    (((a) & 0x00FF000000000000ULL) >> 40) | \
218                    (((a) & 0xFF00000000000000ULL) >> 56) )
219 
220 #if defined(_MSC_VER) && _MSC_VER < 1900
221 #define inline __inline
222 #endif
223 
224 inline static void
swapn2b(void * dst,const void * src,size_t nn)225 swapn2b(void *dst, const void *src, size_t nn)
226 {
227     /* it is OK if dst == src */
228     int i;
229     uint16_t *op = (uint16_t*) dst;
230     uint16_t *ip = (uint16_t*) src;
231     for (i=0; i<nn; i++) {
232         op[i] = ip[i];
233         op[i] = (uint16_t)SWAP2(op[i]);
234     }
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 }
266 
267 # ifndef vax
268 inline static void
swap4b(void * dst,const void * src)269 swap4b(void *dst, const void *src)
270 {
271     /* copy over, make the below swap in-place */
272     uint32_t tmp = *(uint32_t*)src;
273     tmp = SWAP4(tmp);
274     memcpy(dst, &tmp, 4);
275 
276     /* Codes below will cause "break strict-aliasing rules" in gcc
277     uint32_t *op = (uint32_t*)dst;
278     *op = *(uint32_t*)src;
279     *op = SWAP4(*op);
280     */
281 
282     /* Below are copied from netCDF-4.
283      * See https://bugtracking.unidata.ucar.edu/browse/NCF-338
284      * Quote "One issue we are wrestling with is how compilers optimize this
285      * code.  For some reason, we are actually needing to add an artificial
286      * move to a 4 byte space to get it to work.  I think what is happening is
287      * that the optimizer is bit shifting within a double, which is incorrect.
288      * The following code actually does work correctly.
289      *  This is in Linux land, gcc.
290      *
291      * However, the above in-place byte-swap does not appear affected by this.
292      */
293 #if 0
294     uint32_t *ip = (uint32_t*)src;
295     uint32_t tempOut;  /* cannot use pointer when gcc O2 optimizer is used */
296     tempOut = SWAP4(*ip);
297 
298     *(float *)dst = *(float *)(&tempOut);
299 #endif
300 
301     /* OLD implementation that results in four load and four store CPU
302        instructions
303     char *op = dst;
304     const char *ip = src;
305     op[0] = ip[3];
306     op[1] = ip[2];
307     op[2] = ip[1];
308     op[3] = ip[0];
309     */
310 
311 }
312 # endif /* !vax */
313 
314 inline static void
swapn4b(void * dst,const void * src,size_t nn)315 swapn4b(void *dst, const void *src, size_t nn)
316 {
317     int i;
318     uint32_t *op = (uint32_t*) dst;
319     uint32_t *ip = (uint32_t*) src;
320     for (i=0; i<nn; i++) {
321         /* copy over, make the below swap in-place */
322         op[i] = ip[i];
323         op[i] = SWAP4(op[i]);
324     }
325 
326 #if 0
327 	char *op = dst;
328 	const char *ip = src;
329 
330 /* unroll the following to reduce loop overhead
331  *	while (nn-- > 0)
332  *	{
333  *		op[0] = ip[3];
334  *		op[1] = ip[2];
335  *		op[2] = ip[1];
336  *		op[3] = ip[0];
337  *		op += 4;
338  *		ip += 4;
339  *	}
340  */
341 	while (nn > 3)
342 	{
343 		op[0] = ip[3];
344 		op[1] = ip[2];
345 		op[2] = ip[1];
346 		op[3] = ip[0];
347 		op[4] = ip[7];
348 		op[5] = ip[6];
349 		op[6] = ip[5];
350 		op[7] = ip[4];
351 		op[8] = ip[11];
352 		op[9] = ip[10];
353 		op[10] = ip[9];
354 		op[11] = ip[8];
355 		op[12] = ip[15];
356 		op[13] = ip[14];
357 		op[14] = ip[13];
358 		op[15] = ip[12];
359 		op += 16;
360 		ip += 16;
361 		nn -= 4;
362 	}
363 	while (nn-- > 0)
364 	{
365 		op[0] = ip[3];
366 		op[1] = ip[2];
367 		op[2] = ip[1];
368 		op[3] = ip[0];
369 		op += 4;
370 		ip += 4;
371 	}
372 #endif
373 }
374 
375 # ifndef vax
376 inline static void
swap8b(void * dst,const void * src)377 swap8b(void *dst, const void *src)
378 {
379 #ifdef FLOAT_WORDS_BIGENDIAN
380     /* copy over, make the below swap in-place */
381     *(uint64_t*)dst = *(uint64_t*)src;
382 
383     uint32_t *op = (uint32_t*)dst;
384     *op = SWAP4(*op);
385     op = (uint32_t*)((char*)dst+4);
386     *op = SWAP4(*op);
387 #else
388     uint64_t *op = (uint64_t*)dst;
389     /* copy over, make the below swap in-place */
390     *op = *(uint64_t*)src;
391     *op = SWAP8(*op);
392 #endif
393 
394 #if 0
395 	char *op = dst;
396 	const char *ip = src;
397 #  ifndef FLOAT_WORDS_BIGENDIAN
398 	op[0] = ip[7];
399 	op[1] = ip[6];
400 	op[2] = ip[5];
401 	op[3] = ip[4];
402 	op[4] = ip[3];
403 	op[5] = ip[2];
404 	op[6] = ip[1];
405 	op[7] = ip[0];
406 #  else
407 	op[0] = ip[3];
408 	op[1] = ip[2];
409 	op[2] = ip[1];
410 	op[3] = ip[0];
411 	op[4] = ip[7];
412 	op[5] = ip[6];
413 	op[6] = ip[5];
414 	op[7] = ip[4];
415 #endif
416 #endif
417 }
418 # endif /* !vax */
419 
420 # ifndef vax
421 inline static void
swapn8b(void * dst,const void * src,size_t nn)422 swapn8b(void *dst, const void *src, size_t nn)
423 {
424 #ifdef FLOAT_WORDS_BIGENDIAN
425     int i;
426     uint64_t *dst_p = (uint64_t*) dst;
427     uint64_t *src_p = (uint64_t*) src;
428     for (i=0; i<nn; i++) {
429         /* copy over, make the below swap in-place */
430         dst_p[i] = src_p[i];
431         uint32_t *op = (uint32_t*)(&dst_p[i]);
432         *op = SWAP4(*op);
433         op = (uint32_t*)((char*)op+4);
434         *op = SWAP4(*op);
435     }
436 #else
437     int i;
438     uint64_t *op = (uint64_t*) dst;
439     uint64_t *ip = (uint64_t*) src;
440     for (i=0; i<nn; i++) {
441         /* copy over, make the below swap in-place */
442         op[i] = ip[i];
443         op[i] = SWAP8(op[i]);
444     }
445 #endif
446 
447 #if 0
448 	char *op = dst;
449 	const char *ip = src;
450 
451 /* unroll the following to reduce loop overhead
452  *	while (nn-- > 0)
453  *	{
454  *		op[0] = ip[7];
455  *		op[1] = ip[6];
456  *		op[2] = ip[5];
457  *		op[3] = ip[4];
458  *		op[4] = ip[3];
459  *		op[5] = ip[2];
460  *		op[6] = ip[1];
461  *		op[7] = ip[0];
462  *		op += 8;
463  *		ip += 8;
464  *	}
465  */
466 #  ifndef FLOAT_WORDS_BIGENDIAN
467 	while (nn > 1)
468 	{
469 		op[0] = ip[7];
470 		op[1] = ip[6];
471 		op[2] = ip[5];
472 		op[3] = ip[4];
473 		op[4] = ip[3];
474 		op[5] = ip[2];
475 		op[6] = ip[1];
476 		op[7] = ip[0];
477 		op[8] = ip[15];
478 		op[9] = ip[14];
479 		op[10] = ip[13];
480 		op[11] = ip[12];
481 		op[12] = ip[11];
482 		op[13] = ip[10];
483 		op[14] = ip[9];
484 		op[15] = ip[8];
485 		op += 16;
486 		ip += 16;
487 		nn -= 2;
488 	}
489 	while (nn-- > 0)
490 	{
491 		op[0] = ip[7];
492 		op[1] = ip[6];
493 		op[2] = ip[5];
494 		op[3] = ip[4];
495 		op[4] = ip[3];
496 		op[5] = ip[2];
497 		op[6] = ip[1];
498 		op[7] = ip[0];
499 		op += 8;
500 		ip += 8;
501 	}
502 #  else
503 	while (nn-- > 0)
504 	{
505 		op[0] = ip[3];
506 		op[1] = ip[2];
507 		op[2] = ip[1];
508 		op[3] = ip[0];
509 		op[4] = ip[7];
510 		op[5] = ip[6];
511 		op[6] = ip[5];
512 		op[7] = ip[4];
513 		op += 8;
514 		ip += 8;
515 	}
516 #endif
517 #endif
518 }
519 # endif /* !vax */
520 
521 #endif /* LITTLE_ENDIAN */
522 
523 
524 
525 
526 
527 
528 /*
529  * Primitive numeric conversion functions.
530  */
531 
532 
533 
534 
535 
536 /* x_schar */
537 /* x_uchar */
538 
539 /* We don't implement any x_schar and x_uchar primitives. */
540 
541 
542 /* external NC_SHORT --------------------------------------------------------*/
543 
544 #if SHORT_MAX == X_SHORT_MAX
545 typedef short ix_short;
546 #define SIZEOF_IX_SHORT SIZEOF_SHORT
547 #define IX_SHORT_MAX SHORT_MAX
548 #elif INT_MAX >= X_SHORT_MAX
549 typedef int ix_short;
550 #define SIZEOF_IX_SHORT SIZEOF_INT
551 #define IX_SHORT_MAX INT_MAX
552 #elif LONG_MAX >= X_SHORT_MAX
553 typedef long ix_short;
554 #define SIZEOF_IX_SHORT SIZEOF_LONG
555 #define IX_SHORT_MAX LONG_MAX
556 #elif LLONG_MAX >= X_SHORT_MAX
557 typedef long long ix_short;
558 #define SIZEOF_IX_SHORT SIZEOF_LONGLONG
559 #define IX_SHORT_MAX LLONG_MAX
560 #else
561 #error "ix_short implementation"
562 #endif
563 
564 static void
get_ix_short(const void * xp,ix_short * ip)565 get_ix_short(const void *xp, ix_short *ip)
566 {
567 	const uchar *cp = (const uchar *) xp;
568 	*ip = (ix_short)(*cp++ << 8);
569 #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
570 	if (*ip & 0x8000)
571 	{
572 		/* extern is negative */
573 		*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
574 	}
575 #endif
576 	*ip = (ix_short)(*ip | *cp);
577 }
578 
579 static void
put_ix_short(void * xp,const ix_short * ip)580 put_ix_short(void *xp, const ix_short *ip)
581 {
582 	uchar *cp = (uchar *) xp;
583 	*cp++ = (uchar)((*ip) >> 8);
584 	*cp   = (uchar)((*ip) & 0xff);
585 }
586 
587 static int
ncx_get_short_schar(const void * xp,schar * ip)588 ncx_get_short_schar(const void *xp, schar *ip)
589 {
590     int err=NC_NOERR;
591     ix_short xx;
592     get_ix_short(xp, &xx);
593 
594 #if IX_SHORT_MAX > SCHAR_MAX
595     if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
596 #ifdef ERANGE_FILL
597         *ip = NC_FILL_BYTE;
598         return NC_ERANGE;
599 #else
600         err = NC_ERANGE;
601 #endif
602     }
603 #endif
604 
605 
606     *ip = (schar) xx;
607     return err;
608 }
609 
610 static int
ncx_get_short_short(const void * xp,short * ip)611 ncx_get_short_short(const void *xp, short *ip)
612 {
613     int err=NC_NOERR;
614 #if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
615     get_ix_short(xp, (ix_short *)ip);
616 #else
617     ix_short xx;
618     get_ix_short(xp, &xx);
619 
620 #if IX_SHORT_MAX > SHORT_MAX
621     if (xx > SHORT_MAX || xx < SHORT_MIN) {
622 #ifdef ERANGE_FILL
623         *ip = NC_FILL_SHORT;
624         return NC_ERANGE;
625 #else
626         err = NC_ERANGE;
627 #endif
628     }
629 #endif
630 
631 
632     *ip = (short) xx;
633 #endif
634     return err;
635 }
636 
637 static int
ncx_get_short_int(const void * xp,int * ip)638 ncx_get_short_int(const void *xp, int *ip)
639 {
640     int err=NC_NOERR;
641 #if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
642     get_ix_short(xp, (ix_short *)ip);
643 #else
644     ix_short xx;
645     get_ix_short(xp, &xx);
646 
647 #if IX_SHORT_MAX > INT_MAX
648     if (xx > INT_MAX || xx < INT_MIN) {
649 #ifdef ERANGE_FILL
650         *ip = NC_FILL_INT;
651         return NC_ERANGE;
652 #else
653         err = NC_ERANGE;
654 #endif
655     }
656 #endif
657 
658 
659     *ip = (int) xx;
660 #endif
661     return err;
662 }
663 
664 static int
ncx_get_short_long(const void * xp,long * ip)665 ncx_get_short_long(const void *xp, long *ip)
666 {
667     int err=NC_NOERR;
668 #if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
669     get_ix_short(xp, (ix_short *)ip);
670 #else
671     ix_short xx;
672     get_ix_short(xp, &xx);
673 
674 #if IX_SHORT_MAX > LONG_MAX
675     if (xx > LONG_MAX || xx < LONG_MIN) {
676 #ifdef ERANGE_FILL
677         *ip = NC_FILL_INT;
678         return NC_ERANGE;
679 #else
680         err = NC_ERANGE;
681 #endif
682     }
683 #endif
684 
685 
686     *ip = (long) xx;
687 #endif
688     return err;
689 }
690 
691 static int
ncx_get_short_longlong(const void * xp,longlong * ip)692 ncx_get_short_longlong(const void *xp, longlong *ip)
693 {
694     int err=NC_NOERR;
695 #if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
696     get_ix_short(xp, (ix_short *)ip);
697 #else
698     ix_short xx;
699     get_ix_short(xp, &xx);
700 
701 #if IX_SHORT_MAX > LONGLONG_MAX
702     if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
703 #ifdef ERANGE_FILL
704         *ip = NC_FILL_INT64;
705         return NC_ERANGE;
706 #else
707         err = NC_ERANGE;
708 #endif
709     }
710 #endif
711 
712 
713     *ip = (longlong) xx;
714 #endif
715     return err;
716 }
717 
718 static int
ncx_get_short_ushort(const void * xp,ushort * ip)719 ncx_get_short_ushort(const void *xp, ushort *ip)
720 {
721     int err=NC_NOERR;
722     ix_short xx;
723     get_ix_short(xp, &xx);
724 
725 #if IX_SHORT_MAX > USHORT_MAX
726     if (xx > USHORT_MAX) {
727 #ifdef ERANGE_FILL
728         *ip = NC_FILL_USHORT;
729         return NC_ERANGE;
730 #else
731         err = NC_ERANGE;
732 #endif
733     }
734 #endif
735 
736     if (xx < 0) {
737 #ifdef ERANGE_FILL
738         *ip = NC_FILL_USHORT;
739         return NC_ERANGE;
740 #else
741         err = NC_ERANGE; /* because ip is unsigned */
742 #endif
743     }
744     *ip = (ushort) xx;
745     return err;
746 }
747 
748 static int
ncx_get_short_uchar(const void * xp,uchar * ip)749 ncx_get_short_uchar(const void *xp, uchar *ip)
750 {
751     int err=NC_NOERR;
752     ix_short xx;
753     get_ix_short(xp, &xx);
754 
755 #if IX_SHORT_MAX > UCHAR_MAX
756     if (xx > UCHAR_MAX) {
757 #ifdef ERANGE_FILL
758         *ip = NC_FILL_UBYTE;
759         return NC_ERANGE;
760 #else
761         err = NC_ERANGE;
762 #endif
763     }
764 #endif
765 
766     if (xx < 0) {
767 #ifdef ERANGE_FILL
768         *ip = NC_FILL_UBYTE;
769         return NC_ERANGE;
770 #else
771         err = NC_ERANGE; /* because ip is unsigned */
772 #endif
773     }
774     *ip = (uchar) xx;
775     return err;
776 }
777 
778 static int
ncx_get_short_uint(const void * xp,uint * ip)779 ncx_get_short_uint(const void *xp, uint *ip)
780 {
781     int err=NC_NOERR;
782     ix_short xx;
783     get_ix_short(xp, &xx);
784 
785 #if IX_SHORT_MAX > UINT_MAX
786     if (xx > UINT_MAX) {
787 #ifdef ERANGE_FILL
788         *ip = NC_FILL_UINT;
789         return NC_ERANGE;
790 #else
791         err = NC_ERANGE;
792 #endif
793     }
794 #endif
795 
796     if (xx < 0) {
797 #ifdef ERANGE_FILL
798         *ip = NC_FILL_UINT;
799         return NC_ERANGE;
800 #else
801         err = NC_ERANGE; /* because ip is unsigned */
802 #endif
803     }
804     *ip = (uint) xx;
805     return err;
806 }
807 
808 static int
ncx_get_short_ulonglong(const void * xp,ulonglong * ip)809 ncx_get_short_ulonglong(const void *xp, ulonglong *ip)
810 {
811     int err=NC_NOERR;
812     ix_short xx;
813     get_ix_short(xp, &xx);
814 
815 #if IX_SHORT_MAX > ULONGLONG_MAX
816     if (xx > ULONGLONG_MAX) {
817 #ifdef ERANGE_FILL
818         *ip = NC_FILL_UINT64;
819         return NC_ERANGE;
820 #else
821         err = NC_ERANGE;
822 #endif
823     }
824 #endif
825 
826     if (xx < 0) {
827 #ifdef ERANGE_FILL
828         *ip = NC_FILL_UINT64;
829         return NC_ERANGE;
830 #else
831         err = NC_ERANGE; /* because ip is unsigned */
832 #endif
833     }
834     *ip = (ulonglong) xx;
835     return err;
836 }
837 
838 static int
ncx_get_short_float(const void * xp,float * ip)839 ncx_get_short_float(const void *xp, float *ip)
840 {
841 	ix_short xx;
842 	get_ix_short(xp, &xx);
843 	*ip = (float)xx;
844 	return NC_NOERR;
845 }
846 
847 static int
ncx_get_short_double(const void * xp,double * ip)848 ncx_get_short_double(const void *xp, double *ip)
849 {
850 	ix_short xx;
851 	get_ix_short(xp, &xx);
852 	*ip = (double)xx;
853 	return NC_NOERR;
854 }
855 
856 
857 static int
ncx_put_short_schar(void * xp,const schar * ip,void * fillp)858 ncx_put_short_schar(void *xp, const schar *ip, void *fillp)
859 {
860 	uchar *cp = (uchar *) xp;
861 	if (*ip & 0x80)
862 		*cp++ = 0xff;
863 	else
864 		*cp++ = 0;
865 	*cp = (uchar)*ip;
866 	return NC_NOERR;
867 }
868 
869 static int
ncx_put_short_uchar(void * xp,const uchar * ip,void * fillp)870 ncx_put_short_uchar(void *xp, const uchar *ip, void *fillp)
871 {
872 	uchar *cp = (uchar *) xp;
873 	*cp++ = 0;
874 	*cp = *ip;
875 	return NC_NOERR;
876 }
877 
878 static int
ncx_put_short_short(void * xp,const short * ip,void * fillp)879 ncx_put_short_short(void *xp, const short *ip, void *fillp)
880 {
881     int err=NC_NOERR;
882 #if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
883     put_ix_short(xp, (const ix_short *)ip);
884 #else
885     ix_short xx = NC_FILL_SHORT;
886 
887 #if IX_SHORT_MAX < SHORT_MAX
888     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
889 
890 #ifdef ERANGE_FILL
891             if (fillp != NULL) memcpy(&xx, fillp, 2);
892 #endif
893         err = NC_ERANGE;
894     }
895 #ifdef ERANGE_FILL
896     else
897 #endif
898 #endif
899         xx = (ix_short)*ip;
900 
901     put_ix_short(xp, &xx);
902 #endif
903     return err;
904 }
905 
906 static int
ncx_put_short_int(void * xp,const int * ip,void * fillp)907 ncx_put_short_int(void *xp, const int *ip, void *fillp)
908 {
909     int err=NC_NOERR;
910 #if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
911     put_ix_short(xp, (const ix_short *)ip);
912 #else
913     ix_short xx = NC_FILL_SHORT;
914 
915 #if IX_SHORT_MAX < INT_MAX
916     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
917 
918 #ifdef ERANGE_FILL
919             if (fillp != NULL) memcpy(&xx, fillp, 2);
920 #endif
921         err = NC_ERANGE;
922     }
923 #ifdef ERANGE_FILL
924     else
925 #endif
926 #endif
927         xx = (ix_short)*ip;
928 
929     put_ix_short(xp, &xx);
930 #endif
931     return err;
932 }
933 
934 static int
ncx_put_short_long(void * xp,const long * ip,void * fillp)935 ncx_put_short_long(void *xp, const long *ip, void *fillp)
936 {
937     int err=NC_NOERR;
938 #if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
939     put_ix_short(xp, (const ix_short *)ip);
940 #else
941     ix_short xx = NC_FILL_SHORT;
942 
943 #if IX_SHORT_MAX < LONG_MAX
944     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
945 
946 #ifdef ERANGE_FILL
947             if (fillp != NULL) memcpy(&xx, fillp, 2);
948 #endif
949         err = NC_ERANGE;
950     }
951 #ifdef ERANGE_FILL
952     else
953 #endif
954 #endif
955         xx = (ix_short)*ip;
956 
957     put_ix_short(xp, &xx);
958 #endif
959     return err;
960 }
961 
962 static int
ncx_put_short_longlong(void * xp,const longlong * ip,void * fillp)963 ncx_put_short_longlong(void *xp, const longlong *ip, void *fillp)
964 {
965     int err=NC_NOERR;
966 #if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
967     put_ix_short(xp, (const ix_short *)ip);
968 #else
969     ix_short xx = NC_FILL_SHORT;
970 
971 #if IX_SHORT_MAX < LONGLONG_MAX
972     if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
973 
974 #ifdef ERANGE_FILL
975             if (fillp != NULL) memcpy(&xx, fillp, 2);
976 #endif
977         err = NC_ERANGE;
978     }
979 #ifdef ERANGE_FILL
980     else
981 #endif
982 #endif
983         xx = (ix_short)*ip;
984 
985     put_ix_short(xp, &xx);
986 #endif
987     return err;
988 }
989 
990 static int
ncx_put_short_ushort(void * xp,const ushort * ip,void * fillp)991 ncx_put_short_ushort(void *xp, const ushort *ip, void *fillp)
992 {
993     int err=NC_NOERR;
994     ix_short xx = NC_FILL_SHORT;
995 
996 #if IX_SHORT_MAX < USHORT_MAX
997     if (*ip > IX_SHORT_MAX) {
998 
999 #ifdef ERANGE_FILL
1000             if (fillp != NULL) memcpy(&xx, fillp, 2);
1001 #endif
1002         err = NC_ERANGE;
1003     }
1004 #ifdef ERANGE_FILL
1005     else
1006 #endif
1007 #endif
1008         xx = (ix_short)*ip;
1009 
1010     put_ix_short(xp, &xx);
1011     return err;
1012 }
1013 
1014 static int
ncx_put_short_uint(void * xp,const uint * ip,void * fillp)1015 ncx_put_short_uint(void *xp, const uint *ip, void *fillp)
1016 {
1017     int err=NC_NOERR;
1018     ix_short xx = NC_FILL_SHORT;
1019 
1020 #if IX_SHORT_MAX < UINT_MAX
1021     if (*ip > IX_SHORT_MAX) {
1022 
1023 #ifdef ERANGE_FILL
1024             if (fillp != NULL) memcpy(&xx, fillp, 2);
1025 #endif
1026         err = NC_ERANGE;
1027     }
1028 #ifdef ERANGE_FILL
1029     else
1030 #endif
1031 #endif
1032         xx = (ix_short)*ip;
1033 
1034     put_ix_short(xp, &xx);
1035     return err;
1036 }
1037 
1038 static int
ncx_put_short_ulonglong(void * xp,const ulonglong * ip,void * fillp)1039 ncx_put_short_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1040 {
1041     int err=NC_NOERR;
1042     ix_short xx = NC_FILL_SHORT;
1043 
1044 #if IX_SHORT_MAX < ULONGLONG_MAX
1045     if (*ip > IX_SHORT_MAX) {
1046 
1047 #ifdef ERANGE_FILL
1048             if (fillp != NULL) memcpy(&xx, fillp, 2);
1049 #endif
1050         err = NC_ERANGE;
1051     }
1052 #ifdef ERANGE_FILL
1053     else
1054 #endif
1055 #endif
1056         xx = (ix_short)*ip;
1057 
1058     put_ix_short(xp, &xx);
1059     return err;
1060 }
1061 
1062 static int
ncx_put_short_float(void * xp,const float * ip,void * fillp)1063 ncx_put_short_float(void *xp, const float *ip, void *fillp)
1064 {
1065     int err=NC_NOERR;
1066     ix_short xx = NC_FILL_SHORT;
1067 
1068     if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
1069 
1070 #ifdef ERANGE_FILL
1071             if (fillp != NULL) memcpy(&xx, fillp, 2);
1072 #endif
1073         err = NC_ERANGE;
1074     }
1075 #ifdef ERANGE_FILL
1076     else
1077 #endif
1078         xx = (ix_short)*ip;
1079 
1080     put_ix_short(xp, &xx);
1081     return err;
1082 }
1083 
1084 static int
ncx_put_short_double(void * xp,const double * ip,void * fillp)1085 ncx_put_short_double(void *xp, const double *ip, void *fillp)
1086 {
1087     int err=NC_NOERR;
1088     ix_short xx = NC_FILL_SHORT;
1089 
1090     if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) {
1091 
1092 #ifdef ERANGE_FILL
1093             if (fillp != NULL) memcpy(&xx, fillp, 2);
1094 #endif
1095         err = NC_ERANGE;
1096     }
1097 #ifdef ERANGE_FILL
1098     else
1099 #endif
1100         xx = (ix_short)*ip;
1101 
1102     put_ix_short(xp, &xx);
1103     return err;
1104 }
1105 
1106 
1107 /* external NC_USHORT -------------------------------------------------------*/
1108 
1109 #if USHORT_MAX == X_USHORT_MAX
1110 typedef unsigned short ix_ushort;
1111 #define SIZEOF_IX_USHORT SIZEOF_USHORT
1112 #define IX_USHORT_MAX USHORT_MAX
1113 #elif UINT_MAX >= X_USHORT_MAX
1114 typedef unsigned int ix_ushort;
1115 #define SIZEOF_IX_USHORT SIZEOF_UINT
1116 #define IX_USHORT_MAX UINT_MAX
1117 #elif ULONG_MAX >= X_USHORT_MAX
1118 typedef unsigned long ix_ushort;
1119 #define SIZEOF_IX_USHORT SIZEOF_ULONG
1120 #define IX_USHORT_MAX ULONG_MAX
1121 #elif ULLONG_MAX >= X_USHORT_MAX
1122 typedef unsigned long long ix_ushort;
1123 #define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
1124 #define IX_USHORT_MAX ULLONG_MAX
1125 #else
1126 #error "ix_ushort implementation"
1127 #endif
1128 
1129 static void
get_ix_ushort(const void * xp,ix_ushort * ip)1130 get_ix_ushort(const void *xp, ix_ushort *ip)
1131 {
1132 	const uchar *cp = (const uchar *) xp;
1133 	*ip = (ix_ushort)(*cp++ << 8);
1134 #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
1135 	if (*ip & 0x8000)
1136 	{
1137 		/* extern is negative */
1138 		*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
1139 	}
1140 #endif
1141 	*ip = (ix_ushort)(*ip | *cp);
1142 }
1143 
1144 static void
put_ix_ushort(void * xp,const ix_ushort * ip)1145 put_ix_ushort(void *xp, const ix_ushort *ip)
1146 {
1147 	uchar *cp = (uchar *) xp;
1148 	*cp++ = (uchar)((*ip) >> 8);
1149 	*cp   = (uchar)((*ip) & 0xff);
1150 }
1151 
1152 static int
ncx_get_ushort_schar(const void * xp,schar * ip)1153 ncx_get_ushort_schar(const void *xp, schar *ip)
1154 {
1155     int err=NC_NOERR;
1156     ix_ushort xx;
1157     get_ix_ushort(xp, &xx);
1158 
1159 #if IX_USHORT_MAX > SCHAR_MAX
1160     if (xx > SCHAR_MAX) {
1161 #ifdef ERANGE_FILL
1162         *ip = NC_FILL_BYTE;
1163         return NC_ERANGE;
1164 #else
1165         err = NC_ERANGE;
1166 #endif
1167     }
1168 #endif
1169 
1170 
1171     *ip = (schar) xx;
1172     return err;
1173 }
1174 
1175 static int
ncx_get_ushort_short(const void * xp,short * ip)1176 ncx_get_ushort_short(const void *xp, short *ip)
1177 {
1178     int err=NC_NOERR;
1179     ix_ushort xx;
1180     get_ix_ushort(xp, &xx);
1181 
1182 #if IX_USHORT_MAX > SHORT_MAX
1183     if (xx > SHORT_MAX) {
1184 #ifdef ERANGE_FILL
1185         *ip = NC_FILL_SHORT;
1186         return NC_ERANGE;
1187 #else
1188         err = NC_ERANGE;
1189 #endif
1190     }
1191 #endif
1192 
1193 
1194     *ip = (short) xx;
1195     return err;
1196 }
1197 
1198 static int
ncx_get_ushort_int(const void * xp,int * ip)1199 ncx_get_ushort_int(const void *xp, int *ip)
1200 {
1201     int err=NC_NOERR;
1202     ix_ushort xx;
1203     get_ix_ushort(xp, &xx);
1204 
1205 #if IX_USHORT_MAX > INT_MAX
1206     if (xx > INT_MAX) {
1207 #ifdef ERANGE_FILL
1208         *ip = NC_FILL_INT;
1209         return NC_ERANGE;
1210 #else
1211         err = NC_ERANGE;
1212 #endif
1213     }
1214 #endif
1215 
1216 
1217     *ip = (int) xx;
1218     return err;
1219 }
1220 
1221 static int
ncx_get_ushort_long(const void * xp,long * ip)1222 ncx_get_ushort_long(const void *xp, long *ip)
1223 {
1224     int err=NC_NOERR;
1225     ix_ushort xx;
1226     get_ix_ushort(xp, &xx);
1227 
1228 #if IX_USHORT_MAX > LONG_MAX
1229     if (xx > LONG_MAX) {
1230 #ifdef ERANGE_FILL
1231         *ip = NC_FILL_INT;
1232         return NC_ERANGE;
1233 #else
1234         err = NC_ERANGE;
1235 #endif
1236     }
1237 #endif
1238 
1239 
1240     *ip = (long) xx;
1241     return err;
1242 }
1243 
1244 static int
ncx_get_ushort_longlong(const void * xp,longlong * ip)1245 ncx_get_ushort_longlong(const void *xp, longlong *ip)
1246 {
1247     int err=NC_NOERR;
1248     ix_ushort xx;
1249     get_ix_ushort(xp, &xx);
1250 
1251 #if IX_USHORT_MAX > LONGLONG_MAX
1252     if (xx > LONGLONG_MAX) {
1253 #ifdef ERANGE_FILL
1254         *ip = NC_FILL_INT64;
1255         return NC_ERANGE;
1256 #else
1257         err = NC_ERANGE;
1258 #endif
1259     }
1260 #endif
1261 
1262 
1263     *ip = (longlong) xx;
1264     return err;
1265 }
1266 
1267 static int
ncx_get_ushort_ushort(const void * xp,ushort * ip)1268 ncx_get_ushort_ushort(const void *xp, ushort *ip)
1269 {
1270     int err=NC_NOERR;
1271 #if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1272     get_ix_ushort(xp, (ix_ushort *)ip);
1273 #else
1274     ix_ushort xx;
1275     get_ix_ushort(xp, &xx);
1276 
1277 #if IX_USHORT_MAX > USHORT_MAX
1278     if (xx > USHORT_MAX) {
1279 #ifdef ERANGE_FILL
1280         *ip = NC_FILL_USHORT;
1281         return NC_ERANGE;
1282 #else
1283         err = NC_ERANGE;
1284 #endif
1285     }
1286 #endif
1287 
1288 
1289     *ip = (ushort) xx;
1290 #endif
1291     return err;
1292 }
1293 
1294 static int
ncx_get_ushort_uchar(const void * xp,uchar * ip)1295 ncx_get_ushort_uchar(const void *xp, uchar *ip)
1296 {
1297     int err=NC_NOERR;
1298 #if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
1299     get_ix_ushort(xp, (ix_ushort *)ip);
1300 #else
1301     ix_ushort xx;
1302     get_ix_ushort(xp, &xx);
1303 
1304 #if IX_USHORT_MAX > UCHAR_MAX
1305     if (xx > UCHAR_MAX) {
1306 #ifdef ERANGE_FILL
1307         *ip = NC_FILL_UBYTE;
1308         return NC_ERANGE;
1309 #else
1310         err = NC_ERANGE;
1311 #endif
1312     }
1313 #endif
1314 
1315 
1316     *ip = (uchar) xx;
1317 #endif
1318     return err;
1319 }
1320 
1321 static int
ncx_get_ushort_uint(const void * xp,uint * ip)1322 ncx_get_ushort_uint(const void *xp, uint *ip)
1323 {
1324     int err=NC_NOERR;
1325 #if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1326     get_ix_ushort(xp, (ix_ushort *)ip);
1327 #else
1328     ix_ushort xx;
1329     get_ix_ushort(xp, &xx);
1330 
1331 #if IX_USHORT_MAX > UINT_MAX
1332     if (xx > UINT_MAX) {
1333 #ifdef ERANGE_FILL
1334         *ip = NC_FILL_UINT;
1335         return NC_ERANGE;
1336 #else
1337         err = NC_ERANGE;
1338 #endif
1339     }
1340 #endif
1341 
1342 
1343     *ip = (uint) xx;
1344 #endif
1345     return err;
1346 }
1347 
1348 static int
ncx_get_ushort_ulonglong(const void * xp,ulonglong * ip)1349 ncx_get_ushort_ulonglong(const void *xp, ulonglong *ip)
1350 {
1351     int err=NC_NOERR;
1352 #if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1353     get_ix_ushort(xp, (ix_ushort *)ip);
1354 #else
1355     ix_ushort xx;
1356     get_ix_ushort(xp, &xx);
1357 
1358 #if IX_USHORT_MAX > ULONGLONG_MAX
1359     if (xx > ULONGLONG_MAX) {
1360 #ifdef ERANGE_FILL
1361         *ip = NC_FILL_UINT64;
1362         return NC_ERANGE;
1363 #else
1364         err = NC_ERANGE;
1365 #endif
1366     }
1367 #endif
1368 
1369 
1370     *ip = (ulonglong) xx;
1371 #endif
1372     return err;
1373 }
1374 
1375 static int
ncx_get_ushort_float(const void * xp,float * ip)1376 ncx_get_ushort_float(const void *xp, float *ip)
1377 {
1378 	ix_ushort xx;
1379 	get_ix_ushort(xp, &xx);
1380 	*ip = (float)xx;
1381 	return NC_NOERR;
1382 }
1383 
1384 static int
ncx_get_ushort_double(const void * xp,double * ip)1385 ncx_get_ushort_double(const void *xp, double *ip)
1386 {
1387 	ix_ushort xx;
1388 	get_ix_ushort(xp, &xx);
1389 	*ip = (double)xx;
1390 	return NC_NOERR;
1391 }
1392 
1393 
1394 static int
ncx_put_ushort_schar(void * xp,const schar * ip,void * fillp)1395 ncx_put_ushort_schar(void *xp, const schar *ip, void *fillp)
1396 {
1397     int err=NC_NOERR;
1398     uchar *cp;
1399     if (*ip < 0) {
1400 #ifdef ERANGE_FILL
1401         if (fillp != NULL) memcpy(xp, fillp, 2);
1402 #ifndef WORDS_BIGENDIAN
1403         swapn2b(xp, xp, 1);
1404 #endif
1405         return NC_ERANGE;
1406 #else
1407         err = NC_ERANGE;
1408 #endif
1409     }
1410 
1411     cp = (uchar *) xp;
1412     if (*ip & 0x80)
1413         *cp++ = 0xff;
1414     else
1415         *cp++ = 0;
1416     *cp = (uchar)*ip;
1417 
1418     return err;
1419 }
1420 
1421 static int
ncx_put_ushort_uchar(void * xp,const uchar * ip,void * fillp)1422 ncx_put_ushort_uchar(void *xp, const uchar *ip, void *fillp)
1423 {
1424 	uchar *cp = (uchar *) xp;
1425 	*cp++ = 0;
1426 	*cp = *ip;
1427 	return NC_NOERR;
1428 }
1429 
1430 static int
ncx_put_ushort_short(void * xp,const short * ip,void * fillp)1431 ncx_put_ushort_short(void *xp, const short *ip, void *fillp)
1432 {
1433     int err=NC_NOERR;
1434     ix_ushort xx = NC_FILL_USHORT;
1435 
1436 #if IX_USHORT_MAX < SHORT_MAX
1437     if (*ip > IX_USHORT_MAX) {
1438 
1439 #ifdef ERANGE_FILL
1440             if (fillp != NULL) memcpy(&xx, fillp, 2);
1441 #endif
1442         err = NC_ERANGE;
1443     }
1444 #ifdef ERANGE_FILL
1445     else
1446 #endif
1447 #endif
1448     if (*ip < 0) {
1449 
1450 #ifdef ERANGE_FILL
1451             if (fillp != NULL) memcpy(&xx, fillp, 2);
1452 #endif
1453         err = NC_ERANGE; /* because xp is unsigned */
1454     }
1455 #ifdef ERANGE_FILL
1456     else
1457 #endif
1458         xx = (ix_ushort)*ip;
1459 
1460     put_ix_ushort(xp, &xx);
1461     return err;
1462 }
1463 
1464 static int
ncx_put_ushort_int(void * xp,const int * ip,void * fillp)1465 ncx_put_ushort_int(void *xp, const int *ip, void *fillp)
1466 {
1467     int err=NC_NOERR;
1468     ix_ushort xx = NC_FILL_USHORT;
1469 
1470 #if IX_USHORT_MAX < INT_MAX
1471     if (*ip > IX_USHORT_MAX) {
1472 
1473 #ifdef ERANGE_FILL
1474             if (fillp != NULL) memcpy(&xx, fillp, 2);
1475 #endif
1476         err = NC_ERANGE;
1477     }
1478 #ifdef ERANGE_FILL
1479     else
1480 #endif
1481 #endif
1482     if (*ip < 0) {
1483 
1484 #ifdef ERANGE_FILL
1485             if (fillp != NULL) memcpy(&xx, fillp, 2);
1486 #endif
1487         err = NC_ERANGE; /* because xp is unsigned */
1488     }
1489 #ifdef ERANGE_FILL
1490     else
1491 #endif
1492         xx = (ix_ushort)*ip;
1493 
1494     put_ix_ushort(xp, &xx);
1495     return err;
1496 }
1497 
1498 static int
ncx_put_ushort_long(void * xp,const long * ip,void * fillp)1499 ncx_put_ushort_long(void *xp, const long *ip, void *fillp)
1500 {
1501     int err=NC_NOERR;
1502     ix_ushort xx = NC_FILL_USHORT;
1503 
1504 #if IX_USHORT_MAX < LONG_MAX
1505     if (*ip > IX_USHORT_MAX) {
1506 
1507 #ifdef ERANGE_FILL
1508             if (fillp != NULL) memcpy(&xx, fillp, 2);
1509 #endif
1510         err = NC_ERANGE;
1511     }
1512 #ifdef ERANGE_FILL
1513     else
1514 #endif
1515 #endif
1516     if (*ip < 0) {
1517 
1518 #ifdef ERANGE_FILL
1519             if (fillp != NULL) memcpy(&xx, fillp, 2);
1520 #endif
1521         err = NC_ERANGE; /* because xp is unsigned */
1522     }
1523 #ifdef ERANGE_FILL
1524     else
1525 #endif
1526         xx = (ix_ushort)*ip;
1527 
1528     put_ix_ushort(xp, &xx);
1529     return err;
1530 }
1531 
1532 static int
ncx_put_ushort_longlong(void * xp,const longlong * ip,void * fillp)1533 ncx_put_ushort_longlong(void *xp, const longlong *ip, void *fillp)
1534 {
1535     int err=NC_NOERR;
1536     ix_ushort xx = NC_FILL_USHORT;
1537 
1538 #if IX_USHORT_MAX < LONGLONG_MAX
1539     if (*ip > IX_USHORT_MAX) {
1540 
1541 #ifdef ERANGE_FILL
1542             if (fillp != NULL) memcpy(&xx, fillp, 2);
1543 #endif
1544         err = NC_ERANGE;
1545     }
1546 #ifdef ERANGE_FILL
1547     else
1548 #endif
1549 #endif
1550     if (*ip < 0) {
1551 
1552 #ifdef ERANGE_FILL
1553             if (fillp != NULL) memcpy(&xx, fillp, 2);
1554 #endif
1555         err = NC_ERANGE; /* because xp is unsigned */
1556     }
1557 #ifdef ERANGE_FILL
1558     else
1559 #endif
1560         xx = (ix_ushort)*ip;
1561 
1562     put_ix_ushort(xp, &xx);
1563     return err;
1564 }
1565 
1566 static int
ncx_put_ushort_ushort(void * xp,const ushort * ip,void * fillp)1567 ncx_put_ushort_ushort(void *xp, const ushort *ip, void *fillp)
1568 {
1569     int err=NC_NOERR;
1570 #if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
1571     put_ix_ushort(xp, (const ix_ushort *)ip);
1572 #else
1573     ix_ushort xx = NC_FILL_USHORT;
1574 
1575 #if IX_USHORT_MAX < USHORT_MAX
1576     if (*ip > IX_USHORT_MAX) {
1577 
1578 #ifdef ERANGE_FILL
1579             if (fillp != NULL) memcpy(&xx, fillp, 2);
1580 #endif
1581         err = NC_ERANGE;
1582     }
1583 #ifdef ERANGE_FILL
1584     else
1585 #endif
1586 #endif
1587         xx = (ix_ushort)*ip;
1588 
1589     put_ix_ushort(xp, &xx);
1590 #endif
1591     return err;
1592 }
1593 
1594 static int
ncx_put_ushort_uint(void * xp,const uint * ip,void * fillp)1595 ncx_put_ushort_uint(void *xp, const uint *ip, void *fillp)
1596 {
1597     int err=NC_NOERR;
1598 #if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
1599     put_ix_ushort(xp, (const ix_ushort *)ip);
1600 #else
1601     ix_ushort xx = NC_FILL_USHORT;
1602 
1603 #if IX_USHORT_MAX < UINT_MAX
1604     if (*ip > IX_USHORT_MAX) {
1605 
1606 #ifdef ERANGE_FILL
1607             if (fillp != NULL) memcpy(&xx, fillp, 2);
1608 #endif
1609         err = NC_ERANGE;
1610     }
1611 #ifdef ERANGE_FILL
1612     else
1613 #endif
1614 #endif
1615         xx = (ix_ushort)*ip;
1616 
1617     put_ix_ushort(xp, &xx);
1618 #endif
1619     return err;
1620 }
1621 
1622 static int
ncx_put_ushort_ulonglong(void * xp,const ulonglong * ip,void * fillp)1623 ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip, void *fillp)
1624 {
1625     int err=NC_NOERR;
1626 #if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
1627     put_ix_ushort(xp, (const ix_ushort *)ip);
1628 #else
1629     ix_ushort xx = NC_FILL_USHORT;
1630 
1631 #if IX_USHORT_MAX < ULONGLONG_MAX
1632     if (*ip > IX_USHORT_MAX) {
1633 
1634 #ifdef ERANGE_FILL
1635             if (fillp != NULL) memcpy(&xx, fillp, 2);
1636 #endif
1637         err = NC_ERANGE;
1638     }
1639 #ifdef ERANGE_FILL
1640     else
1641 #endif
1642 #endif
1643         xx = (ix_ushort)*ip;
1644 
1645     put_ix_ushort(xp, &xx);
1646 #endif
1647     return err;
1648 }
1649 
1650 static int
ncx_put_ushort_float(void * xp,const float * ip,void * fillp)1651 ncx_put_ushort_float(void *xp, const float *ip, void *fillp)
1652 {
1653     int err=NC_NOERR;
1654     ix_ushort xx = NC_FILL_USHORT;
1655 
1656     if (*ip > (double)X_USHORT_MAX || *ip < 0) {
1657 
1658 #ifdef ERANGE_FILL
1659             if (fillp != NULL) memcpy(&xx, fillp, 2);
1660 #endif
1661         err = NC_ERANGE;
1662     }
1663 #ifdef ERANGE_FILL
1664     else
1665 #endif
1666         xx = (ix_ushort)*ip;
1667 
1668     put_ix_ushort(xp, &xx);
1669     return err;
1670 }
1671 
1672 static int
ncx_put_ushort_double(void * xp,const double * ip,void * fillp)1673 ncx_put_ushort_double(void *xp, const double *ip, void *fillp)
1674 {
1675     int err=NC_NOERR;
1676     ix_ushort xx = NC_FILL_USHORT;
1677 
1678     if (*ip > X_USHORT_MAX || *ip < 0) {
1679 
1680 #ifdef ERANGE_FILL
1681             if (fillp != NULL) memcpy(&xx, fillp, 2);
1682 #endif
1683         err = NC_ERANGE;
1684     }
1685 #ifdef ERANGE_FILL
1686     else
1687 #endif
1688         xx = (ix_ushort)*ip;
1689 
1690     put_ix_ushort(xp, &xx);
1691     return err;
1692 }
1693 
1694 
1695 /* external NC_INT ----------------------------------------------------------*/
1696 
1697 #if SHORT_MAX == X_INT_MAX
1698 typedef short ix_int;
1699 #define SIZEOF_IX_INT SIZEOF_SHORT
1700 #define IX_INT_MAX SHORT_MAX
1701 #elif INT_MAX  >= X_INT_MAX
1702 typedef int ix_int;
1703 #define SIZEOF_IX_INT SIZEOF_INT
1704 #define IX_INT_MAX INT_MAX
1705 #elif LONG_MAX  >= X_INT_MAX
1706 typedef long ix_int;
1707 #define SIZEOF_IX_INT SIZEOF_LONG
1708 #define IX_INT_MAX LONG_MAX
1709 #else
1710 #error "ix_int implementation"
1711 #endif
1712 
1713 
1714 static void
get_ix_int(const void * xp,ix_int * ip)1715 get_ix_int(const void *xp, ix_int *ip)
1716 {
1717 	const uchar *cp = (const uchar *) xp;
1718 
1719 #if INT_MAX  >= X_INT_MAX
1720 	*ip = (ix_int)((unsigned)(*cp++) << 24);
1721 #else
1722 	*ip = *cp++ << 24;
1723 #endif
1724 #if SIZEOF_IX_INT > X_SIZEOF_INT
1725 	if (*ip & 0x80000000)
1726 	{
1727 		/* extern is negative */
1728 		*ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
1729 	}
1730 #endif
1731 	*ip |= (*cp++ << 16);
1732 	*ip |= (*cp++ << 8);
1733 	*ip |= *cp;
1734 }
1735 
1736 static void
put_ix_int(void * xp,const ix_int * ip)1737 put_ix_int(void *xp, const ix_int *ip)
1738 {
1739 	uchar *cp = (uchar *) xp;
1740 
1741 	*cp++ = (uchar)( (*ip) >> 24);
1742 	*cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
1743 	*cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
1744 	*cp   = (uchar)( (*ip) & 0x000000ff);
1745 }
1746 
1747 #if X_SIZEOF_INT != SIZEOF_INT
1748 static int
ncx_get_int_int(const void * xp,int * ip)1749 ncx_get_int_int(const void *xp, int *ip)
1750 {
1751     int err=NC_NOERR;
1752 #if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1753     get_ix_int(xp, (ix_int *)ip);
1754 #else
1755     ix_int xx;
1756     get_ix_int(xp, &xx);
1757 
1758 #if IX_INT_MAX > INT_MAX
1759     if (xx > INT_MAX || xx < INT_MIN) {
1760 #ifdef ERANGE_FILL
1761         *ip = NC_FILL_INT;
1762         return NC_ERANGE;
1763 #else
1764         err = NC_ERANGE;
1765 #endif
1766     }
1767 #endif
1768 
1769 
1770     *ip = (int) xx;
1771 #endif
1772     return err;
1773 }
1774 
1775 #endif
1776 static int
ncx_get_int_schar(const void * xp,schar * ip)1777 ncx_get_int_schar(const void *xp, schar *ip)
1778 {
1779     int err=NC_NOERR;
1780     ix_int xx;
1781     get_ix_int(xp, &xx);
1782 
1783 #if IX_INT_MAX > SCHAR_MAX
1784     if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
1785 #ifdef ERANGE_FILL
1786         *ip = NC_FILL_BYTE;
1787         return NC_ERANGE;
1788 #else
1789         err = NC_ERANGE;
1790 #endif
1791     }
1792 #endif
1793 
1794 
1795     *ip = (schar) xx;
1796     return err;
1797 }
1798 
1799 static int
ncx_get_int_short(const void * xp,short * ip)1800 ncx_get_int_short(const void *xp, short *ip)
1801 {
1802     int err=NC_NOERR;
1803 #if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1804     get_ix_int(xp, (ix_int *)ip);
1805 #else
1806     ix_int xx;
1807     get_ix_int(xp, &xx);
1808 
1809 #if IX_INT_MAX > SHORT_MAX
1810     if (xx > SHORT_MAX || xx < SHORT_MIN) {
1811 #ifdef ERANGE_FILL
1812         *ip = NC_FILL_SHORT;
1813         return NC_ERANGE;
1814 #else
1815         err = NC_ERANGE;
1816 #endif
1817     }
1818 #endif
1819 
1820 
1821     *ip = (short) xx;
1822 #endif
1823     return err;
1824 }
1825 
1826 static int
ncx_get_int_long(const void * xp,long * ip)1827 ncx_get_int_long(const void *xp, long *ip)
1828 {
1829     int err=NC_NOERR;
1830 #if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
1831     get_ix_int(xp, (ix_int *)ip);
1832 #else
1833     ix_int xx;
1834     get_ix_int(xp, &xx);
1835 
1836 #if IX_INT_MAX > LONG_MAX
1837     if (xx > LONG_MAX || xx < LONG_MIN) {
1838 #ifdef ERANGE_FILL
1839         *ip = NC_FILL_INT;
1840         return NC_ERANGE;
1841 #else
1842         err = NC_ERANGE;
1843 #endif
1844     }
1845 #endif
1846 
1847 
1848     *ip = (long) xx;
1849 #endif
1850     return err;
1851 }
1852 
1853 static int
ncx_get_int_longlong(const void * xp,longlong * ip)1854 ncx_get_int_longlong(const void *xp, longlong *ip)
1855 {
1856     int err=NC_NOERR;
1857 #if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1858     get_ix_int(xp, (ix_int *)ip);
1859 #else
1860     ix_int xx;
1861     get_ix_int(xp, &xx);
1862 
1863 #if IX_INT_MAX > LONGLONG_MAX
1864     if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
1865 #ifdef ERANGE_FILL
1866         *ip = NC_FILL_INT64;
1867         return NC_ERANGE;
1868 #else
1869         err = NC_ERANGE;
1870 #endif
1871     }
1872 #endif
1873 
1874 
1875     *ip = (longlong) xx;
1876 #endif
1877     return err;
1878 }
1879 
1880 static int
ncx_get_int_ushort(const void * xp,ushort * ip)1881 ncx_get_int_ushort(const void *xp, ushort *ip)
1882 {
1883     int err=NC_NOERR;
1884     ix_int xx;
1885     get_ix_int(xp, &xx);
1886 
1887 #if IX_INT_MAX > USHORT_MAX
1888     if (xx > USHORT_MAX) {
1889 #ifdef ERANGE_FILL
1890         *ip = NC_FILL_USHORT;
1891         return NC_ERANGE;
1892 #else
1893         err = NC_ERANGE;
1894 #endif
1895     }
1896 #endif
1897 
1898     if (xx < 0) {
1899 #ifdef ERANGE_FILL
1900         *ip = NC_FILL_USHORT;
1901         return NC_ERANGE;
1902 #else
1903         err = NC_ERANGE; /* because ip is unsigned */
1904 #endif
1905     }
1906     *ip = (ushort) xx;
1907     return err;
1908 }
1909 
1910 static int
ncx_get_int_uchar(const void * xp,uchar * ip)1911 ncx_get_int_uchar(const void *xp, uchar *ip)
1912 {
1913     int err=NC_NOERR;
1914     ix_int xx;
1915     get_ix_int(xp, &xx);
1916 
1917 #if IX_INT_MAX > UCHAR_MAX
1918     if (xx > UCHAR_MAX) {
1919 #ifdef ERANGE_FILL
1920         *ip = NC_FILL_UBYTE;
1921         return NC_ERANGE;
1922 #else
1923         err = NC_ERANGE;
1924 #endif
1925     }
1926 #endif
1927 
1928     if (xx < 0) {
1929 #ifdef ERANGE_FILL
1930         *ip = NC_FILL_UBYTE;
1931         return NC_ERANGE;
1932 #else
1933         err = NC_ERANGE; /* because ip is unsigned */
1934 #endif
1935     }
1936     *ip = (uchar) xx;
1937     return err;
1938 }
1939 
1940 static int
ncx_get_int_uint(const void * xp,uint * ip)1941 ncx_get_int_uint(const void *xp, uint *ip)
1942 {
1943     int err=NC_NOERR;
1944     ix_int xx;
1945     get_ix_int(xp, &xx);
1946 
1947 #if IX_INT_MAX > UINT_MAX
1948     if (xx > UINT_MAX) {
1949 #ifdef ERANGE_FILL
1950         *ip = NC_FILL_UINT;
1951         return NC_ERANGE;
1952 #else
1953         err = NC_ERANGE;
1954 #endif
1955     }
1956 #endif
1957 
1958     if (xx < 0) {
1959 #ifdef ERANGE_FILL
1960         *ip = NC_FILL_UINT;
1961         return NC_ERANGE;
1962 #else
1963         err = NC_ERANGE; /* because ip is unsigned */
1964 #endif
1965     }
1966     *ip = (uint) xx;
1967     return err;
1968 }
1969 
1970 static int
ncx_get_int_ulonglong(const void * xp,ulonglong * ip)1971 ncx_get_int_ulonglong(const void *xp, ulonglong *ip)
1972 {
1973     int err=NC_NOERR;
1974     ix_int xx;
1975     get_ix_int(xp, &xx);
1976 
1977 #if IX_INT_MAX > ULONGLONG_MAX
1978     if (xx > ULONGLONG_MAX) {
1979 #ifdef ERANGE_FILL
1980         *ip = NC_FILL_UINT64;
1981         return NC_ERANGE;
1982 #else
1983         err = NC_ERANGE;
1984 #endif
1985     }
1986 #endif
1987 
1988     if (xx < 0) {
1989 #ifdef ERANGE_FILL
1990         *ip = NC_FILL_UINT64;
1991         return NC_ERANGE;
1992 #else
1993         err = NC_ERANGE; /* because ip is unsigned */
1994 #endif
1995     }
1996     *ip = (ulonglong) xx;
1997     return err;
1998 }
1999 
2000 static int
ncx_get_int_float(const void * xp,float * ip)2001 ncx_get_int_float(const void *xp, float *ip)
2002 {
2003 	ix_int xx;
2004 	get_ix_int(xp, &xx);
2005 	*ip = (float)xx;
2006 	return NC_NOERR;
2007 }
2008 
2009 static int
ncx_get_int_double(const void * xp,double * ip)2010 ncx_get_int_double(const void *xp, double *ip)
2011 {
2012 	ix_int xx;
2013 	get_ix_int(xp, &xx);
2014 	*ip = (double)xx;
2015 	return NC_NOERR;
2016 }
2017 
2018 
2019 static int
ncx_put_int_schar(void * xp,const schar * ip,void * fillp)2020 ncx_put_int_schar(void *xp, const schar *ip, void *fillp)
2021 {
2022 	uchar *cp = (uchar *) xp;
2023 	if (*ip & 0x80)
2024 	{
2025 		*cp++ = 0xff;
2026 		*cp++ = 0xff;
2027 		*cp++ = 0xff;
2028 	}
2029 	else
2030 	{
2031 		*cp++ = 0x00;
2032 		*cp++ = 0x00;
2033 		*cp++ = 0x00;
2034 	}
2035 	*cp = (uchar)*ip;
2036 	return NC_NOERR;
2037 }
2038 
2039 static int
ncx_put_int_uchar(void * xp,const uchar * ip,void * fillp)2040 ncx_put_int_uchar(void *xp, const uchar *ip, void *fillp)
2041 {
2042 	uchar *cp = (uchar *) xp;
2043 	*cp++ = 0x00;
2044 	*cp++ = 0x00;
2045 	*cp++ = 0x00;
2046 	*cp   = *ip;
2047 	return NC_NOERR;
2048 }
2049 
2050 #if X_SIZEOF_INT != SIZEOF_INT
2051 static int
ncx_put_int_int(void * xp,const int * ip,void * fillp)2052 ncx_put_int_int(void *xp, const int *ip, void *fillp)
2053 {
2054     int err=NC_NOERR;
2055 #if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
2056     put_ix_int(xp, (const ix_int *)ip);
2057 #else
2058     ix_int xx = NC_FILL_INT;
2059 
2060 #if IX_INT_MAX < INT_MAX
2061     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2062 
2063 #ifdef ERANGE_FILL
2064             if (fillp != NULL) memcpy(&xx, fillp, 4);
2065 #endif
2066         err = NC_ERANGE;
2067     }
2068 #ifdef ERANGE_FILL
2069     else
2070 #endif
2071 #endif
2072         xx = (ix_int)*ip;
2073 
2074     put_ix_int(xp, &xx);
2075 #endif
2076     return err;
2077 }
2078 
2079 #endif
2080 static int
ncx_put_int_short(void * xp,const short * ip,void * fillp)2081 ncx_put_int_short(void *xp, const short *ip, void *fillp)
2082 {
2083     int err=NC_NOERR;
2084 #if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
2085     put_ix_int(xp, (const ix_int *)ip);
2086 #else
2087     ix_int xx = NC_FILL_INT;
2088 
2089 #if IX_INT_MAX < SHORT_MAX
2090     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2091 
2092 #ifdef ERANGE_FILL
2093             if (fillp != NULL) memcpy(&xx, fillp, 4);
2094 #endif
2095         err = NC_ERANGE;
2096     }
2097 #ifdef ERANGE_FILL
2098     else
2099 #endif
2100 #endif
2101         xx = (ix_int)*ip;
2102 
2103     put_ix_int(xp, &xx);
2104 #endif
2105     return err;
2106 }
2107 
2108 static int
ncx_put_int_long(void * xp,const long * ip,void * fillp)2109 ncx_put_int_long(void *xp, const long *ip, void *fillp)
2110 {
2111     int err=NC_NOERR;
2112 #if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
2113     put_ix_int(xp, (const ix_int *)ip);
2114 #else
2115     ix_int xx = NC_FILL_INT;
2116 
2117 #if IX_INT_MAX < LONG_MAX
2118     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2119 
2120 #ifdef ERANGE_FILL
2121             if (fillp != NULL) memcpy(&xx, fillp, 4);
2122 #endif
2123         err = NC_ERANGE;
2124     }
2125 #ifdef ERANGE_FILL
2126     else
2127 #endif
2128 #endif
2129         xx = (ix_int)*ip;
2130 
2131     put_ix_int(xp, &xx);
2132 #endif
2133     return err;
2134 }
2135 
2136 static int
ncx_put_int_longlong(void * xp,const longlong * ip,void * fillp)2137 ncx_put_int_longlong(void *xp, const longlong *ip, void *fillp)
2138 {
2139     int err=NC_NOERR;
2140 #if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
2141     put_ix_int(xp, (const ix_int *)ip);
2142 #else
2143     ix_int xx = NC_FILL_INT;
2144 
2145 #if IX_INT_MAX < LONGLONG_MAX
2146     if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
2147 
2148 #ifdef ERANGE_FILL
2149             if (fillp != NULL) memcpy(&xx, fillp, 4);
2150 #endif
2151         err = NC_ERANGE;
2152     }
2153 #ifdef ERANGE_FILL
2154     else
2155 #endif
2156 #endif
2157         xx = (ix_int)*ip;
2158 
2159     put_ix_int(xp, &xx);
2160 #endif
2161     return err;
2162 }
2163 
2164 static int
ncx_put_int_ushort(void * xp,const ushort * ip,void * fillp)2165 ncx_put_int_ushort(void *xp, const ushort *ip, void *fillp)
2166 {
2167     int err=NC_NOERR;
2168     ix_int xx = NC_FILL_INT;
2169 
2170 #if IX_INT_MAX < USHORT_MAX
2171     if (*ip > IX_INT_MAX) {
2172 
2173 #ifdef ERANGE_FILL
2174             if (fillp != NULL) memcpy(&xx, fillp, 4);
2175 #endif
2176         err = NC_ERANGE;
2177     }
2178 #ifdef ERANGE_FILL
2179     else
2180 #endif
2181 #endif
2182         xx = (ix_int)*ip;
2183 
2184     put_ix_int(xp, &xx);
2185     return err;
2186 }
2187 
2188 static int
ncx_put_int_uint(void * xp,const uint * ip,void * fillp)2189 ncx_put_int_uint(void *xp, const uint *ip, void *fillp)
2190 {
2191     int err=NC_NOERR;
2192     ix_int xx = NC_FILL_INT;
2193 
2194 #if IX_INT_MAX < UINT_MAX
2195     if (*ip > IX_INT_MAX) {
2196 
2197 #ifdef ERANGE_FILL
2198             if (fillp != NULL) memcpy(&xx, fillp, 4);
2199 #endif
2200         err = NC_ERANGE;
2201     }
2202 #ifdef ERANGE_FILL
2203     else
2204 #endif
2205 #endif
2206         xx = (ix_int)*ip;
2207 
2208     put_ix_int(xp, &xx);
2209     return err;
2210 }
2211 
2212 static int
ncx_put_int_ulonglong(void * xp,const ulonglong * ip,void * fillp)2213 ncx_put_int_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2214 {
2215     int err=NC_NOERR;
2216     ix_int xx = NC_FILL_INT;
2217 
2218 #if IX_INT_MAX < ULONGLONG_MAX
2219     if (*ip > IX_INT_MAX) {
2220 
2221 #ifdef ERANGE_FILL
2222             if (fillp != NULL) memcpy(&xx, fillp, 4);
2223 #endif
2224         err = NC_ERANGE;
2225     }
2226 #ifdef ERANGE_FILL
2227     else
2228 #endif
2229 #endif
2230         xx = (ix_int)*ip;
2231 
2232     put_ix_int(xp, &xx);
2233     return err;
2234 }
2235 
2236 static int
ncx_put_int_float(void * xp,const float * ip,void * fillp)2237 ncx_put_int_float(void *xp, const float *ip, void *fillp)
2238 {
2239     int err=NC_NOERR;
2240     ix_int xx = NC_FILL_INT;
2241 
2242     if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
2243 
2244 #ifdef ERANGE_FILL
2245             if (fillp != NULL) memcpy(&xx, fillp, 4);
2246 #endif
2247         err = NC_ERANGE;
2248     }
2249 #ifdef ERANGE_FILL
2250     else
2251 #endif
2252         xx = (ix_int)*ip;
2253 
2254     put_ix_int(xp, &xx);
2255     return err;
2256 }
2257 
2258 static int
ncx_put_int_double(void * xp,const double * ip,void * fillp)2259 ncx_put_int_double(void *xp, const double *ip, void *fillp)
2260 {
2261     int err=NC_NOERR;
2262     ix_int xx = NC_FILL_INT;
2263 
2264     if (*ip > X_INT_MAX || *ip < X_INT_MIN) {
2265 
2266 #ifdef ERANGE_FILL
2267             if (fillp != NULL) memcpy(&xx, fillp, 4);
2268 #endif
2269         err = NC_ERANGE;
2270     }
2271 #ifdef ERANGE_FILL
2272     else
2273 #endif
2274         xx = (ix_int)*ip;
2275 
2276     put_ix_int(xp, &xx);
2277     return err;
2278 }
2279 
2280 
2281 
2282 /* external NC_UINT ---------------------------------------------------------*/
2283 
2284 #if USHORT_MAX == X_UINT_MAX
2285 typedef ushort ix_uint;
2286 #define SIZEOF_IX_UINT SIZEOF_USHORT
2287 #define IX_UINT_MAX USHORT_MAX
2288 #elif UINT_MAX  >= X_UINT_MAX
2289 typedef uint ix_uint;
2290 #define SIZEOF_IX_UINT SIZEOF_UINT
2291 #define IX_UINT_MAX UINT_MAX
2292 #elif ULONG_MAX  >= X_UINT_MAX
2293 typedef ulong ix_uint;
2294 #define SIZEOF_IX_UINT SIZEOF_ULONG
2295 #define IX_UINT_MAX ULONG_MAX
2296 #else
2297 #error "ix_uint implementation"
2298 #endif
2299 
2300 
2301 static void
get_ix_uint(const void * xp,ix_uint * ip)2302 get_ix_uint(const void *xp, ix_uint *ip)
2303 {
2304 	const uchar *cp = (const uchar *) xp;
2305 
2306 	*ip = (ix_uint)(*cp++ << 24);
2307 	*ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 16));
2308 	*ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 8));
2309 	*ip = (ix_uint)(*ip | *cp);
2310 }
2311 
2312 static void
put_ix_uint(void * xp,const ix_uint * ip)2313 put_ix_uint(void *xp, const ix_uint *ip)
2314 {
2315 	uchar *cp = (uchar *) xp;
2316 
2317 	*cp++ = (uchar)((*ip) >> 24);
2318 	*cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
2319 	*cp++ = (uchar)(((*ip) & 0x0000ff00) >>  8);
2320 	*cp   = (uchar)( (*ip) & 0x000000ff);
2321 }
2322 
2323 #if X_SIZEOF_UINT != SIZEOF_UINT
2324 static int
ncx_get_uint_uint(const void * xp,uint * ip)2325 ncx_get_uint_uint(const void *xp, uint *ip)
2326 {
2327     int err=NC_NOERR;
2328 #if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2329     get_ix_uint(xp, (ix_uint *)ip);
2330 #else
2331     ix_uint xx;
2332     get_ix_uint(xp, &xx);
2333 
2334 #if IX_UINT_MAX > UINT_MAX
2335     if (xx > UINT_MAX) {
2336 #ifdef ERANGE_FILL
2337         *ip = NC_FILL_UINT;
2338         return NC_ERANGE;
2339 #else
2340         err = NC_ERANGE;
2341 #endif
2342     }
2343 #endif
2344 
2345 
2346     *ip = (uint) xx;
2347 #endif
2348     return err;
2349 }
2350 
2351 #endif
2352 
2353 static int
ncx_get_uint_schar(const void * xp,schar * ip)2354 ncx_get_uint_schar(const void *xp, schar *ip)
2355 {
2356     int err=NC_NOERR;
2357     ix_uint xx;
2358     get_ix_uint(xp, &xx);
2359 
2360 #if IX_UINT_MAX > SCHAR_MAX
2361     if (xx > SCHAR_MAX) {
2362 #ifdef ERANGE_FILL
2363         *ip = NC_FILL_BYTE;
2364         return NC_ERANGE;
2365 #else
2366         err = NC_ERANGE;
2367 #endif
2368     }
2369 #endif
2370 
2371 
2372     *ip = (schar) xx;
2373     return err;
2374 }
2375 
2376 static int
ncx_get_uint_short(const void * xp,short * ip)2377 ncx_get_uint_short(const void *xp, short *ip)
2378 {
2379     int err=NC_NOERR;
2380     ix_uint xx;
2381     get_ix_uint(xp, &xx);
2382 
2383 #if IX_UINT_MAX > SHORT_MAX
2384     if (xx > SHORT_MAX) {
2385 #ifdef ERANGE_FILL
2386         *ip = NC_FILL_SHORT;
2387         return NC_ERANGE;
2388 #else
2389         err = NC_ERANGE;
2390 #endif
2391     }
2392 #endif
2393 
2394 
2395     *ip = (short) xx;
2396     return err;
2397 }
2398 
2399 static int
ncx_get_uint_int(const void * xp,int * ip)2400 ncx_get_uint_int(const void *xp, int *ip)
2401 {
2402     int err=NC_NOERR;
2403     ix_uint xx;
2404     get_ix_uint(xp, &xx);
2405 
2406 #if IX_UINT_MAX > INT_MAX
2407     if (xx > INT_MAX) {
2408 #ifdef ERANGE_FILL
2409         *ip = NC_FILL_INT;
2410         return NC_ERANGE;
2411 #else
2412         err = NC_ERANGE;
2413 #endif
2414     }
2415 #endif
2416 
2417 
2418     *ip = (int) xx;
2419     return err;
2420 }
2421 
2422 static int
ncx_get_uint_long(const void * xp,long * ip)2423 ncx_get_uint_long(const void *xp, long *ip)
2424 {
2425     int err=NC_NOERR;
2426     ix_uint xx;
2427     get_ix_uint(xp, &xx);
2428 
2429 #if IX_UINT_MAX > LONG_MAX
2430     if (xx > LONG_MAX) {
2431 #ifdef ERANGE_FILL
2432         *ip = NC_FILL_INT;
2433         return NC_ERANGE;
2434 #else
2435         err = NC_ERANGE;
2436 #endif
2437     }
2438 #endif
2439 
2440 
2441     *ip = (long) xx;
2442     return err;
2443 }
2444 
2445 static int
ncx_get_uint_longlong(const void * xp,longlong * ip)2446 ncx_get_uint_longlong(const void *xp, longlong *ip)
2447 {
2448     int err=NC_NOERR;
2449     ix_uint xx;
2450     get_ix_uint(xp, &xx);
2451 
2452 #if IX_UINT_MAX > LONGLONG_MAX
2453     if (xx > LONGLONG_MAX) {
2454 #ifdef ERANGE_FILL
2455         *ip = NC_FILL_INT64;
2456         return NC_ERANGE;
2457 #else
2458         err = NC_ERANGE;
2459 #endif
2460     }
2461 #endif
2462 
2463 
2464     *ip = (longlong) xx;
2465     return err;
2466 }
2467 
2468 static int
ncx_get_uint_ushort(const void * xp,ushort * ip)2469 ncx_get_uint_ushort(const void *xp, ushort *ip)
2470 {
2471     int err=NC_NOERR;
2472 #if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2473     get_ix_uint(xp, (ix_uint *)ip);
2474 #else
2475     ix_uint xx;
2476     get_ix_uint(xp, &xx);
2477 
2478 #if IX_UINT_MAX > USHORT_MAX
2479     if (xx > USHORT_MAX) {
2480 #ifdef ERANGE_FILL
2481         *ip = NC_FILL_USHORT;
2482         return NC_ERANGE;
2483 #else
2484         err = NC_ERANGE;
2485 #endif
2486     }
2487 #endif
2488 
2489 
2490     *ip = (ushort) xx;
2491 #endif
2492     return err;
2493 }
2494 
2495 static int
ncx_get_uint_uchar(const void * xp,uchar * ip)2496 ncx_get_uint_uchar(const void *xp, uchar *ip)
2497 {
2498     int err=NC_NOERR;
2499 #if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
2500     get_ix_uint(xp, (ix_uint *)ip);
2501 #else
2502     ix_uint xx;
2503     get_ix_uint(xp, &xx);
2504 
2505 #if IX_UINT_MAX > UCHAR_MAX
2506     if (xx > UCHAR_MAX) {
2507 #ifdef ERANGE_FILL
2508         *ip = NC_FILL_UBYTE;
2509         return NC_ERANGE;
2510 #else
2511         err = NC_ERANGE;
2512 #endif
2513     }
2514 #endif
2515 
2516 
2517     *ip = (uchar) xx;
2518 #endif
2519     return err;
2520 }
2521 
2522 static int
ncx_get_uint_ulonglong(const void * xp,ulonglong * ip)2523 ncx_get_uint_ulonglong(const void *xp, ulonglong *ip)
2524 {
2525     int err=NC_NOERR;
2526 #if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2527     get_ix_uint(xp, (ix_uint *)ip);
2528 #else
2529     ix_uint xx;
2530     get_ix_uint(xp, &xx);
2531 
2532 #if IX_UINT_MAX > ULONGLONG_MAX
2533     if (xx > ULONGLONG_MAX) {
2534 #ifdef ERANGE_FILL
2535         *ip = NC_FILL_UINT64;
2536         return NC_ERANGE;
2537 #else
2538         err = NC_ERANGE;
2539 #endif
2540     }
2541 #endif
2542 
2543 
2544     *ip = (ulonglong) xx;
2545 #endif
2546     return err;
2547 }
2548 
2549 static int
ncx_get_uint_float(const void * xp,float * ip)2550 ncx_get_uint_float(const void *xp, float *ip)
2551 {
2552 	ix_uint xx;
2553 	get_ix_uint(xp, &xx);
2554 	*ip = (float)xx;
2555 	return NC_NOERR;
2556 }
2557 
2558 static int
ncx_get_uint_double(const void * xp,double * ip)2559 ncx_get_uint_double(const void *xp, double *ip)
2560 {
2561 	ix_uint xx;
2562 	get_ix_uint(xp, &xx);
2563 	*ip = (double)xx;
2564 	return NC_NOERR;
2565 }
2566 
2567 
2568 static int
ncx_put_uint_schar(void * xp,const schar * ip,void * fillp)2569 ncx_put_uint_schar(void *xp, const schar *ip, void *fillp)
2570 {
2571     uchar *cp;
2572     if (*ip < 0) {
2573 #ifdef ERANGE_FILL
2574         if (fillp != NULL) memcpy(xp, fillp, 4);
2575 #ifndef WORDS_BIGENDIAN
2576         swapn4b(xp, xp, 1);
2577 #endif
2578 #endif
2579         return NC_ERANGE;
2580     }
2581 
2582     cp = (uchar *) xp;
2583     *cp++ = 0x00;
2584     *cp++ = 0x00;
2585     *cp++ = 0x00;
2586     *cp = (uchar)*ip;
2587 
2588     return NC_NOERR;
2589 }
2590 
2591 static int
ncx_put_uint_uchar(void * xp,const uchar * ip,void * fillp)2592 ncx_put_uint_uchar(void *xp, const uchar *ip, void *fillp)
2593 {
2594 	uchar *cp = (uchar *) xp;
2595 	*cp++ = 0x00;
2596 	*cp++ = 0x00;
2597 	*cp++ = 0x00;
2598 	*cp   = *ip;
2599 	return NC_NOERR;
2600 }
2601 
2602 #if X_SIZEOF_UINT != SIZEOF_UINT
2603 static int
ncx_put_uint_uint(void * xp,const uint * ip,void * fillp)2604 ncx_put_uint_uint(void *xp, const uint *ip, void *fillp)
2605 {
2606     int err=NC_NOERR;
2607 #if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
2608     put_ix_uint(xp, (const ix_uint *)ip);
2609 #else
2610     ix_uint xx = NC_FILL_UINT;
2611 
2612 #if IX_UINT_MAX < UINT_MAX
2613     if (*ip > IX_UINT_MAX) {
2614 
2615 #ifdef ERANGE_FILL
2616             if (fillp != NULL) memcpy(&xx, fillp, 4);
2617 #endif
2618         err = NC_ERANGE;
2619     }
2620 #ifdef ERANGE_FILL
2621     else
2622 #endif
2623 #endif
2624         xx = (ix_uint)*ip;
2625 
2626     put_ix_uint(xp, &xx);
2627 #endif
2628     return err;
2629 }
2630 
2631 #endif
2632 
2633 static int
ncx_put_uint_short(void * xp,const short * ip,void * fillp)2634 ncx_put_uint_short(void *xp, const short *ip, void *fillp)
2635 {
2636     int err=NC_NOERR;
2637     ix_uint xx = NC_FILL_UINT;
2638 
2639 #if IX_UINT_MAX < SHORT_MAX
2640     if (*ip > IX_UINT_MAX) {
2641 
2642 #ifdef ERANGE_FILL
2643             if (fillp != NULL) memcpy(&xx, fillp, 4);
2644 #endif
2645         err = NC_ERANGE;
2646     }
2647 #ifdef ERANGE_FILL
2648     else
2649 #endif
2650 #endif
2651     if (*ip < 0) {
2652 
2653 #ifdef ERANGE_FILL
2654             if (fillp != NULL) memcpy(&xx, fillp, 4);
2655 #endif
2656         err = NC_ERANGE; /* because xp is unsigned */
2657     }
2658 #ifdef ERANGE_FILL
2659     else
2660 #endif
2661         xx = (ix_uint)*ip;
2662 
2663     put_ix_uint(xp, &xx);
2664     return err;
2665 }
2666 
2667 static int
ncx_put_uint_int(void * xp,const int * ip,void * fillp)2668 ncx_put_uint_int(void *xp, const int *ip, void *fillp)
2669 {
2670     int err=NC_NOERR;
2671     ix_uint xx = NC_FILL_UINT;
2672 
2673 #if IX_UINT_MAX < INT_MAX
2674     if (*ip > IX_UINT_MAX) {
2675 
2676 #ifdef ERANGE_FILL
2677             if (fillp != NULL) memcpy(&xx, fillp, 4);
2678 #endif
2679         err = NC_ERANGE;
2680     }
2681 #ifdef ERANGE_FILL
2682     else
2683 #endif
2684 #endif
2685     if (*ip < 0) {
2686 
2687 #ifdef ERANGE_FILL
2688             if (fillp != NULL) memcpy(&xx, fillp, 4);
2689 #endif
2690         err = NC_ERANGE; /* because xp is unsigned */
2691     }
2692 #ifdef ERANGE_FILL
2693     else
2694 #endif
2695         xx = (ix_uint)*ip;
2696 
2697     put_ix_uint(xp, &xx);
2698     return err;
2699 }
2700 
2701 static int
ncx_put_uint_long(void * xp,const long * ip,void * fillp)2702 ncx_put_uint_long(void *xp, const long *ip, void *fillp)
2703 {
2704     int err=NC_NOERR;
2705     ix_uint xx = NC_FILL_UINT;
2706 
2707 #if IX_UINT_MAX < LONG_MAX
2708     if (*ip > IX_UINT_MAX) {
2709 
2710 #ifdef ERANGE_FILL
2711             if (fillp != NULL) memcpy(&xx, fillp, 4);
2712 #endif
2713         err = NC_ERANGE;
2714     }
2715 #ifdef ERANGE_FILL
2716     else
2717 #endif
2718 #endif
2719     if (*ip < 0) {
2720 
2721 #ifdef ERANGE_FILL
2722             if (fillp != NULL) memcpy(&xx, fillp, 4);
2723 #endif
2724         err = NC_ERANGE; /* because xp is unsigned */
2725     }
2726 #ifdef ERANGE_FILL
2727     else
2728 #endif
2729         xx = (ix_uint)*ip;
2730 
2731     put_ix_uint(xp, &xx);
2732     return err;
2733 }
2734 
2735 static int
ncx_put_uint_longlong(void * xp,const longlong * ip,void * fillp)2736 ncx_put_uint_longlong(void *xp, const longlong *ip, void *fillp)
2737 {
2738     int err=NC_NOERR;
2739     ix_uint xx = NC_FILL_UINT;
2740 
2741 #if IX_UINT_MAX < LONGLONG_MAX
2742     if (*ip > IX_UINT_MAX) {
2743 
2744 #ifdef ERANGE_FILL
2745             if (fillp != NULL) memcpy(&xx, fillp, 4);
2746 #endif
2747         err = NC_ERANGE;
2748     }
2749 #ifdef ERANGE_FILL
2750     else
2751 #endif
2752 #endif
2753     if (*ip < 0) {
2754 
2755 #ifdef ERANGE_FILL
2756             if (fillp != NULL) memcpy(&xx, fillp, 4);
2757 #endif
2758         err = NC_ERANGE; /* because xp is unsigned */
2759     }
2760 #ifdef ERANGE_FILL
2761     else
2762 #endif
2763         xx = (ix_uint)*ip;
2764 
2765     put_ix_uint(xp, &xx);
2766     return err;
2767 }
2768 
2769 static int
ncx_put_uint_ushort(void * xp,const ushort * ip,void * fillp)2770 ncx_put_uint_ushort(void *xp, const ushort *ip, void *fillp)
2771 {
2772     int err=NC_NOERR;
2773 #if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
2774     put_ix_uint(xp, (const ix_uint *)ip);
2775 #else
2776     ix_uint xx = NC_FILL_UINT;
2777 
2778 #if IX_UINT_MAX < USHORT_MAX
2779     if (*ip > IX_UINT_MAX) {
2780 
2781 #ifdef ERANGE_FILL
2782             if (fillp != NULL) memcpy(&xx, fillp, 4);
2783 #endif
2784         err = NC_ERANGE;
2785     }
2786 #ifdef ERANGE_FILL
2787     else
2788 #endif
2789 #endif
2790         xx = (ix_uint)*ip;
2791 
2792     put_ix_uint(xp, &xx);
2793 #endif
2794     return err;
2795 }
2796 
2797 static int
ncx_put_uint_ulonglong(void * xp,const ulonglong * ip,void * fillp)2798 ncx_put_uint_ulonglong(void *xp, const ulonglong *ip, void *fillp)
2799 {
2800     int err=NC_NOERR;
2801 #if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
2802     put_ix_uint(xp, (const ix_uint *)ip);
2803 #else
2804     ix_uint xx = NC_FILL_UINT;
2805 
2806 #if IX_UINT_MAX < ULONGLONG_MAX
2807     if (*ip > IX_UINT_MAX) {
2808 
2809 #ifdef ERANGE_FILL
2810             if (fillp != NULL) memcpy(&xx, fillp, 4);
2811 #endif
2812         err = NC_ERANGE;
2813     }
2814 #ifdef ERANGE_FILL
2815     else
2816 #endif
2817 #endif
2818         xx = (ix_uint)*ip;
2819 
2820     put_ix_uint(xp, &xx);
2821 #endif
2822     return err;
2823 }
2824 
2825 static int
ncx_put_uint_float(void * xp,const float * ip,void * fillp)2826 ncx_put_uint_float(void *xp, const float *ip, void *fillp)
2827 {
2828     int err=NC_NOERR;
2829     ix_uint xx = NC_FILL_UINT;
2830 
2831     if (*ip > (double)X_UINT_MAX || *ip < 0) {
2832 
2833 #ifdef ERANGE_FILL
2834             if (fillp != NULL) memcpy(&xx, fillp, 4);
2835 #endif
2836         err = NC_ERANGE;
2837     }
2838 #ifdef ERANGE_FILL
2839     else
2840 #endif
2841         xx = (ix_uint)*ip;
2842 
2843     put_ix_uint(xp, &xx);
2844     return err;
2845 }
2846 
2847 static int
ncx_put_uint_double(void * xp,const double * ip,void * fillp)2848 ncx_put_uint_double(void *xp, const double *ip, void *fillp)
2849 {
2850     int err=NC_NOERR;
2851     ix_uint xx = NC_FILL_UINT;
2852 
2853     if (*ip > X_UINT_MAX || *ip < 0) {
2854 
2855 #ifdef ERANGE_FILL
2856             if (fillp != NULL) memcpy(&xx, fillp, 4);
2857 #endif
2858         err = NC_ERANGE;
2859     }
2860 #ifdef ERANGE_FILL
2861     else
2862 #endif
2863         xx = (ix_uint)*ip;
2864 
2865     put_ix_uint(xp, &xx);
2866     return err;
2867 }
2868 
2869 
2870 
2871 /* external NC_FLOAT --------------------------------------------------------*/
2872 
2873 #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
2874 
2875 inline static void
get_ix_float(const void * xp,float * ip)2876 get_ix_float(const void *xp, float *ip)
2877 {
2878 #ifdef WORDS_BIGENDIAN
2879 	(void) memcpy(ip, xp, SIZEOF_FLOAT);
2880 #else
2881 	swap4b(ip, xp);
2882 #endif
2883 }
2884 
2885 inline static void
put_ix_float(void * xp,const float * ip)2886 put_ix_float(void *xp, const float *ip)
2887 {
2888 #ifdef WORDS_BIGENDIAN
2889 	(void) memcpy(xp, ip, X_SIZEOF_FLOAT);
2890 #else
2891 	swap4b(xp, ip);
2892 #endif
2893 }
2894 
2895 #elif defined(vax) && vax != 0
2896 
2897 /* What IEEE single precision floating point looks like on a Vax */
2898 struct	ieee_single {
2899 	unsigned int	exp_hi       : 7;
2900 	unsigned int	sign         : 1;
2901 	unsigned int 	mant_hi      : 7;
2902 	unsigned int	exp_lo       : 1;
2903 	unsigned int	mant_lo_hi   : 8;
2904 	unsigned int	mant_lo_lo   : 8;
2905 };
2906 
2907 /* Vax single precision floating point */
2908 struct	vax_single {
2909 	unsigned int	mantissa1 : 7;
2910 	unsigned int	exp       : 8;
2911 	unsigned int	sign      : 1;
2912 	unsigned int	mantissa2 : 16;
2913 };
2914 
2915 #define VAX_SNG_BIAS	0x81
2916 #define IEEE_SNG_BIAS	0x7f
2917 
2918 static struct sgl_limits {
2919 	struct vax_single s;
2920 	struct ieee_single ieee;
2921 } max = {
2922 	{ 0x7f, 0xff, 0x0, 0xffff },	/* Max Vax */
2923 	{ 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }		/* Max IEEE */
2924 };
2925 static struct sgl_limits min = {
2926 	{ 0x0, 0x0, 0x0, 0x0 },	/* Min Vax */
2927 	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }		/* Min IEEE */
2928 };
2929 
2930 static void
get_ix_float(const void * xp,float * ip)2931 get_ix_float(const void *xp, float *ip)
2932 {
2933 		struct vax_single *const vsp = (struct vax_single *) ip;
2934 		const struct ieee_single *const isp =
2935 			 (const struct ieee_single *) xp;
2936 		unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
2937 
2938 		switch(exp) {
2939 		case 0 :
2940 			/* ieee subnormal */
2941 			if (isp->mant_hi == min.ieee.mant_hi
2942 				&& isp->mant_lo_hi == min.ieee.mant_lo_hi
2943 				&& isp->mant_lo_lo == min.ieee.mant_lo_lo)
2944 			{
2945 				*vsp = min.s;
2946 			}
2947 			else
2948 			{
2949 				unsigned mantissa = (isp->mant_hi << 16)
2950 					 | isp->mant_lo_hi << 8
2951 					 | isp->mant_lo_lo;
2952 				unsigned tmp = mantissa >> 20;
2953 				if (tmp >= 4) {
2954 					vsp->exp = 2;
2955 				} else if (tmp >= 2) {
2956 					vsp->exp = 1;
2957 				} else {
2958 					*vsp = min.s;
2959 					break;
2960 				} /* else */
2961 				tmp = mantissa - (1 << (20 + vsp->exp ));
2962 				tmp <<= 3 - vsp->exp;
2963 				vsp->mantissa2 = tmp;
2964 				vsp->mantissa1 = (tmp >> 16);
2965 			}
2966 			break;
2967 		case 0xfe :
2968 		case 0xff :
2969 			*vsp = max.s;
2970 			break;
2971 		default :
2972 			vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
2973 			vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
2974 			vsp->mantissa1 = isp->mant_hi;
2975 		}
2976 
2977 		vsp->sign = isp->sign;
2978 
2979 }
2980 
2981 
2982 static void
put_ix_float(void * xp,const float * ip)2983 put_ix_float(void *xp, const float *ip)
2984 {
2985 		const struct vax_single *const vsp =
2986 			 (const struct vax_single *)ip;
2987 		struct ieee_single *const isp = (struct ieee_single *) xp;
2988 
2989 		switch(vsp->exp){
2990 		case 0 :
2991 			/* all vax float with zero exponent map to zero */
2992 			*isp = min.ieee;
2993 			break;
2994 		case 2 :
2995 		case 1 :
2996 		{
2997 			/* These will map to subnormals */
2998 			unsigned mantissa = (vsp->mantissa1 << 16)
2999 					 | vsp->mantissa2;
3000 			mantissa >>= 3 - vsp->exp;
3001 			mantissa += (1 << (20 + vsp->exp));
3002 			isp->mant_lo_lo = mantissa;
3003 			isp->mant_lo_hi = mantissa >> 8;
3004 			isp->mant_hi = mantissa >> 16;
3005 			isp->exp_lo = 0;
3006 			isp->exp_hi = 0;
3007 		}
3008 			break;
3009 		case 0xff : /* max.s.exp */
3010 			if (vsp->mantissa2 == max.s.mantissa2 &&
3011 			    vsp->mantissa1 == max.s.mantissa1)
3012 			{
3013 				/* map largest vax float to ieee infinity */
3014 				*isp = max.ieee;
3015 				break;
3016 			} /* else, fall thru */
3017 		default :
3018 		{
3019 			unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
3020 			isp->exp_hi = exp >> 1;
3021 			isp->exp_lo = exp;
3022 			isp->mant_lo_lo = vsp->mantissa2;
3023 			isp->mant_lo_hi = vsp->mantissa2 >> 8;
3024 			isp->mant_hi = vsp->mantissa1;
3025 		}
3026 		}
3027 
3028 		isp->sign = vsp->sign;
3029 
3030 }
3031 
3032 	/* vax */
3033 #elif defined(_CRAY) && !defined(__crayx1)
3034 
3035 /*
3036  * Return the number of bytes until the next "word" boundary
3037  * N.B. This is based on the very weird YMP address structure,
3038  * which puts the address within a word in the leftmost 3 bits
3039  * of the address.
3040  */
3041 static size_t
word_align(const void * vp)3042 word_align(const void *vp)
3043 {
3044 	const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
3045 	return (rem != 0);
3046 }
3047 
3048 struct ieee_single_hi {
3049 	unsigned int	sign	: 1;
3050 	unsigned int	 exp	: 8;
3051 	unsigned int	mant	:23;
3052 	unsigned int	pad	:32;
3053 };
3054 typedef struct ieee_single_hi ieee_single_hi;
3055 
3056 struct ieee_single_lo {
3057 	unsigned int	pad	:32;
3058 	unsigned int	sign	: 1;
3059 	unsigned int	 exp	: 8;
3060 	unsigned int	mant	:23;
3061 };
3062 typedef struct ieee_single_lo ieee_single_lo;
3063 
3064 static const int ieee_single_bias = 0x7f;
3065 
3066 struct ieee_double {
3067 	unsigned int	sign	: 1;
3068 	unsigned int	 exp	:11;
3069 	unsigned int	mant	:52;
3070 };
3071 typedef struct ieee_double ieee_double;
3072 
3073 static const int ieee_double_bias = 0x3ff;
3074 
3075 #if defined(NO_IEEE_FLOAT)
3076 
3077 struct cray_single {
3078 	unsigned int	sign	: 1;
3079 	unsigned int	 exp	:15;
3080 	unsigned int	mant	:48;
3081 };
3082 typedef struct cray_single cray_single;
3083 
3084 static const int cs_ieis_bias = 0x4000 - 0x7f;
3085 
3086 static const int cs_id_bias = 0x4000 - 0x3ff;
3087 
3088 
3089 static void
get_ix_float(const void * xp,float * ip)3090 get_ix_float(const void *xp, float *ip)
3091 {
3092 
3093 	if (word_align(xp) == 0)
3094 	{
3095 		const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3096 		cray_single *csp = (cray_single *) ip;
3097 
3098 		if (isp->exp == 0)
3099 		{
3100 			/* ieee subnormal */
3101 			*ip = (double)isp->mant;
3102 			if (isp->mant != 0)
3103 			{
3104 				csp->exp -= (ieee_single_bias + 22);
3105 			}
3106 		}
3107 		else
3108 		{
3109 			csp->exp  = isp->exp + cs_ieis_bias + 1;
3110 			csp->mant = isp->mant << (48 - 1 - 23);
3111 			csp->mant |= (1 << (48 - 1));
3112 		}
3113 		csp->sign = isp->sign;
3114 
3115 
3116 	}
3117 	else
3118 	{
3119 		const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3120 		cray_single *csp = (cray_single *) ip;
3121 
3122 		if (isp->exp == 0)
3123 		{
3124 			/* ieee subnormal */
3125 			*ip = (double)isp->mant;
3126 			if (isp->mant != 0)
3127 			{
3128 				csp->exp -= (ieee_single_bias + 22);
3129 			}
3130 		}
3131 		else
3132 		{
3133 			csp->exp  = isp->exp + cs_ieis_bias + 1;
3134 			csp->mant = isp->mant << (48 - 1 - 23);
3135 			csp->mant |= (1 << (48 - 1));
3136 		}
3137 		csp->sign = isp->sign;
3138 
3139 
3140 	}
3141 }
3142 
3143 static void
put_ix_float(void * xp,const float * ip)3144 put_ix_float(void *xp, const float *ip)
3145 {
3146 	if (word_align(xp) == 0)
3147 	{
3148 		ieee_single_hi *isp = (ieee_single_hi*)xp;
3149 	const cray_single *csp = (const cray_single *) ip;
3150 	int ieee_exp = csp->exp - cs_ieis_bias -1;
3151 
3152 	isp->sign = csp->sign;
3153 
3154 	if (ieee_exp >= 0xff)
3155 	{
3156 		/* NC_ERANGE => ieee Inf */
3157 		isp->exp = 0xff;
3158 		isp->mant = 0x0;
3159 	}
3160 	else if (ieee_exp > 0)
3161 	{
3162 		/* normal ieee representation */
3163 		isp->exp  = ieee_exp;
3164 		/* assumes cray rep is in normal form */
3165 		assert(csp->mant & 0x800000000000);
3166 		isp->mant = (((csp->mant << 1) &
3167 				0xffffffffffff) >> (48 - 23));
3168 	}
3169 	else if (ieee_exp > -23)
3170 	{
3171 		/* ieee subnormal, right shift */
3172 		const int rshift = (48 - 23 - ieee_exp);
3173 
3174 		isp->mant = csp->mant >> rshift;
3175 
3176 #if 0
3177 		if (csp->mant & (1 << (rshift -1)))
3178 		{
3179 			/* round up */
3180 			isp->mant++;
3181 		}
3182 #endif
3183 
3184 		isp->exp  = 0;
3185 	}
3186 	else
3187 	{
3188 		/* smaller than ieee can represent */
3189 		isp->exp = 0;
3190 		isp->mant = 0;
3191 	}
3192 
3193 	}
3194 	else
3195 	{
3196 		ieee_single_lo *isp = (ieee_single_lo*)xp;
3197 	const cray_single *csp = (const cray_single *) ip;
3198 	int ieee_exp = csp->exp - cs_ieis_bias -1;
3199 
3200 	isp->sign = csp->sign;
3201 
3202 	if (ieee_exp >= 0xff)
3203 	{
3204 		/* NC_ERANGE => ieee Inf */
3205 		isp->exp = 0xff;
3206 		isp->mant = 0x0;
3207 	}
3208 	else if (ieee_exp > 0)
3209 	{
3210 		/* normal ieee representation */
3211 		isp->exp  = ieee_exp;
3212 		/* assumes cray rep is in normal form */
3213 		assert(csp->mant & 0x800000000000);
3214 		isp->mant = (((csp->mant << 1) &
3215 				0xffffffffffff) >> (48 - 23));
3216 	}
3217 	else if (ieee_exp > -23)
3218 	{
3219 		/* ieee subnormal, right shift */
3220 		const int rshift = (48 - 23 - ieee_exp);
3221 
3222 		isp->mant = csp->mant >> rshift;
3223 
3224 #if 0
3225 		if (csp->mant & (1 << (rshift -1)))
3226 		{
3227 			/* round up */
3228 			isp->mant++;
3229 		}
3230 #endif
3231 
3232 		isp->exp  = 0;
3233 	}
3234 	else
3235 	{
3236 		/* smaller than ieee can represent */
3237 		isp->exp = 0;
3238 		isp->mant = 0;
3239 	}
3240 
3241 	}
3242 }
3243 
3244 #else
3245 	/* IEEE Cray with only doubles */
3246 static void
get_ix_float(const void * xp,float * ip)3247 get_ix_float(const void *xp, float *ip)
3248 {
3249 
3250 	ieee_double *idp = (ieee_double *) ip;
3251 
3252 	if (word_align(xp) == 0)
3253 	{
3254 		const ieee_single_hi *isp = (const ieee_single_hi *) xp;
3255 		if (isp->exp == 0 && isp->mant == 0)
3256 		{
3257 			idp->exp = 0;
3258 			idp->mant = 0;
3259 		}
3260 		else
3261 		{
3262 			idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3263 			idp->mant = isp->mant << (52 - 23);
3264 		}
3265 		idp->sign = isp->sign;
3266 	}
3267 	else
3268 	{
3269 		const ieee_single_lo *isp = (const ieee_single_lo *) xp;
3270 		if (isp->exp == 0 && isp->mant == 0)
3271 		{
3272 			idp->exp = 0;
3273 			idp->mant = 0;
3274 		}
3275 		else
3276 		{
3277 			idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
3278 			idp->mant = isp->mant << (52 - 23);
3279 		}
3280 		idp->sign = isp->sign;
3281 	}
3282 }
3283 
3284 static void
put_ix_float(void * xp,const float * ip)3285 put_ix_float(void *xp, const float *ip)
3286 {
3287 	const ieee_double *idp = (const ieee_double *) ip;
3288 	if (word_align(xp) == 0)
3289 	{
3290 		ieee_single_hi *isp = (ieee_single_hi*)xp;
3291 		if (idp->exp > (ieee_double_bias - ieee_single_bias))
3292 			isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3293 		else
3294 			isp->exp = 0;
3295 		isp->mant = idp->mant >> (52 - 23);
3296 		isp->sign = idp->sign;
3297 	}
3298 	else
3299 	{
3300 		ieee_single_lo *isp = (ieee_single_lo*)xp;
3301 		if (idp->exp > (ieee_double_bias - ieee_single_bias))
3302 			isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
3303 		else
3304 			isp->exp = 0;
3305 		isp->mant = idp->mant >> (52 - 23);
3306 		isp->sign = idp->sign;
3307 	}
3308 }
3309 #endif
3310 
3311 #else
3312 #error "ix_float implementation"
3313 #endif
3314 
3315 #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3316 static int
ncx_get_float_float(const void * xp,float * ip,void * fillp)3317 ncx_get_float_float(const void *xp, float *ip, void *fillp)
3318 {
3319 	/* TODO */
3320 	get_ix_float(xp, ip);
3321 	return NC_NOERR;
3322 }
3323 #endif
3324 
3325 #define ix_float float
3326 
3327 static int
ncx_get_float_schar(const void * xp,schar * ip)3328 ncx_get_float_schar(const void *xp, schar *ip)
3329 {
3330 	ix_float xx;
3331 	get_ix_float(xp, &xx);
3332 	if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3333 #ifdef ERANGE_FILL
3334             *ip = NC_FILL_BYTE;
3335 #endif
3336             return NC_ERANGE;
3337         }
3338 	*ip = (schar)xx;
3339 	return NC_NOERR;
3340 }
3341 
3342 static int
ncx_get_float_short(const void * xp,short * ip)3343 ncx_get_float_short(const void *xp, short *ip)
3344 {
3345 	ix_float xx;
3346 	get_ix_float(xp, &xx);
3347 	if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3348 #ifdef ERANGE_FILL
3349             *ip = NC_FILL_SHORT;
3350 #endif
3351             return NC_ERANGE;
3352         }
3353 	*ip = (short)xx;
3354 	return NC_NOERR;
3355 }
3356 
3357 static int
ncx_get_float_int(const void * xp,int * ip)3358 ncx_get_float_int(const void *xp, int *ip)
3359 {
3360 	ix_float xx;
3361 	get_ix_float(xp, &xx);
3362 	if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3363 #ifdef ERANGE_FILL
3364             *ip = NC_FILL_INT;
3365 #endif
3366             return NC_ERANGE;
3367         }
3368 	*ip = (int)xx;
3369 	return NC_NOERR;
3370 }
3371 
3372 static int
ncx_get_float_long(const void * xp,long * ip)3373 ncx_get_float_long(const void *xp, long *ip)
3374 {
3375 	ix_float xx;
3376 	get_ix_float(xp, &xx);
3377 	if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3378 #ifdef ERANGE_FILL
3379             *ip = NC_FILL_INT;
3380 #endif
3381             return NC_ERANGE;
3382         }
3383 	*ip = (long)xx;
3384 	return NC_NOERR;
3385 }
3386 
3387 static int
ncx_get_float_double(const void * xp,double * ip)3388 ncx_get_float_double(const void *xp, double *ip)
3389 {
3390 	ix_float xx;
3391 	get_ix_float(xp, &xx);
3392 	*ip = (double)xx;
3393 	return NC_NOERR;
3394 }
3395 
3396 static int
ncx_get_float_longlong(const void * xp,longlong * ip)3397 ncx_get_float_longlong(const void *xp, longlong *ip)
3398 {
3399 	ix_float xx;
3400 	get_ix_float(xp, &xx);
3401 	if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3402 	else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3403 	else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3404 #ifdef ERANGE_FILL
3405             *ip = NC_FILL_INT64;
3406 #endif
3407             return NC_ERANGE;
3408         }
3409 	else *ip = (longlong)xx;
3410 	return NC_NOERR;
3411 }
3412 
3413 static int
ncx_get_float_uchar(const void * xp,uchar * ip)3414 ncx_get_float_uchar(const void *xp, uchar *ip)
3415 {
3416 	ix_float xx;
3417 	get_ix_float(xp, &xx);
3418 	if (xx > (double)UCHAR_MAX || xx < 0) {
3419 #ifdef ERANGE_FILL
3420             *ip = NC_FILL_UBYTE;
3421 #endif
3422             return NC_ERANGE;
3423         }
3424 	*ip = (uchar)xx;
3425 	return NC_NOERR;
3426 }
3427 
3428 static int
ncx_get_float_ushort(const void * xp,ushort * ip)3429 ncx_get_float_ushort(const void *xp, ushort *ip)
3430 {
3431 	ix_float xx;
3432 	get_ix_float(xp, &xx);
3433 	if (xx > (double)USHORT_MAX || xx < 0) {
3434 #ifdef ERANGE_FILL
3435             *ip = NC_FILL_USHORT;
3436 #endif
3437             return NC_ERANGE;
3438         }
3439 	*ip = (ushort)xx;
3440 	return NC_NOERR;
3441 }
3442 
3443 static int
ncx_get_float_uint(const void * xp,uint * ip)3444 ncx_get_float_uint(const void *xp, uint *ip)
3445 {
3446 	ix_float xx;
3447 	get_ix_float(xp, &xx);
3448 	if (xx > (double)UINT_MAX || xx < 0) {
3449 #ifdef ERANGE_FILL
3450             *ip = NC_FILL_UINT;
3451 #endif
3452             return NC_ERANGE;
3453         }
3454 	*ip = (uint)xx;
3455 	return NC_NOERR;
3456 }
3457 
3458 static int
ncx_get_float_ulonglong(const void * xp,ulonglong * ip)3459 ncx_get_float_ulonglong(const void *xp, ulonglong *ip)
3460 {
3461 	ix_float xx;
3462 	get_ix_float(xp, &xx);
3463 	if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
3464 	else if (xx > (double)ULONGLONG_MAX || xx < 0) {
3465 #ifdef ERANGE_FILL
3466             *ip = NC_FILL_UINT64;
3467 #endif
3468             return NC_ERANGE;
3469         }
3470 	else *ip = (ulonglong)xx;
3471 	return NC_NOERR;
3472 }
3473 
3474 
3475 #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
3476 static int
ncx_put_float_float(void * xp,const float * ip,void * fillp)3477 ncx_put_float_float(void *xp, const float *ip, void *fillp)
3478 {
3479     int err=NC_NOERR;
3480     float *_ip=ip;
3481 #ifdef NO_IEEE_FLOAT
3482 #ifdef ERANGE_FILL
3483     float tmp;
3484 #endif
3485     if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3486 
3487 #ifdef ERANGE_FILL
3488             if (fillp != NULL) memcpy(&tmp, fillp, 4);
3489 #endif
3490 #ifdef ERANGE_FILL
3491         _ip = &tmp;
3492 #endif
3493         err = NC_ERANGE;
3494     }
3495 #endif
3496     put_ix_float(xp, _ip);
3497     return err;
3498 }
3499 #endif
3500 
3501 static int
ncx_put_float_schar(void * xp,const schar * ip,void * fillp)3502 ncx_put_float_schar(void *xp, const schar *ip, void *fillp)
3503 {
3504     int err=NC_NOERR;
3505     ix_float xx = NC_FILL_FLOAT;
3506 
3507 
3508         xx = (ix_float)*ip;
3509 
3510     put_ix_float(xp, &xx);
3511     return err;
3512 }
3513 
3514 static int
ncx_put_float_short(void * xp,const short * ip,void * fillp)3515 ncx_put_float_short(void *xp, const short *ip, void *fillp)
3516 {
3517     int err=NC_NOERR;
3518     ix_float xx = NC_FILL_FLOAT;
3519 
3520 
3521         xx = (ix_float)*ip;
3522 
3523     put_ix_float(xp, &xx);
3524     return err;
3525 }
3526 
3527 static int
ncx_put_float_int(void * xp,const int * ip,void * fillp)3528 ncx_put_float_int(void *xp, const int *ip, void *fillp)
3529 {
3530     int err=NC_NOERR;
3531     ix_float xx = NC_FILL_FLOAT;
3532 
3533 
3534         xx = (ix_float)*ip;
3535 
3536     put_ix_float(xp, &xx);
3537     return err;
3538 }
3539 
3540 static int
ncx_put_float_long(void * xp,const long * ip,void * fillp)3541 ncx_put_float_long(void *xp, const long *ip, void *fillp)
3542 {
3543     int err=NC_NOERR;
3544     ix_float xx = NC_FILL_FLOAT;
3545 
3546 
3547         xx = (ix_float)*ip;
3548 
3549     put_ix_float(xp, &xx);
3550     return err;
3551 }
3552 
3553 static int
ncx_put_float_double(void * xp,const double * ip,void * fillp)3554 ncx_put_float_double(void *xp, const double *ip, void *fillp)
3555 {
3556     int err=NC_NOERR;
3557     ix_float xx = NC_FILL_FLOAT;
3558 
3559     if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
3560 
3561 #ifdef ERANGE_FILL
3562             if (fillp != NULL) memcpy(&xx, fillp, 4);
3563 #endif
3564         err = NC_ERANGE;
3565     }
3566 #ifdef ERANGE_FILL
3567     else
3568 #endif
3569         xx = (ix_float)*ip;
3570 
3571     put_ix_float(xp, &xx);
3572     return err;
3573 }
3574 
3575 static int
ncx_put_float_longlong(void * xp,const longlong * ip,void * fillp)3576 ncx_put_float_longlong(void *xp, const longlong *ip, void *fillp)
3577 {
3578     int err=NC_NOERR;
3579     ix_float xx = NC_FILL_FLOAT;
3580 
3581 
3582         xx = (ix_float)*ip;
3583 
3584     put_ix_float(xp, &xx);
3585     return err;
3586 }
3587 
3588 static int
ncx_put_float_uchar(void * xp,const uchar * ip,void * fillp)3589 ncx_put_float_uchar(void *xp, const uchar *ip, void *fillp)
3590 {
3591     int err=NC_NOERR;
3592     ix_float xx = NC_FILL_FLOAT;
3593 
3594 
3595         xx = (ix_float)*ip;
3596 
3597     put_ix_float(xp, &xx);
3598     return err;
3599 }
3600 
3601 static int
ncx_put_float_ushort(void * xp,const ushort * ip,void * fillp)3602 ncx_put_float_ushort(void *xp, const ushort *ip, void *fillp)
3603 {
3604     int err=NC_NOERR;
3605     ix_float xx = NC_FILL_FLOAT;
3606 
3607 
3608         xx = (ix_float)*ip;
3609 
3610     put_ix_float(xp, &xx);
3611     return err;
3612 }
3613 
3614 static int
ncx_put_float_uint(void * xp,const uint * ip,void * fillp)3615 ncx_put_float_uint(void *xp, const uint *ip, void *fillp)
3616 {
3617     int err=NC_NOERR;
3618     ix_float xx = NC_FILL_FLOAT;
3619 
3620 
3621         xx = (ix_float)*ip;
3622 
3623     put_ix_float(xp, &xx);
3624     return err;
3625 }
3626 
3627 static int
ncx_put_float_ulonglong(void * xp,const ulonglong * ip,void * fillp)3628 ncx_put_float_ulonglong(void *xp, const ulonglong *ip, void *fillp)
3629 {
3630     int err=NC_NOERR;
3631     ix_float xx = NC_FILL_FLOAT;
3632 
3633 
3634         xx = (ix_float)*ip;
3635 
3636     put_ix_float(xp, &xx);
3637     return err;
3638 }
3639 
3640 
3641 
3642 /* external NC_DOUBLE -------------------------------------------------------*/
3643 
3644 #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
3645 
3646 static void
get_ix_double(const void * xp,double * ip)3647 get_ix_double(const void *xp, double *ip)
3648 {
3649 #ifdef WORDS_BIGENDIAN
3650 	(void) memcpy(ip, xp, SIZEOF_DOUBLE);
3651 #else
3652 	swap8b(ip, xp);
3653 #endif
3654 }
3655 
3656 static void
put_ix_double(void * xp,const double * ip)3657 put_ix_double(void *xp, const double *ip)
3658 {
3659 #ifdef WORDS_BIGENDIAN
3660 	(void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
3661 #else
3662 	swap8b(xp, ip);
3663 #endif
3664 }
3665 
3666 #elif defined(vax) && vax != 0
3667 
3668 /* What IEEE double precision floating point looks like on a Vax */
3669 struct	ieee_double {
3670 	unsigned int	exp_hi   : 7;
3671 	unsigned int	sign     : 1;
3672 	unsigned int 	mant_6   : 4;
3673 	unsigned int	exp_lo   : 4;
3674 	unsigned int	mant_5   : 8;
3675 	unsigned int	mant_4   : 8;
3676 
3677 	unsigned int	mant_lo  : 32;
3678 };
3679 
3680 /* Vax double precision floating point */
3681 struct  vax_double {
3682 	unsigned int	mantissa1 : 7;
3683 	unsigned int	exp       : 8;
3684 	unsigned int	sign      : 1;
3685 	unsigned int	mantissa2 : 16;
3686 	unsigned int	mantissa3 : 16;
3687 	unsigned int	mantissa4 : 16;
3688 };
3689 
3690 #define VAX_DBL_BIAS	0x81
3691 #define IEEE_DBL_BIAS	0x3ff
3692 #define MASK(nbits)	((1 << nbits) - 1)
3693 
3694 static const struct dbl_limits {
3695 	struct	vax_double d;
3696 	struct	ieee_double ieee;
3697 } dbl_limits[2] = {
3698 	{{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },	/* Max Vax */
3699 	{ 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
3700 	{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* Min Vax */
3701 	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
3702 };
3703 
3704 
3705 static void
get_ix_double(const void * xp,double * ip)3706 get_ix_double(const void *xp, double *ip)
3707 {
3708 	struct vax_double *const vdp =
3709 			 (struct vax_double *)ip;
3710 	const struct ieee_double *const idp =
3711 			 (const struct ieee_double *) xp;
3712 	{
3713 		const struct dbl_limits *lim;
3714 		int ii;
3715 		for (ii = 0, lim = dbl_limits;
3716 			ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
3717 			ii++, lim++)
3718 		{
3719 			if ((idp->mant_lo == lim->ieee.mant_lo)
3720 				&& (idp->mant_4 == lim->ieee.mant_4)
3721 				&& (idp->mant_5 == lim->ieee.mant_5)
3722 				&& (idp->mant_6 == lim->ieee.mant_6)
3723 				&& (idp->exp_lo == lim->ieee.exp_lo)
3724 				&& (idp->exp_hi == lim->ieee.exp_hi)
3725 				)
3726 			{
3727 				*vdp = lim->d;
3728 				goto doneit;
3729 			}
3730 		}
3731 	}
3732 	{
3733 		unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
3734 		vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
3735 	}
3736 	{
3737 		unsigned mant_hi = ((idp->mant_6 << 16)
3738 				 | (idp->mant_5 << 8)
3739 				 | idp->mant_4);
3740 		unsigned mant_lo = SWAP4(idp->mant_lo);
3741 		vdp->mantissa1 = (mant_hi >> 13);
3742 		vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
3743 				| (mant_lo >> 29);
3744 		vdp->mantissa3 = (mant_lo >> 13);
3745 		vdp->mantissa4 = (mant_lo << 3);
3746 	}
3747 	doneit:
3748 		vdp->sign = idp->sign;
3749 
3750 }
3751 
3752 
3753 static void
put_ix_double(void * xp,const double * ip)3754 put_ix_double(void *xp, const double *ip)
3755 {
3756 	const struct vax_double *const vdp =
3757 			(const struct vax_double *)ip;
3758 	struct ieee_double *const idp =
3759 			 (struct ieee_double *) xp;
3760 
3761 	if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
3762 		(vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
3763 		(vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
3764 		(vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
3765 		(vdp->exp == dbl_limits[0].d.exp))
3766 	{
3767 		*idp = dbl_limits[0].ieee;
3768 		goto shipit;
3769 	}
3770 	if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
3771 		(vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
3772 		(vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
3773 		(vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
3774 		(vdp->exp == dbl_limits[1].d.exp))
3775 	{
3776 		*idp = dbl_limits[1].ieee;
3777 		goto shipit;
3778 	}
3779 
3780 	{
3781 		unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
3782 
3783 		unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
3784 			(vdp->mantissa3 << 13) |
3785 			((vdp->mantissa4 >> 3) & MASK(13));
3786 
3787 		unsigned mant_hi = (vdp->mantissa1 << 13)
3788 				 | (vdp->mantissa2 >> 3);
3789 
3790 		if ((vdp->mantissa4 & 7) > 4)
3791 		{
3792 			/* round up */
3793 			mant_lo++;
3794 			if (mant_lo == 0)
3795 			{
3796 				mant_hi++;
3797 				if (mant_hi > 0xffffff)
3798 				{
3799 					mant_hi = 0;
3800 					exp++;
3801 				}
3802 			}
3803 		}
3804 
3805 		idp->mant_lo = SWAP4(mant_lo);
3806 		idp->mant_6 = mant_hi >> 16;
3807 		idp->mant_5 = (mant_hi & 0xff00) >> 8;
3808 		idp->mant_4 = mant_hi;
3809 		idp->exp_hi = exp >> 4;
3810 		idp->exp_lo = exp;
3811 	}
3812 
3813 	shipit:
3814 		idp->sign = vdp->sign;
3815 
3816 }
3817 
3818 	/* vax */
3819 #elif defined(_CRAY) && !defined(__crayx1)
3820 
3821 static void
get_ix_double(const void * xp,double * ip)3822 get_ix_double(const void *xp, double *ip)
3823 {
3824 	const ieee_double *idp = (const ieee_double *) xp;
3825 	cray_single *csp = (cray_single *) ip;
3826 
3827 	if (idp->exp == 0)
3828 	{
3829 		/* ieee subnormal */
3830 		*ip = (double)idp->mant;
3831 		if (idp->mant != 0)
3832 		{
3833 			csp->exp -= (ieee_double_bias + 51);
3834 		}
3835 	}
3836 	else
3837 	{
3838 		csp->exp  = idp->exp + cs_id_bias + 1;
3839 		csp->mant = idp->mant >> (52 - 48 + 1);
3840 		csp->mant |= (1 << (48 - 1));
3841 	}
3842 	csp->sign = idp->sign;
3843 }
3844 
3845 static void
put_ix_double(void * xp,const double * ip)3846 put_ix_double(void *xp, const double *ip)
3847 {
3848 	ieee_double *idp = (ieee_double *) xp;
3849 	const cray_single *csp = (const cray_single *) ip;
3850 
3851 	int ieee_exp = csp->exp - cs_id_bias -1;
3852 
3853 	idp->sign = csp->sign;
3854 
3855 	if (ieee_exp >= 0x7ff)
3856 	{
3857 		/* NC_ERANGE => ieee Inf */
3858 		idp->exp = 0x7ff;
3859 		idp->mant = 0x0;
3860 	}
3861 	else if (ieee_exp > 0)
3862 	{
3863 		/* normal ieee representation */
3864 		idp->exp  = ieee_exp;
3865 		/* assumes cray rep is in normal form */
3866 		assert(csp->mant & 0x800000000000);
3867 		idp->mant = (((csp->mant << 1) &
3868 				0xffffffffffff) << (52 - 48));
3869 	}
3870 	else if (ieee_exp >= (-(52 -48)))
3871 	{
3872 		/* ieee subnormal, left shift */
3873 		const int lshift = (52 - 48) + ieee_exp;
3874 		idp->mant = csp->mant << lshift;
3875 		idp->exp  = 0;
3876 	}
3877 	else if (ieee_exp >= -52)
3878 	{
3879 		/* ieee subnormal, right shift */
3880 		const int rshift = (- (52 - 48) - ieee_exp);
3881 
3882 		idp->mant = csp->mant >> rshift;
3883 
3884 #if 0
3885 		if (csp->mant & (1 << (rshift -1)))
3886 		{
3887 			/* round up */
3888 			idp->mant++;
3889 		}
3890 #endif
3891 
3892 		idp->exp  = 0;
3893 	}
3894 	else
3895 	{
3896 		/* smaller than ieee can represent */
3897 		idp->exp = 0;
3898 		idp->mant = 0;
3899 	}
3900 }
3901 #else
3902 #error "ix_double implementation"
3903 #endif
3904 
3905 #define ix_double double
3906 
3907 static int
ncx_get_double_schar(const void * xp,schar * ip)3908 ncx_get_double_schar(const void *xp, schar *ip)
3909 {
3910 	ix_double xx;
3911 	get_ix_double(xp, &xx);
3912 	if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
3913 #ifdef ERANGE_FILL
3914             *ip = NC_FILL_BYTE;
3915 #endif
3916             return NC_ERANGE;
3917         }
3918 	*ip = (schar)xx;
3919 	return NC_NOERR;
3920 }
3921 
3922 static int
ncx_get_double_short(const void * xp,short * ip)3923 ncx_get_double_short(const void *xp, short *ip)
3924 {
3925 	ix_double xx;
3926 	get_ix_double(xp, &xx);
3927 	if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
3928 #ifdef ERANGE_FILL
3929             *ip = NC_FILL_SHORT;
3930 #endif
3931             return NC_ERANGE;
3932         }
3933 	*ip = (short)xx;
3934 	return NC_NOERR;
3935 }
3936 
3937 static int
ncx_get_double_int(const void * xp,int * ip)3938 ncx_get_double_int(const void *xp, int *ip)
3939 {
3940 	ix_double xx;
3941 	get_ix_double(xp, &xx);
3942 	if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
3943 #ifdef ERANGE_FILL
3944             *ip = NC_FILL_INT;
3945 #endif
3946             return NC_ERANGE;
3947         }
3948 	*ip = (int)xx;
3949 	return NC_NOERR;
3950 }
3951 
3952 static int
ncx_get_double_long(const void * xp,long * ip)3953 ncx_get_double_long(const void *xp, long *ip)
3954 {
3955 	ix_double xx;
3956 	get_ix_double(xp, &xx);
3957 	if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
3958 #ifdef ERANGE_FILL
3959             *ip = NC_FILL_INT;
3960 #endif
3961             return NC_ERANGE;
3962         }
3963 	*ip = (long)xx;
3964 	return NC_NOERR;
3965 }
3966 
3967 static int
ncx_get_double_longlong(const void * xp,longlong * ip)3968 ncx_get_double_longlong(const void *xp, longlong *ip)
3969 {
3970 	ix_double xx;
3971 	get_ix_double(xp, &xx);
3972 	if (xx == LONGLONG_MAX)      *ip = LONGLONG_MAX;
3973 	else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
3974 	else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
3975 #ifdef ERANGE_FILL
3976             *ip = NC_FILL_INT64;
3977 #endif
3978             return NC_ERANGE;
3979         }
3980 	else *ip = (longlong)xx;
3981 	return NC_NOERR;
3982 }
3983 
3984 static int
ncx_get_double_uchar(const void * xp,uchar * ip)3985 ncx_get_double_uchar(const void *xp, uchar *ip)
3986 {
3987 	ix_double xx;
3988 	get_ix_double(xp, &xx);
3989 	if (xx > (double)UCHAR_MAX || xx < 0) {
3990 #ifdef ERANGE_FILL
3991             *ip = NC_FILL_UBYTE;
3992 #endif
3993             return NC_ERANGE;
3994         }
3995 	*ip = (uchar)xx;
3996 	return NC_NOERR;
3997 }
3998 
3999 static int
ncx_get_double_ushort(const void * xp,ushort * ip)4000 ncx_get_double_ushort(const void *xp, ushort *ip)
4001 {
4002 	ix_double xx;
4003 	get_ix_double(xp, &xx);
4004 	if (xx > (double)USHORT_MAX || xx < 0) {
4005 #ifdef ERANGE_FILL
4006             *ip = NC_FILL_USHORT;
4007 #endif
4008             return NC_ERANGE;
4009         }
4010 	*ip = (ushort)xx;
4011 	return NC_NOERR;
4012 }
4013 
4014 static int
ncx_get_double_uint(const void * xp,uint * ip)4015 ncx_get_double_uint(const void *xp, uint *ip)
4016 {
4017 	ix_double xx;
4018 	get_ix_double(xp, &xx);
4019 	if (xx > (double)UINT_MAX || xx < 0) {
4020 #ifdef ERANGE_FILL
4021             *ip = NC_FILL_UINT;
4022 #endif
4023             return NC_ERANGE;
4024         }
4025 	*ip = (uint)xx;
4026 	return NC_NOERR;
4027 }
4028 
4029 static int
ncx_get_double_ulonglong(const void * xp,ulonglong * ip)4030 ncx_get_double_ulonglong(const void *xp, ulonglong *ip)
4031 {
4032 	ix_double xx;
4033 	get_ix_double(xp, &xx);
4034 	if (xx == ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
4035 	else if (xx > (double)ULONGLONG_MAX || xx < 0) {
4036 #ifdef ERANGE_FILL
4037             *ip = NC_FILL_UINT64;
4038 #endif
4039             return NC_ERANGE;
4040         }
4041 	else *ip = (ulonglong)xx;
4042 	return NC_NOERR;
4043 }
4044 
4045 
4046 static int
ncx_get_double_float(const void * xp,float * ip)4047 ncx_get_double_float(const void *xp, float *ip)
4048 {
4049     double xx;
4050     get_ix_double(xp, &xx);
4051     if (xx > FLT_MAX) {
4052 #ifdef ERANGE_FILL
4053         *ip = NC_FILL_FLOAT;
4054 #else
4055         *ip = FLT_MAX;
4056 #endif
4057         return NC_ERANGE;
4058     }
4059     if (xx < (-FLT_MAX)) {
4060 #ifdef ERANGE_FILL
4061         *ip = NC_FILL_FLOAT;
4062 #else
4063         *ip = (-FLT_MAX);
4064 #endif
4065         return NC_ERANGE;
4066     }
4067     *ip = (float) xx;
4068     return NC_NOERR;
4069 }
4070 
4071 #if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4072 static int
ncx_get_double_double(const void * xp,double * ip,void * fillp)4073 ncx_get_double_double(const void *xp, double *ip, void *fillp)
4074 {
4075 	/* TODO */
4076 	get_ix_double(xp, ip);
4077 	return NC_NOERR;
4078 }
4079 #endif
4080 
4081 static int
ncx_put_double_schar(void * xp,const schar * ip,void * fillp)4082 ncx_put_double_schar(void *xp, const schar *ip, void *fillp)
4083 {
4084     int err=NC_NOERR;
4085     ix_double xx = NC_FILL_DOUBLE;
4086 
4087 
4088         xx = (ix_double)*ip;
4089 
4090     put_ix_double(xp, &xx);
4091     return err;
4092 }
4093 
4094 static int
ncx_put_double_uchar(void * xp,const uchar * ip,void * fillp)4095 ncx_put_double_uchar(void *xp, const uchar *ip, void *fillp)
4096 {
4097     int err=NC_NOERR;
4098     ix_double xx = NC_FILL_DOUBLE;
4099 
4100 
4101         xx = (ix_double)*ip;
4102 
4103     put_ix_double(xp, &xx);
4104     return err;
4105 }
4106 
4107 static int
ncx_put_double_short(void * xp,const short * ip,void * fillp)4108 ncx_put_double_short(void *xp, const short *ip, void *fillp)
4109 {
4110     int err=NC_NOERR;
4111     ix_double xx = NC_FILL_DOUBLE;
4112 
4113 
4114         xx = (ix_double)*ip;
4115 
4116     put_ix_double(xp, &xx);
4117     return err;
4118 }
4119 
4120 static int
ncx_put_double_ushort(void * xp,const ushort * ip,void * fillp)4121 ncx_put_double_ushort(void *xp, const ushort *ip, void *fillp)
4122 {
4123     int err=NC_NOERR;
4124     ix_double xx = NC_FILL_DOUBLE;
4125 
4126 
4127         xx = (ix_double)*ip;
4128 
4129     put_ix_double(xp, &xx);
4130     return err;
4131 }
4132 
4133 static int
ncx_put_double_int(void * xp,const int * ip,void * fillp)4134 ncx_put_double_int(void *xp, const int *ip, void *fillp)
4135 {
4136     int err=NC_NOERR;
4137     ix_double xx = NC_FILL_DOUBLE;
4138 
4139 
4140         xx = (ix_double)*ip;
4141 
4142     put_ix_double(xp, &xx);
4143     return err;
4144 }
4145 
4146 static int
ncx_put_double_long(void * xp,const long * ip,void * fillp)4147 ncx_put_double_long(void *xp, const long *ip, void *fillp)
4148 {
4149     int err=NC_NOERR;
4150     ix_double xx = NC_FILL_DOUBLE;
4151 
4152 
4153         xx = (ix_double)*ip;
4154 
4155     put_ix_double(xp, &xx);
4156     return err;
4157 }
4158 
4159 static int
ncx_put_double_uint(void * xp,const uint * ip,void * fillp)4160 ncx_put_double_uint(void *xp, const uint *ip, void *fillp)
4161 {
4162     int err=NC_NOERR;
4163     ix_double xx = NC_FILL_DOUBLE;
4164 
4165 
4166         xx = (ix_double)*ip;
4167 
4168     put_ix_double(xp, &xx);
4169     return err;
4170 }
4171 
4172 static int
ncx_put_double_longlong(void * xp,const longlong * ip,void * fillp)4173 ncx_put_double_longlong(void *xp, const longlong *ip, void *fillp)
4174 {
4175     int err=NC_NOERR;
4176     ix_double xx = NC_FILL_DOUBLE;
4177 
4178 
4179         xx = (ix_double)*ip;
4180 
4181     put_ix_double(xp, &xx);
4182     return err;
4183 }
4184 
4185 static int
ncx_put_double_ulonglong(void * xp,const ulonglong * ip,void * fillp)4186 ncx_put_double_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4187 {
4188     int err=NC_NOERR;
4189     ix_double xx = NC_FILL_DOUBLE;
4190 
4191 
4192         xx = (ix_double)*ip;
4193 
4194     put_ix_double(xp, &xx);
4195     return err;
4196 }
4197 
4198 
4199 static int
ncx_put_double_float(void * xp,const float * ip,void * fillp)4200 ncx_put_double_float(void *xp, const float *ip, void *fillp)
4201 {
4202     int err=NC_NOERR;
4203     double xx = NC_FILL_DOUBLE;
4204 #if 1	/* TODO: figure this out (if condition below will never be true)*/
4205     if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
4206 
4207 #ifdef ERANGE_FILL
4208             if (fillp != NULL) memcpy(&xx, fillp, 8);
4209 #endif
4210         err = NC_ERANGE;
4211     }
4212 #ifdef ERANGE_FILL
4213     else
4214 #endif
4215 #endif
4216         xx = (double) *ip;
4217 
4218     put_ix_double(xp, &xx);
4219     return err;
4220 }
4221 
4222 #if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
4223 static int
ncx_put_double_double(void * xp,const double * ip,void * fillp)4224 ncx_put_double_double(void *xp, const double *ip, void *fillp)
4225 {
4226     int err=NC_NOERR;
4227     double *_ip = ip;
4228 #ifdef NO_IEEE_FLOAT
4229 #ifdef ERANGE_FILL
4230     double tmp=NC_FILL_DOUBLE;
4231 #endif
4232     if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
4233 
4234 #ifdef ERANGE_FILL
4235             if (fillp != NULL) memcpy(&tmp, fillp, 8);
4236 #endif
4237 #ifdef ERANGE_FILL
4238         _ip = &tmp;
4239 #endif
4240         err = NC_ERANGE;
4241     }
4242 #endif
4243     put_ix_double(xp, _ip);
4244     return err;
4245 }
4246 #endif
4247 
4248 
4249 /* external NC_INT64 --------------------------------------------------------*/
4250 
4251 #if SHORT_MAX == X_INT64_MAX
4252 typedef short ix_int64;
4253 #define SIZEOF_IX_INT64 SIZEOF_SHORT
4254 #define IX_INT64_MAX SHORT_MAX
4255 #elif LONG_LONG_MAX  >= X_INT64_MAX
4256 typedef longlong ix_int64;
4257 #define SIZEOF_IX_INT64 SIZEOF_LONGLONG
4258 #define IX_INT64_MAX LONG_LONG_MAX
4259 #elif LONG_MAX  >= X_INT64_MAX
4260 typedef long ix_int64;
4261 #define SIZEOF_IX_INT64 SIZEOF_LONG
4262 #define IX_INT64_MAX LONG_MAX
4263 #else
4264 #error "ix_int64 implementation"
4265 #endif
4266 
4267 
4268 static void
get_ix_int64(const void * xp,ix_int64 * ip)4269 get_ix_int64(const void *xp, ix_int64 *ip)
4270 {
4271     const uchar *cp = (const uchar *) xp;
4272 
4273     *ip  = ((ix_int64)(*cp++) << 56);
4274     *ip |= ((ix_int64)(*cp++) << 48);
4275     *ip |= ((ix_int64)(*cp++) << 40);
4276     *ip |= ((ix_int64)(*cp++) << 32);
4277     *ip |= ((ix_int64)(*cp++) << 24);
4278     *ip |= ((ix_int64)(*cp++) << 16);
4279     *ip |= ((ix_int64)(*cp++) <<  8);
4280     *ip |=  (ix_int64)*cp;
4281 }
4282 
4283 static void
put_ix_int64(void * xp,const ix_int64 * ip)4284 put_ix_int64(void *xp, const ix_int64 *ip)
4285 {
4286     uchar *cp = (uchar *) xp;
4287 
4288     *cp++ = (uchar)((*ip) >> 56);
4289     *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48);
4290     *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40);
4291     *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32);
4292     *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24);
4293     *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16);
4294     *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >>  8);
4295     *cp   = (uchar)( (*ip) & 0x00000000000000ffLL);
4296 }
4297 
4298 #if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4299 static int
ncx_get_longlong_longlong(const void * xp,longlong * ip)4300 ncx_get_longlong_longlong(const void *xp, longlong *ip)
4301 {
4302     int err=NC_NOERR;
4303 #if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4304     get_ix_int64(xp, (ix_int64 *)ip);
4305 #else
4306     ix_int64 xx;
4307     get_ix_int64(xp, &xx);
4308 
4309 #if IX_INT64_MAX > LONGLONG_MAX
4310     if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
4311 #ifdef ERANGE_FILL
4312         *ip = NC_FILL_INT64;
4313         return NC_ERANGE;
4314 #else
4315         err = NC_ERANGE;
4316 #endif
4317     }
4318 #endif
4319 
4320 
4321     *ip = (longlong) xx;
4322 #endif
4323     return err;
4324 }
4325 
4326 #endif
4327 static int
ncx_get_longlong_schar(const void * xp,schar * ip)4328 ncx_get_longlong_schar(const void *xp, schar *ip)
4329 {
4330     int err=NC_NOERR;
4331     ix_int64 xx;
4332     get_ix_int64(xp, &xx);
4333 
4334 #if IX_INT64_MAX > SCHAR_MAX
4335     if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
4336 #ifdef ERANGE_FILL
4337         *ip = NC_FILL_BYTE;
4338         return NC_ERANGE;
4339 #else
4340         err = NC_ERANGE;
4341 #endif
4342     }
4343 #endif
4344 
4345 
4346     *ip = (schar) xx;
4347     return err;
4348 }
4349 
4350 static int
ncx_get_longlong_short(const void * xp,short * ip)4351 ncx_get_longlong_short(const void *xp, short *ip)
4352 {
4353     int err=NC_NOERR;
4354 #if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4355     get_ix_int64(xp, (ix_int64 *)ip);
4356 #else
4357     ix_int64 xx;
4358     get_ix_int64(xp, &xx);
4359 
4360 #if IX_INT64_MAX > SHORT_MAX
4361     if (xx > SHORT_MAX || xx < SHORT_MIN) {
4362 #ifdef ERANGE_FILL
4363         *ip = NC_FILL_SHORT;
4364         return NC_ERANGE;
4365 #else
4366         err = NC_ERANGE;
4367 #endif
4368     }
4369 #endif
4370 
4371 
4372     *ip = (short) xx;
4373 #endif
4374     return err;
4375 }
4376 
4377 static int
ncx_get_longlong_int(const void * xp,int * ip)4378 ncx_get_longlong_int(const void *xp, int *ip)
4379 {
4380     int err=NC_NOERR;
4381 #if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4382     get_ix_int64(xp, (ix_int64 *)ip);
4383 #else
4384     ix_int64 xx;
4385     get_ix_int64(xp, &xx);
4386 
4387 #if IX_INT64_MAX > INT_MAX
4388     if (xx > INT_MAX || xx < INT_MIN) {
4389 #ifdef ERANGE_FILL
4390         *ip = NC_FILL_INT;
4391         return NC_ERANGE;
4392 #else
4393         err = NC_ERANGE;
4394 #endif
4395     }
4396 #endif
4397 
4398 
4399     *ip = (int) xx;
4400 #endif
4401     return err;
4402 }
4403 
4404 static int
ncx_get_longlong_long(const void * xp,long * ip)4405 ncx_get_longlong_long(const void *xp, long *ip)
4406 {
4407     int err=NC_NOERR;
4408 #if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4409     get_ix_int64(xp, (ix_int64 *)ip);
4410 #else
4411     ix_int64 xx;
4412     get_ix_int64(xp, &xx);
4413 
4414 #if IX_INT64_MAX > LONG_MAX
4415     if (xx > LONG_MAX || xx < LONG_MIN) {
4416 #ifdef ERANGE_FILL
4417         *ip = NC_FILL_INT;
4418         return NC_ERANGE;
4419 #else
4420         err = NC_ERANGE;
4421 #endif
4422     }
4423 #endif
4424 
4425 
4426     *ip = (long) xx;
4427 #endif
4428     return err;
4429 }
4430 
4431 static int
ncx_get_longlong_ushort(const void * xp,ushort * ip)4432 ncx_get_longlong_ushort(const void *xp, ushort *ip)
4433 {
4434     int err=NC_NOERR;
4435     ix_int64 xx;
4436     get_ix_int64(xp, &xx);
4437 
4438 #if IX_INT64_MAX > USHORT_MAX
4439     if (xx > USHORT_MAX) {
4440 #ifdef ERANGE_FILL
4441         *ip = NC_FILL_USHORT;
4442         return NC_ERANGE;
4443 #else
4444         err = NC_ERANGE;
4445 #endif
4446     }
4447 #endif
4448 
4449     if (xx < 0) {
4450 #ifdef ERANGE_FILL
4451         *ip = NC_FILL_USHORT;
4452         return NC_ERANGE;
4453 #else
4454         err = NC_ERANGE; /* because ip is unsigned */
4455 #endif
4456     }
4457     *ip = (ushort) xx;
4458     return err;
4459 }
4460 
4461 static int
ncx_get_longlong_uchar(const void * xp,uchar * ip)4462 ncx_get_longlong_uchar(const void *xp, uchar *ip)
4463 {
4464     int err=NC_NOERR;
4465     ix_int64 xx;
4466     get_ix_int64(xp, &xx);
4467 
4468 #if IX_INT64_MAX > UCHAR_MAX
4469     if (xx > UCHAR_MAX) {
4470 #ifdef ERANGE_FILL
4471         *ip = NC_FILL_UBYTE;
4472         return NC_ERANGE;
4473 #else
4474         err = NC_ERANGE;
4475 #endif
4476     }
4477 #endif
4478 
4479     if (xx < 0) {
4480 #ifdef ERANGE_FILL
4481         *ip = NC_FILL_UBYTE;
4482         return NC_ERANGE;
4483 #else
4484         err = NC_ERANGE; /* because ip is unsigned */
4485 #endif
4486     }
4487     *ip = (uchar) xx;
4488     return err;
4489 }
4490 
4491 static int
ncx_get_longlong_uint(const void * xp,uint * ip)4492 ncx_get_longlong_uint(const void *xp, uint *ip)
4493 {
4494     int err=NC_NOERR;
4495     ix_int64 xx;
4496     get_ix_int64(xp, &xx);
4497 
4498 #if IX_INT64_MAX > UINT_MAX
4499     if (xx > UINT_MAX) {
4500 #ifdef ERANGE_FILL
4501         *ip = NC_FILL_UINT;
4502         return NC_ERANGE;
4503 #else
4504         err = NC_ERANGE;
4505 #endif
4506     }
4507 #endif
4508 
4509     if (xx < 0) {
4510 #ifdef ERANGE_FILL
4511         *ip = NC_FILL_UINT;
4512         return NC_ERANGE;
4513 #else
4514         err = NC_ERANGE; /* because ip is unsigned */
4515 #endif
4516     }
4517     *ip = (uint) xx;
4518     return err;
4519 }
4520 
4521 static int
ncx_get_longlong_ulonglong(const void * xp,ulonglong * ip)4522 ncx_get_longlong_ulonglong(const void *xp, ulonglong *ip)
4523 {
4524     int err=NC_NOERR;
4525     ix_int64 xx;
4526     get_ix_int64(xp, &xx);
4527 
4528 #if IX_INT64_MAX > ULONGLONG_MAX
4529     if (xx > ULONGLONG_MAX) {
4530 #ifdef ERANGE_FILL
4531         *ip = NC_FILL_UINT64;
4532         return NC_ERANGE;
4533 #else
4534         err = NC_ERANGE;
4535 #endif
4536     }
4537 #endif
4538 
4539     if (xx < 0) {
4540 #ifdef ERANGE_FILL
4541         *ip = NC_FILL_UINT64;
4542         return NC_ERANGE;
4543 #else
4544         err = NC_ERANGE; /* because ip is unsigned */
4545 #endif
4546     }
4547     *ip = (ulonglong) xx;
4548     return err;
4549 }
4550 
4551 static int
ncx_get_longlong_float(const void * xp,float * ip)4552 ncx_get_longlong_float(const void *xp, float *ip)
4553 {
4554 	ix_int64 xx;
4555 	get_ix_int64(xp, &xx);
4556 	*ip = (float)xx;
4557 	return NC_NOERR;
4558 }
4559 
4560 static int
ncx_get_longlong_double(const void * xp,double * ip)4561 ncx_get_longlong_double(const void *xp, double *ip)
4562 {
4563 	ix_int64 xx;
4564 	get_ix_int64(xp, &xx);
4565 	*ip = (double)xx;
4566 	return NC_NOERR;
4567 }
4568 
4569 
4570 #if X_SIZEOF_INT64 != SIZEOF_LONGLONG
4571 static int
ncx_put_longlong_longlong(void * xp,const longlong * ip,void * fillp)4572 ncx_put_longlong_longlong(void *xp, const longlong *ip, void *fillp)
4573 {
4574     int err=NC_NOERR;
4575 #if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
4576     put_ix_int64(xp, (const ix_int64 *)ip);
4577 #else
4578     ix_int64 xx = NC_FILL_INT64;
4579 
4580 #if IX_INT64_MAX < LONGLONG_MAX
4581     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4582 
4583 #ifdef ERANGE_FILL
4584             if (fillp != NULL) memcpy(&xx, fillp, 8);
4585 #endif
4586         err = NC_ERANGE;
4587     }
4588 #ifdef ERANGE_FILL
4589     else
4590 #endif
4591 #endif
4592         xx = (ix_int64)*ip;
4593 
4594     put_ix_int64(xp, &xx);
4595 #endif
4596     return err;
4597 }
4598 
4599 #endif
4600 static int
ncx_put_longlong_schar(void * xp,const schar * ip,void * fillp)4601 ncx_put_longlong_schar(void *xp, const schar *ip, void *fillp)
4602 {
4603     int err=NC_NOERR;
4604     ix_int64 xx = NC_FILL_INT64;
4605 
4606 #if IX_INT64_MAX < SCHAR_MAX
4607     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4608 
4609 #ifdef ERANGE_FILL
4610             if (fillp != NULL) memcpy(&xx, fillp, 8);
4611 #endif
4612         err = NC_ERANGE;
4613     }
4614 #ifdef ERANGE_FILL
4615     else
4616 #endif
4617 #endif
4618         xx = (ix_int64)*ip;
4619 
4620     put_ix_int64(xp, &xx);
4621     return err;
4622 }
4623 
4624 static int
ncx_put_longlong_short(void * xp,const short * ip,void * fillp)4625 ncx_put_longlong_short(void *xp, const short *ip, void *fillp)
4626 {
4627     int err=NC_NOERR;
4628 #if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
4629     put_ix_int64(xp, (const ix_int64 *)ip);
4630 #else
4631     ix_int64 xx = NC_FILL_INT64;
4632 
4633 #if IX_INT64_MAX < SHORT_MAX
4634     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4635 
4636 #ifdef ERANGE_FILL
4637             if (fillp != NULL) memcpy(&xx, fillp, 8);
4638 #endif
4639         err = NC_ERANGE;
4640     }
4641 #ifdef ERANGE_FILL
4642     else
4643 #endif
4644 #endif
4645         xx = (ix_int64)*ip;
4646 
4647     put_ix_int64(xp, &xx);
4648 #endif
4649     return err;
4650 }
4651 
4652 static int
ncx_put_longlong_int(void * xp,const int * ip,void * fillp)4653 ncx_put_longlong_int(void *xp, const int *ip, void *fillp)
4654 {
4655     int err=NC_NOERR;
4656 #if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
4657     put_ix_int64(xp, (const ix_int64 *)ip);
4658 #else
4659     ix_int64 xx = NC_FILL_INT64;
4660 
4661 #if IX_INT64_MAX < INT_MAX
4662     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4663 
4664 #ifdef ERANGE_FILL
4665             if (fillp != NULL) memcpy(&xx, fillp, 8);
4666 #endif
4667         err = NC_ERANGE;
4668     }
4669 #ifdef ERANGE_FILL
4670     else
4671 #endif
4672 #endif
4673         xx = (ix_int64)*ip;
4674 
4675     put_ix_int64(xp, &xx);
4676 #endif
4677     return err;
4678 }
4679 
4680 static int
ncx_put_longlong_long(void * xp,const long * ip,void * fillp)4681 ncx_put_longlong_long(void *xp, const long *ip, void *fillp)
4682 {
4683     int err=NC_NOERR;
4684 #if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
4685     put_ix_int64(xp, (const ix_int64 *)ip);
4686 #else
4687     ix_int64 xx = NC_FILL_INT64;
4688 
4689 #if IX_INT64_MAX < LONG_MAX
4690     if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
4691 
4692 #ifdef ERANGE_FILL
4693             if (fillp != NULL) memcpy(&xx, fillp, 8);
4694 #endif
4695         err = NC_ERANGE;
4696     }
4697 #ifdef ERANGE_FILL
4698     else
4699 #endif
4700 #endif
4701         xx = (ix_int64)*ip;
4702 
4703     put_ix_int64(xp, &xx);
4704 #endif
4705     return err;
4706 }
4707 
4708 static int
ncx_put_longlong_ushort(void * xp,const ushort * ip,void * fillp)4709 ncx_put_longlong_ushort(void *xp, const ushort *ip, void *fillp)
4710 {
4711     int err=NC_NOERR;
4712     ix_int64 xx = NC_FILL_INT64;
4713 
4714 #if IX_INT64_MAX < USHORT_MAX
4715     if (*ip > IX_INT64_MAX) {
4716 
4717 #ifdef ERANGE_FILL
4718             if (fillp != NULL) memcpy(&xx, fillp, 8);
4719 #endif
4720         err = NC_ERANGE;
4721     }
4722 #ifdef ERANGE_FILL
4723     else
4724 #endif
4725 #endif
4726         xx = (ix_int64)*ip;
4727 
4728     put_ix_int64(xp, &xx);
4729     return err;
4730 }
4731 
4732 static int
ncx_put_longlong_uchar(void * xp,const uchar * ip,void * fillp)4733 ncx_put_longlong_uchar(void *xp, const uchar *ip, void *fillp)
4734 {
4735     int err=NC_NOERR;
4736     ix_int64 xx = NC_FILL_INT64;
4737 
4738 #if IX_INT64_MAX < UCHAR_MAX
4739     if (*ip > IX_INT64_MAX) {
4740 
4741 #ifdef ERANGE_FILL
4742             if (fillp != NULL) memcpy(&xx, fillp, 8);
4743 #endif
4744         err = NC_ERANGE;
4745     }
4746 #ifdef ERANGE_FILL
4747     else
4748 #endif
4749 #endif
4750         xx = (ix_int64)*ip;
4751 
4752     put_ix_int64(xp, &xx);
4753     return err;
4754 }
4755 
4756 static int
ncx_put_longlong_uint(void * xp,const uint * ip,void * fillp)4757 ncx_put_longlong_uint(void *xp, const uint *ip, void *fillp)
4758 {
4759     int err=NC_NOERR;
4760     ix_int64 xx = NC_FILL_INT64;
4761 
4762 #if IX_INT64_MAX < UINT_MAX
4763     if (*ip > IX_INT64_MAX) {
4764 
4765 #ifdef ERANGE_FILL
4766             if (fillp != NULL) memcpy(&xx, fillp, 8);
4767 #endif
4768         err = NC_ERANGE;
4769     }
4770 #ifdef ERANGE_FILL
4771     else
4772 #endif
4773 #endif
4774         xx = (ix_int64)*ip;
4775 
4776     put_ix_int64(xp, &xx);
4777     return err;
4778 }
4779 
4780 static int
ncx_put_longlong_ulonglong(void * xp,const ulonglong * ip,void * fillp)4781 ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
4782 {
4783     int err=NC_NOERR;
4784     ix_int64 xx = NC_FILL_INT64;
4785 
4786 #if IX_INT64_MAX < ULONGLONG_MAX
4787     if (*ip > IX_INT64_MAX) {
4788 
4789 #ifdef ERANGE_FILL
4790             if (fillp != NULL) memcpy(&xx, fillp, 8);
4791 #endif
4792         err = NC_ERANGE;
4793     }
4794 #ifdef ERANGE_FILL
4795     else
4796 #endif
4797 #endif
4798         xx = (ix_int64)*ip;
4799 
4800     put_ix_int64(xp, &xx);
4801     return err;
4802 }
4803 
4804 static int
ncx_put_longlong_float(void * xp,const float * ip,void * fillp)4805 ncx_put_longlong_float(void *xp, const float *ip, void *fillp)
4806 {
4807     int err=NC_NOERR;
4808     ix_int64 xx = NC_FILL_INT64;
4809 
4810     if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
4811 
4812 #ifdef ERANGE_FILL
4813             if (fillp != NULL) memcpy(&xx, fillp, 8);
4814 #endif
4815         err = NC_ERANGE;
4816     }
4817 #ifdef ERANGE_FILL
4818     else
4819 #endif
4820         xx = (ix_int64)*ip;
4821 
4822     put_ix_int64(xp, &xx);
4823     return err;
4824 }
4825 
4826 static int
ncx_put_longlong_double(void * xp,const double * ip,void * fillp)4827 ncx_put_longlong_double(void *xp, const double *ip, void *fillp)
4828 {
4829     int err=NC_NOERR;
4830     ix_int64 xx = NC_FILL_INT64;
4831 
4832     if (*ip > X_INT64_MAX || *ip < X_INT64_MIN) {
4833 
4834 #ifdef ERANGE_FILL
4835             if (fillp != NULL) memcpy(&xx, fillp, 8);
4836 #endif
4837         err = NC_ERANGE;
4838     }
4839 #ifdef ERANGE_FILL
4840     else
4841 #endif
4842         xx = (ix_int64)*ip;
4843 
4844     put_ix_int64(xp, &xx);
4845     return err;
4846 }
4847 
4848 
4849 
4850 /* external NC_UINT64 -------------------------------------------------------*/
4851 
4852 #if USHORT_MAX == X_UINT64_MAX
4853 typedef ushort ix_uint64;
4854 #define SIZEOF_IX_UINT64 SIZEOF_USHORT
4855 #define IX_UINT64_MAX USHORT_MAX
4856 #elif ULONG_LONG_MAX  >= X_UINT64_MAX
4857 typedef ulonglong ix_uint64;
4858 #define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
4859 #define IX_UINT64_MAX ULONG_LONG_MAX
4860 #elif ULONG_MAX  >= X_UINT64_MAX
4861 typedef ulong ix_uint64;
4862 #define SIZEOF_IX_UINT64 SIZEOF_ULONG
4863 #define IX_UINT64_MAX ULONG_MAX
4864 #else
4865 #error "ix_uint64 implementation"
4866 #endif
4867 
4868 
4869 static void
get_ix_uint64(const void * xp,ix_uint64 * ip)4870 get_ix_uint64(const void *xp, ix_uint64 *ip)
4871 {
4872     const uchar *cp = (const uchar *) xp;
4873 
4874     *ip  = ((ix_uint64)(*cp++) << 56);
4875     *ip |= ((ix_uint64)(*cp++) << 48);
4876     *ip |= ((ix_uint64)(*cp++) << 40);
4877     *ip |= ((ix_uint64)(*cp++) << 32);
4878     *ip |= ((ix_uint64)(*cp++) << 24);
4879     *ip |= ((ix_uint64)(*cp++) << 16);
4880     *ip |= ((ix_uint64)(*cp++) <<  8);
4881     *ip |=  (ix_uint64)*cp;
4882 }
4883 
4884 static void
put_ix_uint64(void * xp,const ix_uint64 * ip)4885 put_ix_uint64(void *xp, const ix_uint64 *ip)
4886 {
4887     uchar *cp = (uchar *) xp;
4888 
4889     *cp++ = (uchar)((*ip) >> 56);
4890     *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48);
4891     *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40);
4892     *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32);
4893     *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24);
4894     *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16);
4895     *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >>  8);
4896     *cp   = (uchar)( (*ip) & 0x00000000000000ffULL);
4897 }
4898 
4899 #if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
4900 static int
ncx_get_ulonglong_ulonglong(const void * xp,ulonglong * ip)4901 ncx_get_ulonglong_ulonglong(const void *xp, ulonglong *ip)
4902 {
4903     int err=NC_NOERR;
4904 #if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
4905     get_ix_uint64(xp, (ix_uint64 *)ip);
4906 #else
4907     ix_uint64 xx;
4908     get_ix_uint64(xp, &xx);
4909 
4910 #if IX_UINT64_MAX > ULONGLONG_MAX
4911     if (xx > ULONGLONG_MAX) {
4912 #ifdef ERANGE_FILL
4913         *ip = NC_FILL_UINT64;
4914         return NC_ERANGE;
4915 #else
4916         err = NC_ERANGE;
4917 #endif
4918     }
4919 #endif
4920 
4921 
4922     *ip = (ulonglong) xx;
4923 #endif
4924     return err;
4925 }
4926 
4927 #endif
4928 static int
ncx_get_ulonglong_schar(const void * xp,schar * ip)4929 ncx_get_ulonglong_schar(const void *xp, schar *ip)
4930 {
4931     int err=NC_NOERR;
4932     ix_uint64 xx;
4933     get_ix_uint64(xp, &xx);
4934 
4935 #if IX_UINT64_MAX > SCHAR_MAX
4936     if (xx > SCHAR_MAX) {
4937 #ifdef ERANGE_FILL
4938         *ip = NC_FILL_BYTE;
4939         return NC_ERANGE;
4940 #else
4941         err = NC_ERANGE;
4942 #endif
4943     }
4944 #endif
4945 
4946 
4947     *ip = (schar) xx;
4948     return err;
4949 }
4950 
4951 static int
ncx_get_ulonglong_short(const void * xp,short * ip)4952 ncx_get_ulonglong_short(const void *xp, short *ip)
4953 {
4954     int err=NC_NOERR;
4955     ix_uint64 xx;
4956     get_ix_uint64(xp, &xx);
4957 
4958 #if IX_UINT64_MAX > SHORT_MAX
4959     if (xx > SHORT_MAX) {
4960 #ifdef ERANGE_FILL
4961         *ip = NC_FILL_SHORT;
4962         return NC_ERANGE;
4963 #else
4964         err = NC_ERANGE;
4965 #endif
4966     }
4967 #endif
4968 
4969 
4970     *ip = (short) xx;
4971     return err;
4972 }
4973 
4974 static int
ncx_get_ulonglong_int(const void * xp,int * ip)4975 ncx_get_ulonglong_int(const void *xp, int *ip)
4976 {
4977     int err=NC_NOERR;
4978     ix_uint64 xx;
4979     get_ix_uint64(xp, &xx);
4980 
4981 #if IX_UINT64_MAX > INT_MAX
4982     if (xx > INT_MAX) {
4983 #ifdef ERANGE_FILL
4984         *ip = NC_FILL_INT;
4985         return NC_ERANGE;
4986 #else
4987         err = NC_ERANGE;
4988 #endif
4989     }
4990 #endif
4991 
4992 
4993     *ip = (int) xx;
4994     return err;
4995 }
4996 
4997 static int
ncx_get_ulonglong_long(const void * xp,long * ip)4998 ncx_get_ulonglong_long(const void *xp, long *ip)
4999 {
5000     int err=NC_NOERR;
5001     ix_uint64 xx;
5002     get_ix_uint64(xp, &xx);
5003 
5004 #if IX_UINT64_MAX > LONG_MAX
5005     if (xx > LONG_MAX) {
5006 #ifdef ERANGE_FILL
5007         *ip = NC_FILL_INT;
5008         return NC_ERANGE;
5009 #else
5010         err = NC_ERANGE;
5011 #endif
5012     }
5013 #endif
5014 
5015 
5016     *ip = (long) xx;
5017     return err;
5018 }
5019 
5020 static int
ncx_get_ulonglong_longlong(const void * xp,longlong * ip)5021 ncx_get_ulonglong_longlong(const void *xp, longlong *ip)
5022 {
5023     int err=NC_NOERR;
5024     ix_uint64 xx;
5025     get_ix_uint64(xp, &xx);
5026 
5027 #if IX_UINT64_MAX > LONGLONG_MAX
5028     if (xx > LONGLONG_MAX) {
5029 #ifdef ERANGE_FILL
5030         *ip = NC_FILL_INT64;
5031         return NC_ERANGE;
5032 #else
5033         err = NC_ERANGE;
5034 #endif
5035     }
5036 #endif
5037 
5038 
5039     *ip = (longlong) xx;
5040     return err;
5041 }
5042 
5043 static int
ncx_get_ulonglong_ushort(const void * xp,ushort * ip)5044 ncx_get_ulonglong_ushort(const void *xp, ushort *ip)
5045 {
5046     int err=NC_NOERR;
5047 #if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5048     get_ix_uint64(xp, (ix_uint64 *)ip);
5049 #else
5050     ix_uint64 xx;
5051     get_ix_uint64(xp, &xx);
5052 
5053 #if IX_UINT64_MAX > USHORT_MAX
5054     if (xx > USHORT_MAX) {
5055 #ifdef ERANGE_FILL
5056         *ip = NC_FILL_USHORT;
5057         return NC_ERANGE;
5058 #else
5059         err = NC_ERANGE;
5060 #endif
5061     }
5062 #endif
5063 
5064 
5065     *ip = (ushort) xx;
5066 #endif
5067     return err;
5068 }
5069 
5070 static int
ncx_get_ulonglong_uchar(const void * xp,uchar * ip)5071 ncx_get_ulonglong_uchar(const void *xp, uchar *ip)
5072 {
5073     int err=NC_NOERR;
5074 #if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5075     get_ix_uint64(xp, (ix_uint64 *)ip);
5076 #else
5077     ix_uint64 xx;
5078     get_ix_uint64(xp, &xx);
5079 
5080 #if IX_UINT64_MAX > UCHAR_MAX
5081     if (xx > UCHAR_MAX) {
5082 #ifdef ERANGE_FILL
5083         *ip = NC_FILL_UBYTE;
5084         return NC_ERANGE;
5085 #else
5086         err = NC_ERANGE;
5087 #endif
5088     }
5089 #endif
5090 
5091 
5092     *ip = (uchar) xx;
5093 #endif
5094     return err;
5095 }
5096 
5097 static int
ncx_get_ulonglong_uint(const void * xp,uint * ip)5098 ncx_get_ulonglong_uint(const void *xp, uint *ip)
5099 {
5100     int err=NC_NOERR;
5101 #if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5102     get_ix_uint64(xp, (ix_uint64 *)ip);
5103 #else
5104     ix_uint64 xx;
5105     get_ix_uint64(xp, &xx);
5106 
5107 #if IX_UINT64_MAX > UINT_MAX
5108     if (xx > UINT_MAX) {
5109 #ifdef ERANGE_FILL
5110         *ip = NC_FILL_UINT;
5111         return NC_ERANGE;
5112 #else
5113         err = NC_ERANGE;
5114 #endif
5115     }
5116 #endif
5117 
5118 
5119     *ip = (uint) xx;
5120 #endif
5121     return err;
5122 }
5123 
5124 static int
ncx_get_ulonglong_float(const void * xp,float * ip)5125 ncx_get_ulonglong_float(const void *xp, float *ip)
5126 {
5127 	ix_uint64 xx;
5128 	get_ix_uint64(xp, &xx);
5129 	*ip = (float)xx;
5130 	return NC_NOERR;
5131 }
5132 
5133 static int
ncx_get_ulonglong_double(const void * xp,double * ip)5134 ncx_get_ulonglong_double(const void *xp, double *ip)
5135 {
5136 	ix_uint64 xx;
5137 	get_ix_uint64(xp, &xx);
5138 	*ip = (double)xx;
5139 	return NC_NOERR;
5140 }
5141 
5142 
5143 #if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
5144 static int
ncx_put_ulonglong_ulonglong(void * xp,const ulonglong * ip,void * fillp)5145 ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip, void *fillp)
5146 {
5147     int err=NC_NOERR;
5148 #if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
5149     put_ix_uint64(xp, (const ix_uint64 *)ip);
5150 #else
5151     ix_uint64 xx = NC_FILL_UINT64;
5152 
5153 #if IX_UINT64_MAX < ULONGLONG_MAX
5154     if (*ip > IX_UINT64_MAX) {
5155 
5156 #ifdef ERANGE_FILL
5157             if (fillp != NULL) memcpy(&xx, fillp, 8);
5158 #endif
5159         err = NC_ERANGE;
5160     }
5161 #ifdef ERANGE_FILL
5162     else
5163 #endif
5164 #endif
5165         xx = (ix_uint64)*ip;
5166 
5167     put_ix_uint64(xp, &xx);
5168 #endif
5169     return err;
5170 }
5171 
5172 #endif
5173 static int
ncx_put_ulonglong_schar(void * xp,const schar * ip,void * fillp)5174 ncx_put_ulonglong_schar(void *xp, const schar *ip, void *fillp)
5175 {
5176     int err=NC_NOERR;
5177     ix_uint64 xx = NC_FILL_UINT64;
5178 
5179 #if IX_UINT64_MAX < SCHAR_MAX
5180     if (*ip > IX_UINT64_MAX) {
5181 
5182 #ifdef ERANGE_FILL
5183             if (fillp != NULL) memcpy(&xx, fillp, 8);
5184 #endif
5185         err = NC_ERANGE;
5186     }
5187 #ifdef ERANGE_FILL
5188     else
5189 #endif
5190 #endif
5191     if (*ip < 0) {
5192 
5193 #ifdef ERANGE_FILL
5194             if (fillp != NULL) memcpy(&xx, fillp, 8);
5195 #endif
5196         err = NC_ERANGE; /* because xp is unsigned */
5197     }
5198 #ifdef ERANGE_FILL
5199     else
5200 #endif
5201         xx = (ix_uint64)*ip;
5202 
5203     put_ix_uint64(xp, &xx);
5204     return err;
5205 }
5206 
5207 static int
ncx_put_ulonglong_short(void * xp,const short * ip,void * fillp)5208 ncx_put_ulonglong_short(void *xp, const short *ip, void *fillp)
5209 {
5210     int err=NC_NOERR;
5211     ix_uint64 xx = NC_FILL_UINT64;
5212 
5213 #if IX_UINT64_MAX < SHORT_MAX
5214     if (*ip > IX_UINT64_MAX) {
5215 
5216 #ifdef ERANGE_FILL
5217             if (fillp != NULL) memcpy(&xx, fillp, 8);
5218 #endif
5219         err = NC_ERANGE;
5220     }
5221 #ifdef ERANGE_FILL
5222     else
5223 #endif
5224 #endif
5225     if (*ip < 0) {
5226 
5227 #ifdef ERANGE_FILL
5228             if (fillp != NULL) memcpy(&xx, fillp, 8);
5229 #endif
5230         err = NC_ERANGE; /* because xp is unsigned */
5231     }
5232 #ifdef ERANGE_FILL
5233     else
5234 #endif
5235         xx = (ix_uint64)*ip;
5236 
5237     put_ix_uint64(xp, &xx);
5238     return err;
5239 }
5240 
5241 static int
ncx_put_ulonglong_int(void * xp,const int * ip,void * fillp)5242 ncx_put_ulonglong_int(void *xp, const int *ip, void *fillp)
5243 {
5244     int err=NC_NOERR;
5245     ix_uint64 xx = NC_FILL_UINT64;
5246 
5247 #if IX_UINT64_MAX < INT_MAX
5248     if (*ip > IX_UINT64_MAX) {
5249 
5250 #ifdef ERANGE_FILL
5251             if (fillp != NULL) memcpy(&xx, fillp, 8);
5252 #endif
5253         err = NC_ERANGE;
5254     }
5255 #ifdef ERANGE_FILL
5256     else
5257 #endif
5258 #endif
5259     if (*ip < 0) {
5260 
5261 #ifdef ERANGE_FILL
5262             if (fillp != NULL) memcpy(&xx, fillp, 8);
5263 #endif
5264         err = NC_ERANGE; /* because xp is unsigned */
5265     }
5266 #ifdef ERANGE_FILL
5267     else
5268 #endif
5269         xx = (ix_uint64)*ip;
5270 
5271     put_ix_uint64(xp, &xx);
5272     return err;
5273 }
5274 
5275 static int
ncx_put_ulonglong_long(void * xp,const long * ip,void * fillp)5276 ncx_put_ulonglong_long(void *xp, const long *ip, void *fillp)
5277 {
5278     int err=NC_NOERR;
5279     ix_uint64 xx = NC_FILL_UINT64;
5280 
5281 #if IX_UINT64_MAX < LONG_MAX
5282     if (*ip > IX_UINT64_MAX) {
5283 
5284 #ifdef ERANGE_FILL
5285             if (fillp != NULL) memcpy(&xx, fillp, 8);
5286 #endif
5287         err = NC_ERANGE;
5288     }
5289 #ifdef ERANGE_FILL
5290     else
5291 #endif
5292 #endif
5293     if (*ip < 0) {
5294 
5295 #ifdef ERANGE_FILL
5296             if (fillp != NULL) memcpy(&xx, fillp, 8);
5297 #endif
5298         err = NC_ERANGE; /* because xp is unsigned */
5299     }
5300 #ifdef ERANGE_FILL
5301     else
5302 #endif
5303         xx = (ix_uint64)*ip;
5304 
5305     put_ix_uint64(xp, &xx);
5306     return err;
5307 }
5308 
5309 static int
ncx_put_ulonglong_longlong(void * xp,const longlong * ip,void * fillp)5310 ncx_put_ulonglong_longlong(void *xp, const longlong *ip, void *fillp)
5311 {
5312     int err=NC_NOERR;
5313     ix_uint64 xx = NC_FILL_UINT64;
5314 
5315 #if IX_UINT64_MAX < LONGLONG_MAX
5316     if (*ip > IX_UINT64_MAX) {
5317 
5318 #ifdef ERANGE_FILL
5319             if (fillp != NULL) memcpy(&xx, fillp, 8);
5320 #endif
5321         err = NC_ERANGE;
5322     }
5323 #ifdef ERANGE_FILL
5324     else
5325 #endif
5326 #endif
5327     if (*ip < 0) {
5328 
5329 #ifdef ERANGE_FILL
5330             if (fillp != NULL) memcpy(&xx, fillp, 8);
5331 #endif
5332         err = NC_ERANGE; /* because xp is unsigned */
5333     }
5334 #ifdef ERANGE_FILL
5335     else
5336 #endif
5337         xx = (ix_uint64)*ip;
5338 
5339     put_ix_uint64(xp, &xx);
5340     return err;
5341 }
5342 
5343 static int
ncx_put_ulonglong_uchar(void * xp,const uchar * ip,void * fillp)5344 ncx_put_ulonglong_uchar(void *xp, const uchar *ip, void *fillp)
5345 {
5346     int err=NC_NOERR;
5347 #if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
5348     put_ix_uint64(xp, (const ix_uint64 *)ip);
5349 #else
5350     ix_uint64 xx = NC_FILL_UINT64;
5351 
5352 #if IX_UINT64_MAX < UCHAR_MAX
5353     if (*ip > IX_UINT64_MAX) {
5354 
5355 #ifdef ERANGE_FILL
5356             if (fillp != NULL) memcpy(&xx, fillp, 8);
5357 #endif
5358         err = NC_ERANGE;
5359     }
5360 #ifdef ERANGE_FILL
5361     else
5362 #endif
5363 #endif
5364         xx = (ix_uint64)*ip;
5365 
5366     put_ix_uint64(xp, &xx);
5367 #endif
5368     return err;
5369 }
5370 
5371 static int
ncx_put_ulonglong_ushort(void * xp,const ushort * ip,void * fillp)5372 ncx_put_ulonglong_ushort(void *xp, const ushort *ip, void *fillp)
5373 {
5374     int err=NC_NOERR;
5375 #if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
5376     put_ix_uint64(xp, (const ix_uint64 *)ip);
5377 #else
5378     ix_uint64 xx = NC_FILL_UINT64;
5379 
5380 #if IX_UINT64_MAX < USHORT_MAX
5381     if (*ip > IX_UINT64_MAX) {
5382 
5383 #ifdef ERANGE_FILL
5384             if (fillp != NULL) memcpy(&xx, fillp, 8);
5385 #endif
5386         err = NC_ERANGE;
5387     }
5388 #ifdef ERANGE_FILL
5389     else
5390 #endif
5391 #endif
5392         xx = (ix_uint64)*ip;
5393 
5394     put_ix_uint64(xp, &xx);
5395 #endif
5396     return err;
5397 }
5398 
5399 static int
ncx_put_ulonglong_uint(void * xp,const uint * ip,void * fillp)5400 ncx_put_ulonglong_uint(void *xp, const uint *ip, void *fillp)
5401 {
5402     int err=NC_NOERR;
5403 #if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
5404     put_ix_uint64(xp, (const ix_uint64 *)ip);
5405 #else
5406     ix_uint64 xx = NC_FILL_UINT64;
5407 
5408 #if IX_UINT64_MAX < UINT_MAX
5409     if (*ip > IX_UINT64_MAX) {
5410 
5411 #ifdef ERANGE_FILL
5412             if (fillp != NULL) memcpy(&xx, fillp, 8);
5413 #endif
5414         err = NC_ERANGE;
5415     }
5416 #ifdef ERANGE_FILL
5417     else
5418 #endif
5419 #endif
5420         xx = (ix_uint64)*ip;
5421 
5422     put_ix_uint64(xp, &xx);
5423 #endif
5424     return err;
5425 }
5426 
5427 static int
ncx_put_ulonglong_float(void * xp,const float * ip,void * fillp)5428 ncx_put_ulonglong_float(void *xp, const float *ip, void *fillp)
5429 {
5430     int err=NC_NOERR;
5431     ix_uint64 xx = NC_FILL_UINT64;
5432 
5433     if (*ip > (double)X_UINT64_MAX || *ip < 0) {
5434 
5435 #ifdef ERANGE_FILL
5436             if (fillp != NULL) memcpy(&xx, fillp, 8);
5437 #endif
5438         err = NC_ERANGE;
5439     }
5440 #ifdef ERANGE_FILL
5441     else
5442 #endif
5443         xx = (ix_uint64)*ip;
5444 
5445     put_ix_uint64(xp, &xx);
5446     return err;
5447 }
5448 
5449 static int
ncx_put_ulonglong_double(void * xp,const double * ip,void * fillp)5450 ncx_put_ulonglong_double(void *xp, const double *ip, void *fillp)
5451 {
5452     int err=NC_NOERR;
5453     ix_uint64 xx = NC_FILL_UINT64;
5454 
5455     if (*ip > X_UINT64_MAX || *ip < 0) {
5456 
5457 #ifdef ERANGE_FILL
5458             if (fillp != NULL) memcpy(&xx, fillp, 8);
5459 #endif
5460         err = NC_ERANGE;
5461     }
5462 #ifdef ERANGE_FILL
5463     else
5464 #endif
5465         xx = (ix_uint64)*ip;
5466 
5467     put_ix_uint64(xp, &xx);
5468     return err;
5469 }
5470 
5471 
5472 
5473 /* x_size_t */
5474 
5475 #if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
5476 #error "x_size_t implementation"
5477 /* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
5478 #endif
5479 
5480 int
ncx_put_size_t(void ** xpp,const size_t * ulp)5481 ncx_put_size_t(void **xpp, const size_t *ulp)
5482 {
5483 	/* similar to put_ix_int() */
5484 	uchar *cp = (uchar *) *xpp;
5485 	assert(*ulp <= X_SIZE_MAX);
5486 
5487 	*cp++ = (uchar)((*ulp) >> 24);
5488 	*cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
5489 	*cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
5490 	*cp   = (uchar)((*ulp) & 0x000000ff);
5491 
5492 	*xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
5493 	return NC_NOERR;
5494 }
5495 
5496 int
ncx_get_size_t(const void ** xpp,size_t * ulp)5497 ncx_get_size_t(const void **xpp,  size_t *ulp)
5498 {
5499 	/* similar to get_ix_int */
5500 	const uchar *cp = (const uchar *) *xpp;
5501 
5502 	*ulp  = (unsigned)(*cp++) << 24;
5503 	*ulp |= (*cp++ << 16);
5504 	*ulp |= (*cp++ << 8);
5505 	*ulp |= *cp;
5506 
5507 	*xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
5508 	return NC_NOERR;
5509 }
5510 
5511 /* x_off_t */
5512 
5513 int
ncx_put_off_t(void ** xpp,const off_t * lp,size_t sizeof_off_t)5514 ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
5515 {
5516 	/* No negative offsets stored in netcdf */
5517 	if (*lp < 0) {
5518 	  /* Assume this is an overflow of a 32-bit int... */
5519 	  return NC_ERANGE;
5520 	}
5521 
5522 	assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5523 
5524 	/* similar to put_ix_int() */
5525 	uchar *cp = (uchar *) *xpp;
5526 
5527 	if (sizeof_off_t == 4) {
5528 		*cp++ = (uchar) ((*lp)               >> 24);
5529 		*cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5530 		*cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5531 		*cp   = (uchar)( (*lp) & 0x000000ff);
5532 	} else {
5533 #if SIZEOF_OFF_T == 4
5534 /* Write a 64-bit offset on a system with only a 32-bit offset */
5535 		*cp++ = (uchar)0;
5536 		*cp++ = (uchar)0;
5537 		*cp++ = (uchar)0;
5538 		*cp++ = (uchar)0;
5539 
5540 		*cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
5541 		*cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
5542 		*cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
5543 		*cp   = (uchar)( (*lp) & 0x000000ff);
5544 #else
5545 		*cp++ = (uchar) ((*lp)                          >> 56);
5546 		*cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48);
5547 		*cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40);
5548 		*cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32);
5549 		*cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24);
5550 		*cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16);
5551 		*cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >>  8);
5552 		*cp   = (uchar)( (*lp) & 0x00000000000000ffLL);
5553 #endif
5554 	}
5555 	*xpp = (void *)((char *)(*xpp) + sizeof_off_t);
5556 	return NC_NOERR;
5557 }
5558 
5559 int
ncx_get_off_t(const void ** xpp,off_t * lp,size_t sizeof_off_t)5560 ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
5561 {
5562 	/* similar to get_ix_int() */
5563 	const uchar *cp = (const uchar *) *xpp;
5564 	assert(sizeof_off_t == 4 || sizeof_off_t == 8);
5565 
5566  	if (sizeof_off_t == 4) {
5567 		*lp =  (off_t)(*cp++ << 24);
5568 		*lp |= (off_t)(*cp++ << 16);
5569 		*lp |= (off_t)(*cp++ <<  8);
5570 		*lp |= (off_t)*cp;
5571 	} else {
5572 #if SIZEOF_OFF_T == 4
5573 /* Read a 64-bit offset on a system with only a 32-bit offset */
5574 /* If the offset overflows, set an error code and return */
5575 		*lp =  ((off_t)(*cp++) << 24);
5576 		*lp |= ((off_t)(*cp++) << 16);
5577 		*lp |= ((off_t)(*cp++) <<  8);
5578 		*lp |= ((off_t)(*cp++));
5579 /*
5580  * lp now contains the upper 32-bits of the 64-bit offset.  if lp is
5581  * not zero, then the dataset is larger than can be represented
5582  * on this system.  Set an error code and return.
5583  */
5584 		if (*lp != 0) {
5585 		  return NC_ERANGE;
5586 		}
5587 
5588 		*lp  = ((off_t)(*cp++) << 24);
5589 		*lp |= ((off_t)(*cp++) << 16);
5590 		*lp |= ((off_t)(*cp++) <<  8);
5591 		*lp |=  (off_t)*cp;
5592 
5593 		if (*lp < 0) {
5594 		  /*
5595 		   * If this fails, then the offset is >2^31, but less
5596 		   * than 2^32 which is not allowed, but is not caught
5597 		   * by the previous check
5598 		   */
5599 		  return NC_ERANGE;
5600 		}
5601 #else
5602 		*lp =  ((off_t)(*cp++) << 56);
5603 		*lp |= ((off_t)(*cp++) << 48);
5604 		*lp |= ((off_t)(*cp++) << 40);
5605 		*lp |= ((off_t)(*cp++) << 32);
5606 		*lp |= ((off_t)(*cp++) << 24);
5607 		*lp |= ((off_t)(*cp++) << 16);
5608 		*lp |= ((off_t)(*cp++) <<  8);
5609 		*lp |=  (off_t)*cp;
5610 #endif
5611 	}
5612 	*xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
5613 	return NC_NOERR;
5614 }
5615 
5616 /*----< ncx_get_uint32() >------------------------------------------*/
5617 int
ncx_get_uint32(const void ** xpp,uint * ip)5618 ncx_get_uint32(const void **xpp, uint *ip)
5619 {
5620 #ifdef WORDS_BIGENDIAN
5621     /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5622      * some system, such as HPUX */
5623     (void) memcpy(ip, *xpp, SIZEOF_UINT);
5624 #else
5625     const uchar *cp = (const uchar *) *xpp;
5626 
5627     *ip = (uint)(*cp++ << 24);
5628     *ip = (uint)(*ip | (uint)(*cp++ << 16));
5629     *ip = (uint)(*ip | (uint)(*cp++ <<  8));
5630     *ip = (uint)(*ip | *cp);
5631 #endif
5632     /* advance *xpp 4 bytes */
5633     *xpp = (void *)((const char *)(*xpp) + 4);
5634 
5635     return NC_NOERR;
5636 }
5637 
5638 /*----< ncx_get_uint64() >------------------------------------------*/
5639 int
ncx_get_uint64(const void ** xpp,unsigned long long * ullp)5640 ncx_get_uint64(const void **xpp, unsigned long long *ullp)
5641 {
5642 #ifdef WORDS_BIGENDIAN
5643     /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5644      * some system, such as HPUX */
5645     (void) memcpy(ullp, *xpp, SIZEOF_UINT64);
5646 #else
5647     const uchar *cp = (const uchar *) *xpp;
5648 
5649     /* below is the same as calling swap8b(ullp, *xpp) */
5650     *ullp = (unsigned long long)(*cp++) << 56;
5651     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48);
5652     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40);
5653     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32);
5654     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24);
5655     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16);
5656     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) <<  8);
5657     *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp));
5658 #endif
5659     /* advance *xpp 8 bytes */
5660     *xpp = (void *)((const char *)(*xpp) + 8);
5661 
5662     return NC_NOERR;
5663 }
5664 
5665 /*---< ncx_put_uint32() >-------------------------------------------*/
5666 /* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
5667  * form and advance *xpp 4 bytes
5668  */
5669 int
ncx_put_uint32(void ** xpp,const unsigned int ip)5670 ncx_put_uint32(void **xpp, const unsigned int ip)
5671 {
5672 #ifdef WORDS_BIGENDIAN
5673     /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5674      * some system, such as HPUX */
5675     (void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
5676 #else
5677     /* bitwise shifts below are to produce an integer in Big Endian */
5678     uchar *cp = (uchar *) *xpp;
5679     *cp++ = (uchar)((ip & 0xff000000) >> 24);
5680     *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
5681     *cp++ = (uchar)((ip & 0x0000ff00) >>  8);
5682     *cp   = (uchar)( ip & 0x000000ff);
5683 #endif
5684     /* advance *xpp 4 bytes */
5685     *xpp  = (void *)((char *)(*xpp) + 4);
5686 
5687     return NC_NOERR;
5688 }
5689 
5690 /*---< ncx_put_uint64() >-------------------------------------------*/
5691 /* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
5692  * form and advance *xpp 8 bytes
5693  */
5694 int
ncx_put_uint64(void ** xpp,const unsigned long long ip)5695 ncx_put_uint64(void **xpp, const unsigned long long ip)
5696 {
5697 #ifdef WORDS_BIGENDIAN
5698     /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
5699      * some system, such as HPUX */
5700     (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
5701 #else
5702     uchar *cp = (uchar *) *xpp;
5703     /* below is the same as calling swap8b(*xpp, &ip) */
5704     *cp++ = (uchar) (ip                         >> 56);
5705     *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48);
5706     *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40);
5707     *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32);
5708     *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24);
5709     *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16);
5710     *cp++ = (uchar)((ip & 0x000000000000ff00LL) >>  8);
5711     *cp   = (uchar) (ip & 0x00000000000000ffLL);
5712 #endif
5713     /* advance *xpp 8 bytes */
5714     *xpp  = (void *)((char *)(*xpp) + 8);
5715 
5716     return NC_NOERR;
5717 }
5718 
5719 
5720 /*
5721  * Aggregate numeric conversion functions.
5722  */
5723 
5724 
5725 
5726 /* schar ---------------------------------------------------------------------*/
5727 
5728 int
ncx_getn_schar_schar(const void ** xpp,size_t nelems,schar * tp)5729 ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5730 {
5731 		(void) memcpy(tp, *xpp, (size_t)nelems);
5732 	*xpp = (void *)((char *)(*xpp) + nelems);
5733 	return NC_NOERR;
5734 
5735 }
5736 int
ncx_getn_schar_uchar(const void ** xpp,size_t nelems,uchar * tp)5737 ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5738 {
5739     int status = NC_NOERR;
5740     schar *xp = (schar *)(*xpp);
5741 
5742     while (nelems-- != 0) {
5743 
5744         if (*xp < 0) {
5745 #ifdef ERANGE_FILL
5746             *tp = NC_FILL_UBYTE;
5747 #endif
5748             status = NC_ERANGE; /* because tp is unsigned */
5749 
5750 #ifdef ERANGE_FILL
5751             xp++; tp++; continue;
5752 #endif
5753         }
5754         *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5755     }
5756 
5757     *xpp = (const void *)xp;
5758     return status;
5759 }
5760 
5761 int
ncx_getn_schar_short(const void ** xpp,size_t nelems,short * tp)5762 ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5763 {
5764     int status = NC_NOERR;
5765     schar *xp = (schar *)(*xpp);
5766 
5767     while (nelems-- != 0) {
5768 
5769         *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5770     }
5771 
5772     *xpp = (const void *)xp;
5773     return status;
5774 }
5775 
5776 int
ncx_getn_schar_int(const void ** xpp,size_t nelems,int * tp)5777 ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5778 {
5779     int status = NC_NOERR;
5780     schar *xp = (schar *)(*xpp);
5781 
5782     while (nelems-- != 0) {
5783 
5784         *tp++ = (int)  (*xp++);  /* type cast from schar to int */
5785     }
5786 
5787     *xpp = (const void *)xp;
5788     return status;
5789 }
5790 
5791 int
ncx_getn_schar_long(const void ** xpp,size_t nelems,long * tp)5792 ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
5793 {
5794     int status = NC_NOERR;
5795     schar *xp = (schar *)(*xpp);
5796 
5797     while (nelems-- != 0) {
5798 
5799         *tp++ = (long)  (*xp++);  /* type cast from schar to long */
5800     }
5801 
5802     *xpp = (const void *)xp;
5803     return status;
5804 }
5805 
5806 int
ncx_getn_schar_float(const void ** xpp,size_t nelems,float * tp)5807 ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
5808 {
5809     int status = NC_NOERR;
5810     schar *xp = (schar *)(*xpp);
5811 
5812     while (nelems-- != 0) {
5813 
5814         *tp++ = (float)  (*xp++);  /* type cast from schar to float */
5815     }
5816 
5817     *xpp = (const void *)xp;
5818     return status;
5819 }
5820 
5821 int
ncx_getn_schar_double(const void ** xpp,size_t nelems,double * tp)5822 ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
5823 {
5824     int status = NC_NOERR;
5825     schar *xp = (schar *)(*xpp);
5826 
5827     while (nelems-- != 0) {
5828 
5829         *tp++ = (double)  (*xp++);  /* type cast from schar to double */
5830     }
5831 
5832     *xpp = (const void *)xp;
5833     return status;
5834 }
5835 
5836 int
ncx_getn_schar_longlong(const void ** xpp,size_t nelems,longlong * tp)5837 ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
5838 {
5839     int status = NC_NOERR;
5840     schar *xp = (schar *)(*xpp);
5841 
5842     while (nelems-- != 0) {
5843 
5844         *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
5845     }
5846 
5847     *xpp = (const void *)xp;
5848     return status;
5849 }
5850 
5851 int
ncx_getn_schar_ushort(const void ** xpp,size_t nelems,ushort * tp)5852 ncx_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
5853 {
5854     int status = NC_NOERR;
5855     schar *xp = (schar *)(*xpp);
5856 
5857     while (nelems-- != 0) {
5858 
5859         if (*xp < 0) {
5860 #ifdef ERANGE_FILL
5861             *tp = NC_FILL_USHORT;
5862 #endif
5863             status = NC_ERANGE; /* because tp is unsigned */
5864 
5865 #ifdef ERANGE_FILL
5866             xp++; tp++; continue;
5867 #endif
5868         }
5869         *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
5870     }
5871 
5872     *xpp = (const void *)xp;
5873     return status;
5874 }
5875 
5876 int
ncx_getn_schar_uint(const void ** xpp,size_t nelems,uint * tp)5877 ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
5878 {
5879     int status = NC_NOERR;
5880     schar *xp = (schar *)(*xpp);
5881 
5882     while (nelems-- != 0) {
5883 
5884         if (*xp < 0) {
5885 #ifdef ERANGE_FILL
5886             *tp = NC_FILL_UINT;
5887 #endif
5888             status = NC_ERANGE; /* because tp is unsigned */
5889 
5890 #ifdef ERANGE_FILL
5891             xp++; tp++; continue;
5892 #endif
5893         }
5894         *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
5895     }
5896 
5897     *xpp = (const void *)xp;
5898     return status;
5899 }
5900 
5901 int
ncx_getn_schar_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)5902 ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
5903 {
5904     int status = NC_NOERR;
5905     schar *xp = (schar *)(*xpp);
5906 
5907     while (nelems-- != 0) {
5908 
5909         if (*xp < 0) {
5910 #ifdef ERANGE_FILL
5911             *tp = NC_FILL_UINT64;
5912 #endif
5913             status = NC_ERANGE; /* because tp is unsigned */
5914 
5915 #ifdef ERANGE_FILL
5916             xp++; tp++; continue;
5917 #endif
5918         }
5919         *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
5920     }
5921 
5922     *xpp = (const void *)xp;
5923     return status;
5924 }
5925 
5926 
5927 int
ncx_pad_getn_schar_schar(const void ** xpp,size_t nelems,schar * tp)5928 ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
5929 {
5930 		size_t rndup = nelems % X_ALIGN;
5931 
5932 	if (rndup)
5933 		rndup = X_ALIGN - rndup;
5934 
5935 	(void) memcpy(tp, *xpp, (size_t)nelems);
5936 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
5937 
5938 	return NC_NOERR;
5939 
5940 }
5941 int
ncx_pad_getn_schar_uchar(const void ** xpp,size_t nelems,uchar * tp)5942 ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
5943 {
5944     int status = NC_NOERR;
5945     size_t rndup = nelems % X_ALIGN;
5946     schar *xp = (schar *) *xpp;
5947 
5948     if (rndup)
5949         rndup = X_ALIGN - rndup;
5950 
5951     while (nelems-- != 0) {
5952 
5953         if (*xp < 0) {
5954 #ifdef ERANGE_FILL
5955             *tp = NC_FILL_UBYTE;
5956 #endif
5957             status = NC_ERANGE; /* because tp is unsigned */
5958 
5959 #ifdef ERANGE_FILL
5960             xp++; tp++; continue;
5961 #endif
5962         }
5963         *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
5964     }
5965 
5966     *xpp = (void *)(xp + rndup);
5967     return status;
5968 }
5969 
5970 int
ncx_pad_getn_schar_short(const void ** xpp,size_t nelems,short * tp)5971 ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
5972 {
5973     int status = NC_NOERR;
5974     size_t rndup = nelems % X_ALIGN;
5975     schar *xp = (schar *) *xpp;
5976 
5977     if (rndup)
5978         rndup = X_ALIGN - rndup;
5979 
5980     while (nelems-- != 0) {
5981 
5982         *tp++ = (short)  (*xp++);  /* type cast from schar to short */
5983     }
5984 
5985     *xpp = (void *)(xp + rndup);
5986     return status;
5987 }
5988 
5989 int
ncx_pad_getn_schar_int(const void ** xpp,size_t nelems,int * tp)5990 ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
5991 {
5992     int status = NC_NOERR;
5993     size_t rndup = nelems % X_ALIGN;
5994     schar *xp = (schar *) *xpp;
5995 
5996     if (rndup)
5997         rndup = X_ALIGN - rndup;
5998 
5999     while (nelems-- != 0) {
6000 
6001         *tp++ = (int)  (*xp++);  /* type cast from schar to int */
6002     }
6003 
6004     *xpp = (void *)(xp + rndup);
6005     return status;
6006 }
6007 
6008 int
ncx_pad_getn_schar_long(const void ** xpp,size_t nelems,long * tp)6009 ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
6010 {
6011     int status = NC_NOERR;
6012     size_t rndup = nelems % X_ALIGN;
6013     schar *xp = (schar *) *xpp;
6014 
6015     if (rndup)
6016         rndup = X_ALIGN - rndup;
6017 
6018     while (nelems-- != 0) {
6019 
6020         *tp++ = (long)  (*xp++);  /* type cast from schar to long */
6021     }
6022 
6023     *xpp = (void *)(xp + rndup);
6024     return status;
6025 }
6026 
6027 int
ncx_pad_getn_schar_float(const void ** xpp,size_t nelems,float * tp)6028 ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
6029 {
6030     int status = NC_NOERR;
6031     size_t rndup = nelems % X_ALIGN;
6032     schar *xp = (schar *) *xpp;
6033 
6034     if (rndup)
6035         rndup = X_ALIGN - rndup;
6036 
6037     while (nelems-- != 0) {
6038 
6039         *tp++ = (float)  (*xp++);  /* type cast from schar to float */
6040     }
6041 
6042     *xpp = (void *)(xp + rndup);
6043     return status;
6044 }
6045 
6046 int
ncx_pad_getn_schar_double(const void ** xpp,size_t nelems,double * tp)6047 ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
6048 {
6049     int status = NC_NOERR;
6050     size_t rndup = nelems % X_ALIGN;
6051     schar *xp = (schar *) *xpp;
6052 
6053     if (rndup)
6054         rndup = X_ALIGN - rndup;
6055 
6056     while (nelems-- != 0) {
6057 
6058         *tp++ = (double)  (*xp++);  /* type cast from schar to double */
6059     }
6060 
6061     *xpp = (void *)(xp + rndup);
6062     return status;
6063 }
6064 
6065 int
ncx_pad_getn_schar_longlong(const void ** xpp,size_t nelems,longlong * tp)6066 ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp)
6067 {
6068     int status = NC_NOERR;
6069     size_t rndup = nelems % X_ALIGN;
6070     schar *xp = (schar *) *xpp;
6071 
6072     if (rndup)
6073         rndup = X_ALIGN - rndup;
6074 
6075     while (nelems-- != 0) {
6076 
6077         *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
6078     }
6079 
6080     *xpp = (void *)(xp + rndup);
6081     return status;
6082 }
6083 
6084 int
ncx_pad_getn_schar_ushort(const void ** xpp,size_t nelems,ushort * tp)6085 ncx_pad_getn_schar_ushort(const void **xpp, size_t nelems, ushort *tp)
6086 {
6087     int status = NC_NOERR;
6088     size_t rndup = nelems % X_ALIGN;
6089     schar *xp = (schar *) *xpp;
6090 
6091     if (rndup)
6092         rndup = X_ALIGN - rndup;
6093 
6094     while (nelems-- != 0) {
6095 
6096         if (*xp < 0) {
6097 #ifdef ERANGE_FILL
6098             *tp = NC_FILL_USHORT;
6099 #endif
6100             status = NC_ERANGE; /* because tp is unsigned */
6101 
6102 #ifdef ERANGE_FILL
6103             xp++; tp++; continue;
6104 #endif
6105         }
6106         *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
6107     }
6108 
6109     *xpp = (void *)(xp + rndup);
6110     return status;
6111 }
6112 
6113 int
ncx_pad_getn_schar_uint(const void ** xpp,size_t nelems,uint * tp)6114 ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp)
6115 {
6116     int status = NC_NOERR;
6117     size_t rndup = nelems % X_ALIGN;
6118     schar *xp = (schar *) *xpp;
6119 
6120     if (rndup)
6121         rndup = X_ALIGN - rndup;
6122 
6123     while (nelems-- != 0) {
6124 
6125         if (*xp < 0) {
6126 #ifdef ERANGE_FILL
6127             *tp = NC_FILL_UINT;
6128 #endif
6129             status = NC_ERANGE; /* because tp is unsigned */
6130 
6131 #ifdef ERANGE_FILL
6132             xp++; tp++; continue;
6133 #endif
6134         }
6135         *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
6136     }
6137 
6138     *xpp = (void *)(xp + rndup);
6139     return status;
6140 }
6141 
6142 int
ncx_pad_getn_schar_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)6143 ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6144 {
6145     int status = NC_NOERR;
6146     size_t rndup = nelems % X_ALIGN;
6147     schar *xp = (schar *) *xpp;
6148 
6149     if (rndup)
6150         rndup = X_ALIGN - rndup;
6151 
6152     while (nelems-- != 0) {
6153 
6154         if (*xp < 0) {
6155 #ifdef ERANGE_FILL
6156             *tp = NC_FILL_UINT64;
6157 #endif
6158             status = NC_ERANGE; /* because tp is unsigned */
6159 
6160 #ifdef ERANGE_FILL
6161             xp++; tp++; continue;
6162 #endif
6163         }
6164         *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
6165     }
6166 
6167     *xpp = (void *)(xp + rndup);
6168     return status;
6169 }
6170 
6171 
6172 int
ncx_putn_schar_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)6173 ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6174 {
6175 		(void) memcpy(*xpp, tp, (size_t)nelems);
6176 	*xpp = (void *)((char *)(*xpp) + nelems);
6177 
6178 	return NC_NOERR;
6179 
6180 }
6181 int
ncx_putn_schar_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)6182 ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6183 {
6184     int status = NC_NOERR;
6185     schar *xp = (schar *) *xpp;
6186 
6187     while (nelems-- != 0) {
6188         if (*tp > (uchar)X_SCHAR_MAX ) {
6189 
6190 #ifdef ERANGE_FILL
6191             if (fillp != NULL) memcpy(xp, fillp, 1);
6192 #endif
6193             status = NC_ERANGE;
6194 
6195 #ifdef ERANGE_FILL
6196             xp++; tp++; continue;
6197 #endif
6198         }
6199         *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6200     }
6201 
6202     *xpp = (void *)xp;
6203     return status;
6204 }
6205 
6206 int
ncx_putn_schar_short(void ** xpp,size_t nelems,const short * tp,void * fillp)6207 ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6208 {
6209     int status = NC_NOERR;
6210     schar *xp = (schar *) *xpp;
6211 
6212     while (nelems-- != 0) {
6213         if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6214 
6215 #ifdef ERANGE_FILL
6216             if (fillp != NULL) memcpy(xp, fillp, 1);
6217 #endif
6218             status = NC_ERANGE;
6219 
6220 #ifdef ERANGE_FILL
6221             xp++; tp++; continue;
6222 #endif
6223         }
6224         *xp++ = (schar)  *tp++; /* type cast from short to schar */
6225     }
6226 
6227     *xpp = (void *)xp;
6228     return status;
6229 }
6230 
6231 int
ncx_putn_schar_int(void ** xpp,size_t nelems,const int * tp,void * fillp)6232 ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6233 {
6234     int status = NC_NOERR;
6235     schar *xp = (schar *) *xpp;
6236 
6237     while (nelems-- != 0) {
6238         if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6239 
6240 #ifdef ERANGE_FILL
6241             if (fillp != NULL) memcpy(xp, fillp, 1);
6242 #endif
6243             status = NC_ERANGE;
6244 
6245 #ifdef ERANGE_FILL
6246             xp++; tp++; continue;
6247 #endif
6248         }
6249         *xp++ = (schar)  *tp++; /* type cast from int to schar */
6250     }
6251 
6252     *xpp = (void *)xp;
6253     return status;
6254 }
6255 
6256 int
ncx_putn_schar_long(void ** xpp,size_t nelems,const long * tp,void * fillp)6257 ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6258 {
6259     int status = NC_NOERR;
6260     schar *xp = (schar *) *xpp;
6261 
6262     while (nelems-- != 0) {
6263         if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6264 
6265 #ifdef ERANGE_FILL
6266             if (fillp != NULL) memcpy(xp, fillp, 1);
6267 #endif
6268             status = NC_ERANGE;
6269 
6270 #ifdef ERANGE_FILL
6271             xp++; tp++; continue;
6272 #endif
6273         }
6274         *xp++ = (schar)  *tp++; /* type cast from long to schar */
6275     }
6276 
6277     *xpp = (void *)xp;
6278     return status;
6279 }
6280 
6281 int
ncx_putn_schar_float(void ** xpp,size_t nelems,const float * tp,void * fillp)6282 ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6283 {
6284     int status = NC_NOERR;
6285     schar *xp = (schar *) *xpp;
6286 
6287     while (nelems-- != 0) {
6288         if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6289 
6290 #ifdef ERANGE_FILL
6291             if (fillp != NULL) memcpy(xp, fillp, 1);
6292 #endif
6293             status = NC_ERANGE;
6294 
6295 #ifdef ERANGE_FILL
6296             xp++; tp++; continue;
6297 #endif
6298         }
6299         *xp++ = (schar)  *tp++; /* type cast from float to schar */
6300     }
6301 
6302     *xpp = (void *)xp;
6303     return status;
6304 }
6305 
6306 int
ncx_putn_schar_double(void ** xpp,size_t nelems,const double * tp,void * fillp)6307 ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6308 {
6309     int status = NC_NOERR;
6310     schar *xp = (schar *) *xpp;
6311 
6312     while (nelems-- != 0) {
6313         if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6314 
6315 #ifdef ERANGE_FILL
6316             if (fillp != NULL) memcpy(xp, fillp, 1);
6317 #endif
6318             status = NC_ERANGE;
6319 
6320 #ifdef ERANGE_FILL
6321             xp++; tp++; continue;
6322 #endif
6323         }
6324         *xp++ = (schar)  *tp++; /* type cast from double to schar */
6325     }
6326 
6327     *xpp = (void *)xp;
6328     return status;
6329 }
6330 
6331 int
ncx_putn_schar_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)6332 ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6333 {
6334     int status = NC_NOERR;
6335     schar *xp = (schar *) *xpp;
6336 
6337     while (nelems-- != 0) {
6338         if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6339 
6340 #ifdef ERANGE_FILL
6341             if (fillp != NULL) memcpy(xp, fillp, 1);
6342 #endif
6343             status = NC_ERANGE;
6344 
6345 #ifdef ERANGE_FILL
6346             xp++; tp++; continue;
6347 #endif
6348         }
6349         *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6350     }
6351 
6352     *xpp = (void *)xp;
6353     return status;
6354 }
6355 
6356 int
ncx_putn_schar_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)6357 ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6358 {
6359     int status = NC_NOERR;
6360     schar *xp = (schar *) *xpp;
6361 
6362     while (nelems-- != 0) {
6363         if (*tp > (ushort)X_SCHAR_MAX ) {
6364 
6365 #ifdef ERANGE_FILL
6366             if (fillp != NULL) memcpy(xp, fillp, 1);
6367 #endif
6368             status = NC_ERANGE;
6369 
6370 #ifdef ERANGE_FILL
6371             xp++; tp++; continue;
6372 #endif
6373         }
6374         *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6375     }
6376 
6377     *xpp = (void *)xp;
6378     return status;
6379 }
6380 
6381 int
ncx_putn_schar_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)6382 ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6383 {
6384     int status = NC_NOERR;
6385     schar *xp = (schar *) *xpp;
6386 
6387     while (nelems-- != 0) {
6388         if (*tp > (uint)X_SCHAR_MAX ) {
6389 
6390 #ifdef ERANGE_FILL
6391             if (fillp != NULL) memcpy(xp, fillp, 1);
6392 #endif
6393             status = NC_ERANGE;
6394 
6395 #ifdef ERANGE_FILL
6396             xp++; tp++; continue;
6397 #endif
6398         }
6399         *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6400     }
6401 
6402     *xpp = (void *)xp;
6403     return status;
6404 }
6405 
6406 int
ncx_putn_schar_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)6407 ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6408 {
6409     int status = NC_NOERR;
6410     schar *xp = (schar *) *xpp;
6411 
6412     while (nelems-- != 0) {
6413         if (*tp > (ulonglong)X_SCHAR_MAX ) {
6414 
6415 #ifdef ERANGE_FILL
6416             if (fillp != NULL) memcpy(xp, fillp, 1);
6417 #endif
6418             status = NC_ERANGE;
6419 
6420 #ifdef ERANGE_FILL
6421             xp++; tp++; continue;
6422 #endif
6423         }
6424         *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6425     }
6426 
6427     *xpp = (void *)xp;
6428     return status;
6429 }
6430 
6431 
6432 int
ncx_pad_putn_schar_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)6433 ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
6434 {
6435 		size_t rndup = nelems % X_ALIGN;
6436 
6437 	if (rndup)
6438 		rndup = X_ALIGN - rndup;
6439 
6440 	(void) memcpy(*xpp, tp, (size_t)nelems);
6441 	*xpp = (void *)((char *)(*xpp) + nelems);
6442 
6443 	if (rndup)
6444 	{
6445 		(void) memcpy(*xpp, nada, (size_t)rndup);
6446 		*xpp = (void *)((char *)(*xpp) + rndup);
6447 	}
6448 
6449 	return NC_NOERR;
6450 
6451 }
6452 int
ncx_pad_putn_schar_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)6453 ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
6454 {
6455     int status = NC_NOERR;
6456     size_t rndup = nelems % X_ALIGN;
6457     schar *xp = (schar *) *xpp;
6458 
6459     if (rndup) rndup = X_ALIGN - rndup;
6460 
6461     while (nelems-- != 0) {
6462         if (*tp > (uchar)X_SCHAR_MAX ) {
6463 
6464 #ifdef ERANGE_FILL
6465             if (fillp != NULL) memcpy(xp, fillp, 1);
6466 #endif
6467             status = NC_ERANGE;
6468 
6469 #ifdef ERANGE_FILL
6470             xp++; tp++; continue;
6471 #endif
6472         }
6473         *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
6474     }
6475 
6476 
6477     if (rndup) {
6478         (void) memcpy(xp, nada, (size_t)rndup);
6479         xp += rndup;
6480     }
6481 
6482     *xpp = (void *)xp;
6483     return status;
6484 }
6485 
6486 int
ncx_pad_putn_schar_short(void ** xpp,size_t nelems,const short * tp,void * fillp)6487 ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
6488 {
6489     int status = NC_NOERR;
6490     size_t rndup = nelems % X_ALIGN;
6491     schar *xp = (schar *) *xpp;
6492 
6493     if (rndup) rndup = X_ALIGN - rndup;
6494 
6495     while (nelems-- != 0) {
6496         if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6497 
6498 #ifdef ERANGE_FILL
6499             if (fillp != NULL) memcpy(xp, fillp, 1);
6500 #endif
6501             status = NC_ERANGE;
6502 
6503 #ifdef ERANGE_FILL
6504             xp++; tp++; continue;
6505 #endif
6506         }
6507         *xp++ = (schar)  *tp++; /* type cast from short to schar */
6508     }
6509 
6510 
6511     if (rndup) {
6512         (void) memcpy(xp, nada, (size_t)rndup);
6513         xp += rndup;
6514     }
6515 
6516     *xpp = (void *)xp;
6517     return status;
6518 }
6519 
6520 int
ncx_pad_putn_schar_int(void ** xpp,size_t nelems,const int * tp,void * fillp)6521 ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
6522 {
6523     int status = NC_NOERR;
6524     size_t rndup = nelems % X_ALIGN;
6525     schar *xp = (schar *) *xpp;
6526 
6527     if (rndup) rndup = X_ALIGN - rndup;
6528 
6529     while (nelems-- != 0) {
6530         if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6531 
6532 #ifdef ERANGE_FILL
6533             if (fillp != NULL) memcpy(xp, fillp, 1);
6534 #endif
6535             status = NC_ERANGE;
6536 
6537 #ifdef ERANGE_FILL
6538             xp++; tp++; continue;
6539 #endif
6540         }
6541         *xp++ = (schar)  *tp++; /* type cast from int to schar */
6542     }
6543 
6544 
6545     if (rndup) {
6546         (void) memcpy(xp, nada, (size_t)rndup);
6547         xp += rndup;
6548     }
6549 
6550     *xpp = (void *)xp;
6551     return status;
6552 }
6553 
6554 int
ncx_pad_putn_schar_long(void ** xpp,size_t nelems,const long * tp,void * fillp)6555 ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
6556 {
6557     int status = NC_NOERR;
6558     size_t rndup = nelems % X_ALIGN;
6559     schar *xp = (schar *) *xpp;
6560 
6561     if (rndup) rndup = X_ALIGN - rndup;
6562 
6563     while (nelems-- != 0) {
6564         if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6565 
6566 #ifdef ERANGE_FILL
6567             if (fillp != NULL) memcpy(xp, fillp, 1);
6568 #endif
6569             status = NC_ERANGE;
6570 
6571 #ifdef ERANGE_FILL
6572             xp++; tp++; continue;
6573 #endif
6574         }
6575         *xp++ = (schar)  *tp++; /* type cast from long to schar */
6576     }
6577 
6578 
6579     if (rndup) {
6580         (void) memcpy(xp, nada, (size_t)rndup);
6581         xp += rndup;
6582     }
6583 
6584     *xpp = (void *)xp;
6585     return status;
6586 }
6587 
6588 int
ncx_pad_putn_schar_float(void ** xpp,size_t nelems,const float * tp,void * fillp)6589 ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
6590 {
6591     int status = NC_NOERR;
6592     size_t rndup = nelems % X_ALIGN;
6593     schar *xp = (schar *) *xpp;
6594 
6595     if (rndup) rndup = X_ALIGN - rndup;
6596 
6597     while (nelems-- != 0) {
6598         if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6599 
6600 #ifdef ERANGE_FILL
6601             if (fillp != NULL) memcpy(xp, fillp, 1);
6602 #endif
6603             status = NC_ERANGE;
6604 
6605 #ifdef ERANGE_FILL
6606             xp++; tp++; continue;
6607 #endif
6608         }
6609         *xp++ = (schar)  *tp++; /* type cast from float to schar */
6610     }
6611 
6612 
6613     if (rndup) {
6614         (void) memcpy(xp, nada, (size_t)rndup);
6615         xp += rndup;
6616     }
6617 
6618     *xpp = (void *)xp;
6619     return status;
6620 }
6621 
6622 int
ncx_pad_putn_schar_double(void ** xpp,size_t nelems,const double * tp,void * fillp)6623 ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
6624 {
6625     int status = NC_NOERR;
6626     size_t rndup = nelems % X_ALIGN;
6627     schar *xp = (schar *) *xpp;
6628 
6629     if (rndup) rndup = X_ALIGN - rndup;
6630 
6631     while (nelems-- != 0) {
6632         if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6633 
6634 #ifdef ERANGE_FILL
6635             if (fillp != NULL) memcpy(xp, fillp, 1);
6636 #endif
6637             status = NC_ERANGE;
6638 
6639 #ifdef ERANGE_FILL
6640             xp++; tp++; continue;
6641 #endif
6642         }
6643         *xp++ = (schar)  *tp++; /* type cast from double to schar */
6644     }
6645 
6646 
6647     if (rndup) {
6648         (void) memcpy(xp, nada, (size_t)rndup);
6649         xp += rndup;
6650     }
6651 
6652     *xpp = (void *)xp;
6653     return status;
6654 }
6655 
6656 int
ncx_pad_putn_schar_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)6657 ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
6658 {
6659     int status = NC_NOERR;
6660     size_t rndup = nelems % X_ALIGN;
6661     schar *xp = (schar *) *xpp;
6662 
6663     if (rndup) rndup = X_ALIGN - rndup;
6664 
6665     while (nelems-- != 0) {
6666         if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
6667 
6668 #ifdef ERANGE_FILL
6669             if (fillp != NULL) memcpy(xp, fillp, 1);
6670 #endif
6671             status = NC_ERANGE;
6672 
6673 #ifdef ERANGE_FILL
6674             xp++; tp++; continue;
6675 #endif
6676         }
6677         *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
6678     }
6679 
6680 
6681     if (rndup) {
6682         (void) memcpy(xp, nada, (size_t)rndup);
6683         xp += rndup;
6684     }
6685 
6686     *xpp = (void *)xp;
6687     return status;
6688 }
6689 
6690 int
ncx_pad_putn_schar_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)6691 ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
6692 {
6693     int status = NC_NOERR;
6694     size_t rndup = nelems % X_ALIGN;
6695     schar *xp = (schar *) *xpp;
6696 
6697     if (rndup) rndup = X_ALIGN - rndup;
6698 
6699     while (nelems-- != 0) {
6700         if (*tp > (ushort)X_SCHAR_MAX ) {
6701 
6702 #ifdef ERANGE_FILL
6703             if (fillp != NULL) memcpy(xp, fillp, 1);
6704 #endif
6705             status = NC_ERANGE;
6706 
6707 #ifdef ERANGE_FILL
6708             xp++; tp++; continue;
6709 #endif
6710         }
6711         *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
6712     }
6713 
6714 
6715     if (rndup) {
6716         (void) memcpy(xp, nada, (size_t)rndup);
6717         xp += rndup;
6718     }
6719 
6720     *xpp = (void *)xp;
6721     return status;
6722 }
6723 
6724 int
ncx_pad_putn_schar_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)6725 ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
6726 {
6727     int status = NC_NOERR;
6728     size_t rndup = nelems % X_ALIGN;
6729     schar *xp = (schar *) *xpp;
6730 
6731     if (rndup) rndup = X_ALIGN - rndup;
6732 
6733     while (nelems-- != 0) {
6734         if (*tp > (uint)X_SCHAR_MAX ) {
6735 
6736 #ifdef ERANGE_FILL
6737             if (fillp != NULL) memcpy(xp, fillp, 1);
6738 #endif
6739             status = NC_ERANGE;
6740 
6741 #ifdef ERANGE_FILL
6742             xp++; tp++; continue;
6743 #endif
6744         }
6745         *xp++ = (schar)  *tp++; /* type cast from uint to schar */
6746     }
6747 
6748 
6749     if (rndup) {
6750         (void) memcpy(xp, nada, (size_t)rndup);
6751         xp += rndup;
6752     }
6753 
6754     *xpp = (void *)xp;
6755     return status;
6756 }
6757 
6758 int
ncx_pad_putn_schar_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)6759 ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
6760 {
6761     int status = NC_NOERR;
6762     size_t rndup = nelems % X_ALIGN;
6763     schar *xp = (schar *) *xpp;
6764 
6765     if (rndup) rndup = X_ALIGN - rndup;
6766 
6767     while (nelems-- != 0) {
6768         if (*tp > (ulonglong)X_SCHAR_MAX ) {
6769 
6770 #ifdef ERANGE_FILL
6771             if (fillp != NULL) memcpy(xp, fillp, 1);
6772 #endif
6773             status = NC_ERANGE;
6774 
6775 #ifdef ERANGE_FILL
6776             xp++; tp++; continue;
6777 #endif
6778         }
6779         *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
6780     }
6781 
6782 
6783     if (rndup) {
6784         (void) memcpy(xp, nada, (size_t)rndup);
6785         xp += rndup;
6786     }
6787 
6788     *xpp = (void *)xp;
6789     return status;
6790 }
6791 
6792 
6793 
6794 /* uchar ---------------------------------------------------------------------*/
6795 int
ncx_getn_uchar_schar(const void ** xpp,size_t nelems,schar * tp)6796 ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6797 {
6798     int status = NC_NOERR;
6799     uchar *xp = (uchar *)(*xpp);
6800 
6801     while (nelems-- != 0) {
6802         if (*xp > SCHAR_MAX) {
6803             *tp = NC_FILL_BYTE;
6804        	    status = NC_ERANGE;
6805 
6806 #ifdef ERANGE_FILL
6807             xp++; tp++; continue;
6808 #endif
6809         }
6810 	*tp++ = (schar) *xp++; /* type cast from uchar to schar */
6811     }
6812 
6813     *xpp = (const void *)xp;
6814     return status;
6815 }
6816 int
ncx_getn_uchar_uchar(const void ** xpp,size_t nelems,uchar * tp)6817 ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6818 {
6819 		(void) memcpy(tp, *xpp, (size_t)nelems);
6820 	*xpp = (void *)((char *)(*xpp) + nelems);
6821 	return NC_NOERR;
6822 
6823 }
6824 int
ncx_getn_uchar_short(const void ** xpp,size_t nelems,short * tp)6825 ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
6826 {
6827     int status = NC_NOERR;
6828     uchar *xp = (uchar *)(*xpp);
6829 
6830     while (nelems-- != 0) {
6831 
6832         *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
6833     }
6834 
6835     *xpp = (const void *)xp;
6836     return status;
6837 }
6838 
6839 int
ncx_getn_uchar_int(const void ** xpp,size_t nelems,int * tp)6840 ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
6841 {
6842     int status = NC_NOERR;
6843     uchar *xp = (uchar *)(*xpp);
6844 
6845     while (nelems-- != 0) {
6846 
6847         *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
6848     }
6849 
6850     *xpp = (const void *)xp;
6851     return status;
6852 }
6853 
6854 int
ncx_getn_uchar_long(const void ** xpp,size_t nelems,long * tp)6855 ncx_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
6856 {
6857     int status = NC_NOERR;
6858     uchar *xp = (uchar *)(*xpp);
6859 
6860     while (nelems-- != 0) {
6861 
6862         *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
6863     }
6864 
6865     *xpp = (const void *)xp;
6866     return status;
6867 }
6868 
6869 int
ncx_getn_uchar_float(const void ** xpp,size_t nelems,float * tp)6870 ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
6871 {
6872     int status = NC_NOERR;
6873     uchar *xp = (uchar *)(*xpp);
6874 
6875     while (nelems-- != 0) {
6876 
6877         *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
6878     }
6879 
6880     *xpp = (const void *)xp;
6881     return status;
6882 }
6883 
6884 int
ncx_getn_uchar_double(const void ** xpp,size_t nelems,double * tp)6885 ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
6886 {
6887     int status = NC_NOERR;
6888     uchar *xp = (uchar *)(*xpp);
6889 
6890     while (nelems-- != 0) {
6891 
6892         *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
6893     }
6894 
6895     *xpp = (const void *)xp;
6896     return status;
6897 }
6898 
6899 int
ncx_getn_uchar_longlong(const void ** xpp,size_t nelems,longlong * tp)6900 ncx_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
6901 {
6902     int status = NC_NOERR;
6903     uchar *xp = (uchar *)(*xpp);
6904 
6905     while (nelems-- != 0) {
6906 
6907         *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
6908     }
6909 
6910     *xpp = (const void *)xp;
6911     return status;
6912 }
6913 
6914 int
ncx_getn_uchar_ushort(const void ** xpp,size_t nelems,ushort * tp)6915 ncx_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
6916 {
6917     int status = NC_NOERR;
6918     uchar *xp = (uchar *)(*xpp);
6919 
6920     while (nelems-- != 0) {
6921 
6922         *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
6923     }
6924 
6925     *xpp = (const void *)xp;
6926     return status;
6927 }
6928 
6929 int
ncx_getn_uchar_uint(const void ** xpp,size_t nelems,uint * tp)6930 ncx_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
6931 {
6932     int status = NC_NOERR;
6933     uchar *xp = (uchar *)(*xpp);
6934 
6935     while (nelems-- != 0) {
6936 
6937         *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
6938     }
6939 
6940     *xpp = (const void *)xp;
6941     return status;
6942 }
6943 
6944 int
ncx_getn_uchar_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)6945 ncx_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
6946 {
6947     int status = NC_NOERR;
6948     uchar *xp = (uchar *)(*xpp);
6949 
6950     while (nelems-- != 0) {
6951 
6952         *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
6953     }
6954 
6955     *xpp = (const void *)xp;
6956     return status;
6957 }
6958 
6959 
6960 int
ncx_pad_getn_uchar_schar(const void ** xpp,size_t nelems,schar * tp)6961 ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
6962 {
6963     int status = NC_NOERR;
6964     size_t rndup = nelems % X_ALIGN;
6965     uchar *xp = (uchar *) *xpp;
6966 
6967     if (rndup) rndup = X_ALIGN - rndup;
6968 
6969     while (nelems-- != 0) {
6970         if (*xp > SCHAR_MAX) {
6971             *tp = NC_FILL_BYTE;
6972             status = NC_ERANGE;
6973 
6974 #ifdef ERANGE_FILL
6975             xp++; tp++; continue;
6976 #endif
6977         }
6978         *tp++ = (schar) *xp++; /* type cast from uchar to schar */
6979     }
6980 
6981     *xpp = (void *)(xp + rndup);
6982     return status;
6983 }
6984 int
ncx_pad_getn_uchar_uchar(const void ** xpp,size_t nelems,uchar * tp)6985 ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
6986 {
6987 		size_t rndup = nelems % X_ALIGN;
6988 
6989 	if (rndup)
6990 		rndup = X_ALIGN - rndup;
6991 
6992 	(void) memcpy(tp, *xpp, (size_t)nelems);
6993 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
6994 
6995 	return NC_NOERR;
6996 
6997 }
6998 int
ncx_pad_getn_uchar_short(const void ** xpp,size_t nelems,short * tp)6999 ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
7000 {
7001     int status = NC_NOERR;
7002     size_t rndup = nelems % X_ALIGN;
7003     uchar *xp = (uchar *) *xpp;
7004 
7005     if (rndup)
7006         rndup = X_ALIGN - rndup;
7007 
7008     while (nelems-- != 0) {
7009 
7010         *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
7011     }
7012 
7013     *xpp = (void *)(xp + rndup);
7014     return status;
7015 }
7016 
7017 int
ncx_pad_getn_uchar_int(const void ** xpp,size_t nelems,int * tp)7018 ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
7019 {
7020     int status = NC_NOERR;
7021     size_t rndup = nelems % X_ALIGN;
7022     uchar *xp = (uchar *) *xpp;
7023 
7024     if (rndup)
7025         rndup = X_ALIGN - rndup;
7026 
7027     while (nelems-- != 0) {
7028 
7029         *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
7030     }
7031 
7032     *xpp = (void *)(xp + rndup);
7033     return status;
7034 }
7035 
7036 int
ncx_pad_getn_uchar_long(const void ** xpp,size_t nelems,long * tp)7037 ncx_pad_getn_uchar_long(const void **xpp, size_t nelems, long *tp)
7038 {
7039     int status = NC_NOERR;
7040     size_t rndup = nelems % X_ALIGN;
7041     uchar *xp = (uchar *) *xpp;
7042 
7043     if (rndup)
7044         rndup = X_ALIGN - rndup;
7045 
7046     while (nelems-- != 0) {
7047 
7048         *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
7049     }
7050 
7051     *xpp = (void *)(xp + rndup);
7052     return status;
7053 }
7054 
7055 int
ncx_pad_getn_uchar_float(const void ** xpp,size_t nelems,float * tp)7056 ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
7057 {
7058     int status = NC_NOERR;
7059     size_t rndup = nelems % X_ALIGN;
7060     uchar *xp = (uchar *) *xpp;
7061 
7062     if (rndup)
7063         rndup = X_ALIGN - rndup;
7064 
7065     while (nelems-- != 0) {
7066 
7067         *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
7068     }
7069 
7070     *xpp = (void *)(xp + rndup);
7071     return status;
7072 }
7073 
7074 int
ncx_pad_getn_uchar_double(const void ** xpp,size_t nelems,double * tp)7075 ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
7076 {
7077     int status = NC_NOERR;
7078     size_t rndup = nelems % X_ALIGN;
7079     uchar *xp = (uchar *) *xpp;
7080 
7081     if (rndup)
7082         rndup = X_ALIGN - rndup;
7083 
7084     while (nelems-- != 0) {
7085 
7086         *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
7087     }
7088 
7089     *xpp = (void *)(xp + rndup);
7090     return status;
7091 }
7092 
7093 int
ncx_pad_getn_uchar_longlong(const void ** xpp,size_t nelems,longlong * tp)7094 ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelems, longlong *tp)
7095 {
7096     int status = NC_NOERR;
7097     size_t rndup = nelems % X_ALIGN;
7098     uchar *xp = (uchar *) *xpp;
7099 
7100     if (rndup)
7101         rndup = X_ALIGN - rndup;
7102 
7103     while (nelems-- != 0) {
7104 
7105         *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
7106     }
7107 
7108     *xpp = (void *)(xp + rndup);
7109     return status;
7110 }
7111 
7112 int
ncx_pad_getn_uchar_ushort(const void ** xpp,size_t nelems,ushort * tp)7113 ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelems, ushort *tp)
7114 {
7115     int status = NC_NOERR;
7116     size_t rndup = nelems % X_ALIGN;
7117     uchar *xp = (uchar *) *xpp;
7118 
7119     if (rndup)
7120         rndup = X_ALIGN - rndup;
7121 
7122     while (nelems-- != 0) {
7123 
7124         *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
7125     }
7126 
7127     *xpp = (void *)(xp + rndup);
7128     return status;
7129 }
7130 
7131 int
ncx_pad_getn_uchar_uint(const void ** xpp,size_t nelems,uint * tp)7132 ncx_pad_getn_uchar_uint(const void **xpp, size_t nelems, uint *tp)
7133 {
7134     int status = NC_NOERR;
7135     size_t rndup = nelems % X_ALIGN;
7136     uchar *xp = (uchar *) *xpp;
7137 
7138     if (rndup)
7139         rndup = X_ALIGN - rndup;
7140 
7141     while (nelems-- != 0) {
7142 
7143         *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
7144     }
7145 
7146     *xpp = (void *)(xp + rndup);
7147     return status;
7148 }
7149 
7150 int
ncx_pad_getn_uchar_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)7151 ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
7152 {
7153     int status = NC_NOERR;
7154     size_t rndup = nelems % X_ALIGN;
7155     uchar *xp = (uchar *) *xpp;
7156 
7157     if (rndup)
7158         rndup = X_ALIGN - rndup;
7159 
7160     while (nelems-- != 0) {
7161 
7162         *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
7163     }
7164 
7165     *xpp = (void *)(xp + rndup);
7166     return status;
7167 }
7168 
7169 
7170 int
ncx_putn_uchar_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)7171 ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7172 {
7173     int status = NC_NOERR;
7174     uchar *xp = (uchar *) *xpp;
7175 
7176     while (nelems-- != 0) {
7177         if (*tp < 0) {
7178 
7179 #ifdef ERANGE_FILL
7180             if (fillp != NULL) memcpy(xp, fillp, 1);
7181 #endif
7182             status = NC_ERANGE;
7183 
7184 #ifdef ERANGE_FILL
7185             xp++; tp++; continue;
7186 #endif
7187         }
7188         *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7189     }
7190 
7191     *xpp = (void *)xp;
7192     return status;
7193 }
7194 int
ncx_putn_uchar_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)7195 ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7196 {
7197 		(void) memcpy(*xpp, tp, (size_t)nelems);
7198 	*xpp = (void *)((char *)(*xpp) + nelems);
7199 
7200 	return NC_NOERR;
7201 
7202 }
7203 int
ncx_putn_uchar_short(void ** xpp,size_t nelems,const short * tp,void * fillp)7204 ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7205 {
7206     int status = NC_NOERR;
7207     uchar *xp = (uchar *) *xpp;
7208 
7209     while (nelems-- != 0) {
7210         if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7211 
7212 #ifdef ERANGE_FILL
7213             if (fillp != NULL) memcpy(xp, fillp, 1);
7214 #endif
7215             status = NC_ERANGE;
7216 
7217 #ifdef ERANGE_FILL
7218             xp++; tp++; continue;
7219 #endif
7220         }
7221         *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7222     }
7223 
7224     *xpp = (void *)xp;
7225     return status;
7226 }
7227 
7228 int
ncx_putn_uchar_int(void ** xpp,size_t nelems,const int * tp,void * fillp)7229 ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7230 {
7231     int status = NC_NOERR;
7232     uchar *xp = (uchar *) *xpp;
7233 
7234     while (nelems-- != 0) {
7235         if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7236 
7237 #ifdef ERANGE_FILL
7238             if (fillp != NULL) memcpy(xp, fillp, 1);
7239 #endif
7240             status = NC_ERANGE;
7241 
7242 #ifdef ERANGE_FILL
7243             xp++; tp++; continue;
7244 #endif
7245         }
7246         *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7247     }
7248 
7249     *xpp = (void *)xp;
7250     return status;
7251 }
7252 
7253 int
ncx_putn_uchar_long(void ** xpp,size_t nelems,const long * tp,void * fillp)7254 ncx_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7255 {
7256     int status = NC_NOERR;
7257     uchar *xp = (uchar *) *xpp;
7258 
7259     while (nelems-- != 0) {
7260         if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7261 
7262 #ifdef ERANGE_FILL
7263             if (fillp != NULL) memcpy(xp, fillp, 1);
7264 #endif
7265             status = NC_ERANGE;
7266 
7267 #ifdef ERANGE_FILL
7268             xp++; tp++; continue;
7269 #endif
7270         }
7271         *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7272     }
7273 
7274     *xpp = (void *)xp;
7275     return status;
7276 }
7277 
7278 int
ncx_putn_uchar_float(void ** xpp,size_t nelems,const float * tp,void * fillp)7279 ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7280 {
7281     int status = NC_NOERR;
7282     uchar *xp = (uchar *) *xpp;
7283 
7284     while (nelems-- != 0) {
7285         if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7286 
7287 #ifdef ERANGE_FILL
7288             if (fillp != NULL) memcpy(xp, fillp, 1);
7289 #endif
7290             status = NC_ERANGE;
7291 
7292 #ifdef ERANGE_FILL
7293             xp++; tp++; continue;
7294 #endif
7295         }
7296         *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7297     }
7298 
7299     *xpp = (void *)xp;
7300     return status;
7301 }
7302 
7303 int
ncx_putn_uchar_double(void ** xpp,size_t nelems,const double * tp,void * fillp)7304 ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7305 {
7306     int status = NC_NOERR;
7307     uchar *xp = (uchar *) *xpp;
7308 
7309     while (nelems-- != 0) {
7310         if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7311 
7312 #ifdef ERANGE_FILL
7313             if (fillp != NULL) memcpy(xp, fillp, 1);
7314 #endif
7315             status = NC_ERANGE;
7316 
7317 #ifdef ERANGE_FILL
7318             xp++; tp++; continue;
7319 #endif
7320         }
7321         *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7322     }
7323 
7324     *xpp = (void *)xp;
7325     return status;
7326 }
7327 
7328 int
ncx_putn_uchar_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)7329 ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7330 {
7331     int status = NC_NOERR;
7332     uchar *xp = (uchar *) *xpp;
7333 
7334     while (nelems-- != 0) {
7335         if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7336 
7337 #ifdef ERANGE_FILL
7338             if (fillp != NULL) memcpy(xp, fillp, 1);
7339 #endif
7340             status = NC_ERANGE;
7341 
7342 #ifdef ERANGE_FILL
7343             xp++; tp++; continue;
7344 #endif
7345         }
7346         *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7347     }
7348 
7349     *xpp = (void *)xp;
7350     return status;
7351 }
7352 
7353 int
ncx_putn_uchar_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)7354 ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7355 {
7356     int status = NC_NOERR;
7357     uchar *xp = (uchar *) *xpp;
7358 
7359     while (nelems-- != 0) {
7360         if (*tp > (ushort)X_UCHAR_MAX ) {
7361 
7362 #ifdef ERANGE_FILL
7363             if (fillp != NULL) memcpy(xp, fillp, 1);
7364 #endif
7365             status = NC_ERANGE;
7366 
7367 #ifdef ERANGE_FILL
7368             xp++; tp++; continue;
7369 #endif
7370         }
7371         *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7372     }
7373 
7374     *xpp = (void *)xp;
7375     return status;
7376 }
7377 
7378 int
ncx_putn_uchar_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)7379 ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7380 {
7381     int status = NC_NOERR;
7382     uchar *xp = (uchar *) *xpp;
7383 
7384     while (nelems-- != 0) {
7385         if (*tp > (uint)X_UCHAR_MAX ) {
7386 
7387 #ifdef ERANGE_FILL
7388             if (fillp != NULL) memcpy(xp, fillp, 1);
7389 #endif
7390             status = NC_ERANGE;
7391 
7392 #ifdef ERANGE_FILL
7393             xp++; tp++; continue;
7394 #endif
7395         }
7396         *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7397     }
7398 
7399     *xpp = (void *)xp;
7400     return status;
7401 }
7402 
7403 int
ncx_putn_uchar_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)7404 ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7405 {
7406     int status = NC_NOERR;
7407     uchar *xp = (uchar *) *xpp;
7408 
7409     while (nelems-- != 0) {
7410         if (*tp > (ulonglong)X_UCHAR_MAX ) {
7411 
7412 #ifdef ERANGE_FILL
7413             if (fillp != NULL) memcpy(xp, fillp, 1);
7414 #endif
7415             status = NC_ERANGE;
7416 
7417 #ifdef ERANGE_FILL
7418             xp++; tp++; continue;
7419 #endif
7420         }
7421         *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7422     }
7423 
7424     *xpp = (void *)xp;
7425     return status;
7426 }
7427 
7428 
7429 int
ncx_pad_putn_uchar_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)7430 ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
7431 {
7432     int status = NC_NOERR;
7433     size_t rndup = nelems % X_ALIGN;
7434     uchar *xp = (uchar *) *xpp;
7435 
7436     if (rndup) rndup = X_ALIGN - rndup;
7437 
7438     while (nelems-- != 0) {
7439         if (*tp < 0) {
7440 
7441 #ifdef ERANGE_FILL
7442             if (fillp != NULL) memcpy(xp, fillp, 1);
7443 #endif
7444             status = NC_ERANGE;
7445 
7446 #ifdef ERANGE_FILL
7447             xp++; tp++; continue;
7448 #endif
7449         }
7450         *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
7451     }
7452 
7453     if (rndup) {
7454         (void) memcpy(xp, nada, (size_t)rndup);
7455         xp += rndup;
7456     }
7457 
7458     *xpp = (void *)xp;
7459     return status;
7460 }
7461 int
ncx_pad_putn_uchar_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)7462 ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
7463 {
7464 		size_t rndup = nelems % X_ALIGN;
7465 
7466 	if (rndup)
7467 		rndup = X_ALIGN - rndup;
7468 
7469 	(void) memcpy(*xpp, tp, (size_t)nelems);
7470 	*xpp = (void *)((char *)(*xpp) + nelems);
7471 
7472 	if (rndup)
7473 	{
7474 		(void) memcpy(*xpp, nada, (size_t)rndup);
7475 		*xpp = (void *)((char *)(*xpp) + rndup);
7476 	}
7477 
7478 	return NC_NOERR;
7479 
7480 }
7481 int
ncx_pad_putn_uchar_short(void ** xpp,size_t nelems,const short * tp,void * fillp)7482 ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp, void *fillp)
7483 {
7484     int status = NC_NOERR;
7485     size_t rndup = nelems % X_ALIGN;
7486     uchar *xp = (uchar *) *xpp;
7487 
7488     if (rndup) rndup = X_ALIGN - rndup;
7489 
7490     while (nelems-- != 0) {
7491         if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
7492 
7493 #ifdef ERANGE_FILL
7494             if (fillp != NULL) memcpy(xp, fillp, 1);
7495 #endif
7496             status = NC_ERANGE;
7497 
7498 #ifdef ERANGE_FILL
7499             xp++; tp++; continue;
7500 #endif
7501         }
7502         *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
7503     }
7504 
7505 
7506     if (rndup) {
7507         (void) memcpy(xp, nada, (size_t)rndup);
7508         xp += rndup;
7509     }
7510 
7511     *xpp = (void *)xp;
7512     return status;
7513 }
7514 
7515 int
ncx_pad_putn_uchar_int(void ** xpp,size_t nelems,const int * tp,void * fillp)7516 ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp, void *fillp)
7517 {
7518     int status = NC_NOERR;
7519     size_t rndup = nelems % X_ALIGN;
7520     uchar *xp = (uchar *) *xpp;
7521 
7522     if (rndup) rndup = X_ALIGN - rndup;
7523 
7524     while (nelems-- != 0) {
7525         if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
7526 
7527 #ifdef ERANGE_FILL
7528             if (fillp != NULL) memcpy(xp, fillp, 1);
7529 #endif
7530             status = NC_ERANGE;
7531 
7532 #ifdef ERANGE_FILL
7533             xp++; tp++; continue;
7534 #endif
7535         }
7536         *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
7537     }
7538 
7539 
7540     if (rndup) {
7541         (void) memcpy(xp, nada, (size_t)rndup);
7542         xp += rndup;
7543     }
7544 
7545     *xpp = (void *)xp;
7546     return status;
7547 }
7548 
7549 int
ncx_pad_putn_uchar_long(void ** xpp,size_t nelems,const long * tp,void * fillp)7550 ncx_pad_putn_uchar_long(void **xpp, size_t nelems, const long *tp, void *fillp)
7551 {
7552     int status = NC_NOERR;
7553     size_t rndup = nelems % X_ALIGN;
7554     uchar *xp = (uchar *) *xpp;
7555 
7556     if (rndup) rndup = X_ALIGN - rndup;
7557 
7558     while (nelems-- != 0) {
7559         if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
7560 
7561 #ifdef ERANGE_FILL
7562             if (fillp != NULL) memcpy(xp, fillp, 1);
7563 #endif
7564             status = NC_ERANGE;
7565 
7566 #ifdef ERANGE_FILL
7567             xp++; tp++; continue;
7568 #endif
7569         }
7570         *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
7571     }
7572 
7573 
7574     if (rndup) {
7575         (void) memcpy(xp, nada, (size_t)rndup);
7576         xp += rndup;
7577     }
7578 
7579     *xpp = (void *)xp;
7580     return status;
7581 }
7582 
7583 int
ncx_pad_putn_uchar_float(void ** xpp,size_t nelems,const float * tp,void * fillp)7584 ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp, void *fillp)
7585 {
7586     int status = NC_NOERR;
7587     size_t rndup = nelems % X_ALIGN;
7588     uchar *xp = (uchar *) *xpp;
7589 
7590     if (rndup) rndup = X_ALIGN - rndup;
7591 
7592     while (nelems-- != 0) {
7593         if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
7594 
7595 #ifdef ERANGE_FILL
7596             if (fillp != NULL) memcpy(xp, fillp, 1);
7597 #endif
7598             status = NC_ERANGE;
7599 
7600 #ifdef ERANGE_FILL
7601             xp++; tp++; continue;
7602 #endif
7603         }
7604         *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
7605     }
7606 
7607 
7608     if (rndup) {
7609         (void) memcpy(xp, nada, (size_t)rndup);
7610         xp += rndup;
7611     }
7612 
7613     *xpp = (void *)xp;
7614     return status;
7615 }
7616 
7617 int
ncx_pad_putn_uchar_double(void ** xpp,size_t nelems,const double * tp,void * fillp)7618 ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp, void *fillp)
7619 {
7620     int status = NC_NOERR;
7621     size_t rndup = nelems % X_ALIGN;
7622     uchar *xp = (uchar *) *xpp;
7623 
7624     if (rndup) rndup = X_ALIGN - rndup;
7625 
7626     while (nelems-- != 0) {
7627         if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
7628 
7629 #ifdef ERANGE_FILL
7630             if (fillp != NULL) memcpy(xp, fillp, 1);
7631 #endif
7632             status = NC_ERANGE;
7633 
7634 #ifdef ERANGE_FILL
7635             xp++; tp++; continue;
7636 #endif
7637         }
7638         *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
7639     }
7640 
7641 
7642     if (rndup) {
7643         (void) memcpy(xp, nada, (size_t)rndup);
7644         xp += rndup;
7645     }
7646 
7647     *xpp = (void *)xp;
7648     return status;
7649 }
7650 
7651 int
ncx_pad_putn_uchar_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)7652 ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
7653 {
7654     int status = NC_NOERR;
7655     size_t rndup = nelems % X_ALIGN;
7656     uchar *xp = (uchar *) *xpp;
7657 
7658     if (rndup) rndup = X_ALIGN - rndup;
7659 
7660     while (nelems-- != 0) {
7661         if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
7662 
7663 #ifdef ERANGE_FILL
7664             if (fillp != NULL) memcpy(xp, fillp, 1);
7665 #endif
7666             status = NC_ERANGE;
7667 
7668 #ifdef ERANGE_FILL
7669             xp++; tp++; continue;
7670 #endif
7671         }
7672         *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
7673     }
7674 
7675 
7676     if (rndup) {
7677         (void) memcpy(xp, nada, (size_t)rndup);
7678         xp += rndup;
7679     }
7680 
7681     *xpp = (void *)xp;
7682     return status;
7683 }
7684 
7685 int
ncx_pad_putn_uchar_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)7686 ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
7687 {
7688     int status = NC_NOERR;
7689     size_t rndup = nelems % X_ALIGN;
7690     uchar *xp = (uchar *) *xpp;
7691 
7692     if (rndup) rndup = X_ALIGN - rndup;
7693 
7694     while (nelems-- != 0) {
7695         if (*tp > (ushort)X_UCHAR_MAX ) {
7696 
7697 #ifdef ERANGE_FILL
7698             if (fillp != NULL) memcpy(xp, fillp, 1);
7699 #endif
7700             status = NC_ERANGE;
7701 
7702 #ifdef ERANGE_FILL
7703             xp++; tp++; continue;
7704 #endif
7705         }
7706         *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
7707     }
7708 
7709 
7710     if (rndup) {
7711         (void) memcpy(xp, nada, (size_t)rndup);
7712         xp += rndup;
7713     }
7714 
7715     *xpp = (void *)xp;
7716     return status;
7717 }
7718 
7719 int
ncx_pad_putn_uchar_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)7720 ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
7721 {
7722     int status = NC_NOERR;
7723     size_t rndup = nelems % X_ALIGN;
7724     uchar *xp = (uchar *) *xpp;
7725 
7726     if (rndup) rndup = X_ALIGN - rndup;
7727 
7728     while (nelems-- != 0) {
7729         if (*tp > (uint)X_UCHAR_MAX ) {
7730 
7731 #ifdef ERANGE_FILL
7732             if (fillp != NULL) memcpy(xp, fillp, 1);
7733 #endif
7734             status = NC_ERANGE;
7735 
7736 #ifdef ERANGE_FILL
7737             xp++; tp++; continue;
7738 #endif
7739         }
7740         *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
7741     }
7742 
7743 
7744     if (rndup) {
7745         (void) memcpy(xp, nada, (size_t)rndup);
7746         xp += rndup;
7747     }
7748 
7749     *xpp = (void *)xp;
7750     return status;
7751 }
7752 
7753 int
ncx_pad_putn_uchar_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)7754 ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
7755 {
7756     int status = NC_NOERR;
7757     size_t rndup = nelems % X_ALIGN;
7758     uchar *xp = (uchar *) *xpp;
7759 
7760     if (rndup) rndup = X_ALIGN - rndup;
7761 
7762     while (nelems-- != 0) {
7763         if (*tp > (ulonglong)X_UCHAR_MAX ) {
7764 
7765 #ifdef ERANGE_FILL
7766             if (fillp != NULL) memcpy(xp, fillp, 1);
7767 #endif
7768             status = NC_ERANGE;
7769 
7770 #ifdef ERANGE_FILL
7771             xp++; tp++; continue;
7772 #endif
7773         }
7774         *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
7775     }
7776 
7777 
7778     if (rndup) {
7779         (void) memcpy(xp, nada, (size_t)rndup);
7780         xp += rndup;
7781     }
7782 
7783     *xpp = (void *)xp;
7784     return status;
7785 }
7786 
7787 
7788 /* short ---------------------------------------------------------------------*/
7789 
7790 #if X_SIZEOF_SHORT == SIZEOF_SHORT
7791 /* optimized version */
7792 int
ncx_getn_short_short(const void ** xpp,size_t nelems,short * tp)7793 ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7794 {
7795 #ifdef WORDS_BIGENDIAN
7796 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
7797 # else
7798 	swapn2b(tp, *xpp, nelems);
7799 # endif
7800 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
7801 	return NC_NOERR;
7802 }
7803 #else
7804 int
ncx_getn_short_short(const void ** xpp,size_t nelems,short * tp)7805 ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
7806 {
7807 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7808 
7809  /* basic algorithm is:
7810   *   - ensure sane alignment of input data
7811   *   - copy (conversion happens automatically) input data
7812   *     to output
7813   *   - update xpp to point at next unconverted input, and tp to point
7814   *     at next location for converted output
7815   */
7816   long i, j, ni;
7817   short tmp[LOOPCNT];        /* in case input is misaligned */
7818   short *xp;
7819   int nrange = 0;         /* number of range errors */
7820   int realign = 0;        /* "do we need to fix input data alignment?" */
7821   long cxp = (long) *((char**)xpp);
7822 
7823   realign = (cxp & 7) % SIZEOF_SHORT;
7824   /* sjl: manually stripmine so we can limit amount of
7825    * vector work space reserved to LOOPCNT elements. Also
7826    * makes vectorisation easy */
7827   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7828     ni=Min(nelems-j,LOOPCNT);
7829     if (realign) {
7830       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7831       xp = tmp;
7832     } else {
7833       xp = (short *) *xpp;
7834     }
7835    /* copy the next block */
7836 #pragma cdir loopcnt=LOOPCNT
7837 #pragma cdir shortloop
7838     for (i=0; i<ni; i++) {
7839       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
7840      /* test for range errors (not always needed but do it anyway) */
7841      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7842      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7843       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
7844     }
7845    /* update xpp and tp */
7846     if (realign) xp = (short *) *xpp;
7847     xp += ni;
7848     tp += ni;
7849     *xpp = (void*)xp;
7850   }
7851   return nrange == 0 ? NC_NOERR : NC_ERANGE;
7852 
7853 #else   /* not SX */
7854 	const char *xp = (const char *) *xpp;
7855 	int status = NC_NOERR;
7856 
7857 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7858 	{
7859 		const int lstatus = ncx_get_short_short(xp, tp);
7860 		if (status == NC_NOERR) /* report the first encountered error */
7861 			status = lstatus;
7862 	}
7863 
7864 	*xpp = (const void *)xp;
7865 	return status;
7866 #endif
7867 }
7868 
7869 #endif
7870 int
ncx_getn_short_schar(const void ** xpp,size_t nelems,schar * tp)7871 ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
7872 {
7873 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7874 
7875  /* basic algorithm is:
7876   *   - ensure sane alignment of input data
7877   *   - copy (conversion happens automatically) input data
7878   *     to output
7879   *   - update xpp to point at next unconverted input, and tp to point
7880   *     at next location for converted output
7881   */
7882   long i, j, ni;
7883   short tmp[LOOPCNT];        /* in case input is misaligned */
7884   short *xp;
7885   int nrange = 0;         /* number of range errors */
7886   int realign = 0;        /* "do we need to fix input data alignment?" */
7887   long cxp = (long) *((char**)xpp);
7888 
7889   realign = (cxp & 7) % SIZEOF_SHORT;
7890   /* sjl: manually stripmine so we can limit amount of
7891    * vector work space reserved to LOOPCNT elements. Also
7892    * makes vectorisation easy */
7893   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7894     ni=Min(nelems-j,LOOPCNT);
7895     if (realign) {
7896       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7897       xp = tmp;
7898     } else {
7899       xp = (short *) *xpp;
7900     }
7901    /* copy the next block */
7902 #pragma cdir loopcnt=LOOPCNT
7903 #pragma cdir shortloop
7904     for (i=0; i<ni; i++) {
7905       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
7906      /* test for range errors (not always needed but do it anyway) */
7907      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7908      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7909       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
7910     }
7911    /* update xpp and tp */
7912     if (realign) xp = (short *) *xpp;
7913     xp += ni;
7914     tp += ni;
7915     *xpp = (void*)xp;
7916   }
7917   return nrange == 0 ? NC_NOERR : NC_ERANGE;
7918 
7919 #else   /* not SX */
7920 	const char *xp = (const char *) *xpp;
7921 	int status = NC_NOERR;
7922 
7923 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7924 	{
7925 		const int lstatus = ncx_get_short_schar(xp, tp);
7926 		if (status == NC_NOERR) /* report the first encountered error */
7927 			status = lstatus;
7928 	}
7929 
7930 	*xpp = (const void *)xp;
7931 	return status;
7932 #endif
7933 }
7934 
7935 int
ncx_getn_short_int(const void ** xpp,size_t nelems,int * tp)7936 ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
7937 {
7938 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
7939 
7940  /* basic algorithm is:
7941   *   - ensure sane alignment of input data
7942   *   - copy (conversion happens automatically) input data
7943   *     to output
7944   *   - update xpp to point at next unconverted input, and tp to point
7945   *     at next location for converted output
7946   */
7947   long i, j, ni;
7948   short tmp[LOOPCNT];        /* in case input is misaligned */
7949   short *xp;
7950   int nrange = 0;         /* number of range errors */
7951   int realign = 0;        /* "do we need to fix input data alignment?" */
7952   long cxp = (long) *((char**)xpp);
7953 
7954   realign = (cxp & 7) % SIZEOF_SHORT;
7955   /* sjl: manually stripmine so we can limit amount of
7956    * vector work space reserved to LOOPCNT elements. Also
7957    * makes vectorisation easy */
7958   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
7959     ni=Min(nelems-j,LOOPCNT);
7960     if (realign) {
7961       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
7962       xp = tmp;
7963     } else {
7964       xp = (short *) *xpp;
7965     }
7966    /* copy the next block */
7967 #pragma cdir loopcnt=LOOPCNT
7968 #pragma cdir shortloop
7969     for (i=0; i<ni; i++) {
7970       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
7971      /* test for range errors (not always needed but do it anyway) */
7972      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
7973      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
7974       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
7975     }
7976    /* update xpp and tp */
7977     if (realign) xp = (short *) *xpp;
7978     xp += ni;
7979     tp += ni;
7980     *xpp = (void*)xp;
7981   }
7982   return nrange == 0 ? NC_NOERR : NC_ERANGE;
7983 
7984 #else   /* not SX */
7985 	const char *xp = (const char *) *xpp;
7986 	int status = NC_NOERR;
7987 
7988 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
7989 	{
7990 		const int lstatus = ncx_get_short_int(xp, tp);
7991 		if (status == NC_NOERR) /* report the first encountered error */
7992 			status = lstatus;
7993 	}
7994 
7995 	*xpp = (const void *)xp;
7996 	return status;
7997 #endif
7998 }
7999 
8000 int
ncx_getn_short_long(const void ** xpp,size_t nelems,long * tp)8001 ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
8002 {
8003 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8004 
8005  /* basic algorithm is:
8006   *   - ensure sane alignment of input data
8007   *   - copy (conversion happens automatically) input data
8008   *     to output
8009   *   - update xpp to point at next unconverted input, and tp to point
8010   *     at next location for converted output
8011   */
8012   long i, j, ni;
8013   short tmp[LOOPCNT];        /* in case input is misaligned */
8014   short *xp;
8015   int nrange = 0;         /* number of range errors */
8016   int realign = 0;        /* "do we need to fix input data alignment?" */
8017   long cxp = (long) *((char**)xpp);
8018 
8019   realign = (cxp & 7) % SIZEOF_SHORT;
8020   /* sjl: manually stripmine so we can limit amount of
8021    * vector work space reserved to LOOPCNT elements. Also
8022    * makes vectorisation easy */
8023   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8024     ni=Min(nelems-j,LOOPCNT);
8025     if (realign) {
8026       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8027       xp = tmp;
8028     } else {
8029       xp = (short *) *xpp;
8030     }
8031    /* copy the next block */
8032 #pragma cdir loopcnt=LOOPCNT
8033 #pragma cdir shortloop
8034     for (i=0; i<ni; i++) {
8035       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
8036      /* test for range errors (not always needed but do it anyway) */
8037      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8038      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8039       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
8040     }
8041    /* update xpp and tp */
8042     if (realign) xp = (short *) *xpp;
8043     xp += ni;
8044     tp += ni;
8045     *xpp = (void*)xp;
8046   }
8047   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8048 
8049 #else   /* not SX */
8050 	const char *xp = (const char *) *xpp;
8051 	int status = NC_NOERR;
8052 
8053 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8054 	{
8055 		const int lstatus = ncx_get_short_long(xp, tp);
8056 		if (status == NC_NOERR) /* report the first encountered error */
8057 			status = lstatus;
8058 	}
8059 
8060 	*xpp = (const void *)xp;
8061 	return status;
8062 #endif
8063 }
8064 
8065 int
ncx_getn_short_float(const void ** xpp,size_t nelems,float * tp)8066 ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
8067 {
8068 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8069 
8070  /* basic algorithm is:
8071   *   - ensure sane alignment of input data
8072   *   - copy (conversion happens automatically) input data
8073   *     to output
8074   *   - update xpp to point at next unconverted input, and tp to point
8075   *     at next location for converted output
8076   */
8077   long i, j, ni;
8078   short tmp[LOOPCNT];        /* in case input is misaligned */
8079   short *xp;
8080   int nrange = 0;         /* number of range errors */
8081   int realign = 0;        /* "do we need to fix input data alignment?" */
8082   long cxp = (long) *((char**)xpp);
8083 
8084   realign = (cxp & 7) % SIZEOF_SHORT;
8085   /* sjl: manually stripmine so we can limit amount of
8086    * vector work space reserved to LOOPCNT elements. Also
8087    * makes vectorisation easy */
8088   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8089     ni=Min(nelems-j,LOOPCNT);
8090     if (realign) {
8091       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8092       xp = tmp;
8093     } else {
8094       xp = (short *) *xpp;
8095     }
8096    /* copy the next block */
8097 #pragma cdir loopcnt=LOOPCNT
8098 #pragma cdir shortloop
8099     for (i=0; i<ni; i++) {
8100       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
8101      /* test for range errors (not always needed but do it anyway) */
8102      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8103      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8104       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
8105     }
8106    /* update xpp and tp */
8107     if (realign) xp = (short *) *xpp;
8108     xp += ni;
8109     tp += ni;
8110     *xpp = (void*)xp;
8111   }
8112   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8113 
8114 #else   /* not SX */
8115 	const char *xp = (const char *) *xpp;
8116 	int status = NC_NOERR;
8117 
8118 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8119 	{
8120 		const int lstatus = ncx_get_short_float(xp, tp);
8121 		if (status == NC_NOERR) /* report the first encountered error */
8122 			status = lstatus;
8123 	}
8124 
8125 	*xpp = (const void *)xp;
8126 	return status;
8127 #endif
8128 }
8129 
8130 int
ncx_getn_short_double(const void ** xpp,size_t nelems,double * tp)8131 ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
8132 {
8133 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8134 
8135  /* basic algorithm is:
8136   *   - ensure sane alignment of input data
8137   *   - copy (conversion happens automatically) input data
8138   *     to output
8139   *   - update xpp to point at next unconverted input, and tp to point
8140   *     at next location for converted output
8141   */
8142   long i, j, ni;
8143   short tmp[LOOPCNT];        /* in case input is misaligned */
8144   short *xp;
8145   int nrange = 0;         /* number of range errors */
8146   int realign = 0;        /* "do we need to fix input data alignment?" */
8147   long cxp = (long) *((char**)xpp);
8148 
8149   realign = (cxp & 7) % SIZEOF_SHORT;
8150   /* sjl: manually stripmine so we can limit amount of
8151    * vector work space reserved to LOOPCNT elements. Also
8152    * makes vectorisation easy */
8153   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8154     ni=Min(nelems-j,LOOPCNT);
8155     if (realign) {
8156       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8157       xp = tmp;
8158     } else {
8159       xp = (short *) *xpp;
8160     }
8161    /* copy the next block */
8162 #pragma cdir loopcnt=LOOPCNT
8163 #pragma cdir shortloop
8164     for (i=0; i<ni; i++) {
8165       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
8166      /* test for range errors (not always needed but do it anyway) */
8167      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8168      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8169       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
8170     }
8171    /* update xpp and tp */
8172     if (realign) xp = (short *) *xpp;
8173     xp += ni;
8174     tp += ni;
8175     *xpp = (void*)xp;
8176   }
8177   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8178 
8179 #else   /* not SX */
8180 	const char *xp = (const char *) *xpp;
8181 	int status = NC_NOERR;
8182 
8183 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8184 	{
8185 		const int lstatus = ncx_get_short_double(xp, tp);
8186 		if (status == NC_NOERR) /* report the first encountered error */
8187 			status = lstatus;
8188 	}
8189 
8190 	*xpp = (const void *)xp;
8191 	return status;
8192 #endif
8193 }
8194 
8195 int
ncx_getn_short_longlong(const void ** xpp,size_t nelems,longlong * tp)8196 ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8197 {
8198 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8199 
8200  /* basic algorithm is:
8201   *   - ensure sane alignment of input data
8202   *   - copy (conversion happens automatically) input data
8203   *     to output
8204   *   - update xpp to point at next unconverted input, and tp to point
8205   *     at next location for converted output
8206   */
8207   long i, j, ni;
8208   short tmp[LOOPCNT];        /* in case input is misaligned */
8209   short *xp;
8210   int nrange = 0;         /* number of range errors */
8211   int realign = 0;        /* "do we need to fix input data alignment?" */
8212   long cxp = (long) *((char**)xpp);
8213 
8214   realign = (cxp & 7) % SIZEOF_SHORT;
8215   /* sjl: manually stripmine so we can limit amount of
8216    * vector work space reserved to LOOPCNT elements. Also
8217    * makes vectorisation easy */
8218   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8219     ni=Min(nelems-j,LOOPCNT);
8220     if (realign) {
8221       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8222       xp = tmp;
8223     } else {
8224       xp = (short *) *xpp;
8225     }
8226    /* copy the next block */
8227 #pragma cdir loopcnt=LOOPCNT
8228 #pragma cdir shortloop
8229     for (i=0; i<ni; i++) {
8230       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
8231      /* test for range errors (not always needed but do it anyway) */
8232      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8233      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8234       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
8235     }
8236    /* update xpp and tp */
8237     if (realign) xp = (short *) *xpp;
8238     xp += ni;
8239     tp += ni;
8240     *xpp = (void*)xp;
8241   }
8242   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8243 
8244 #else   /* not SX */
8245 	const char *xp = (const char *) *xpp;
8246 	int status = NC_NOERR;
8247 
8248 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8249 	{
8250 		const int lstatus = ncx_get_short_longlong(xp, tp);
8251 		if (status == NC_NOERR) /* report the first encountered error */
8252 			status = lstatus;
8253 	}
8254 
8255 	*xpp = (const void *)xp;
8256 	return status;
8257 #endif
8258 }
8259 
8260 int
ncx_getn_short_uchar(const void ** xpp,size_t nelems,uchar * tp)8261 ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8262 {
8263 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8264 
8265  /* basic algorithm is:
8266   *   - ensure sane alignment of input data
8267   *   - copy (conversion happens automatically) input data
8268   *     to output
8269   *   - update xpp to point at next unconverted input, and tp to point
8270   *     at next location for converted output
8271   */
8272   long i, j, ni;
8273   short tmp[LOOPCNT];        /* in case input is misaligned */
8274   short *xp;
8275   int nrange = 0;         /* number of range errors */
8276   int realign = 0;        /* "do we need to fix input data alignment?" */
8277   long cxp = (long) *((char**)xpp);
8278 
8279   realign = (cxp & 7) % SIZEOF_SHORT;
8280   /* sjl: manually stripmine so we can limit amount of
8281    * vector work space reserved to LOOPCNT elements. Also
8282    * makes vectorisation easy */
8283   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8284     ni=Min(nelems-j,LOOPCNT);
8285     if (realign) {
8286       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8287       xp = tmp;
8288     } else {
8289       xp = (short *) *xpp;
8290     }
8291    /* copy the next block */
8292 #pragma cdir loopcnt=LOOPCNT
8293 #pragma cdir shortloop
8294     for (i=0; i<ni; i++) {
8295       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
8296      /* test for range errors (not always needed but do it anyway) */
8297      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8298      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8299       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
8300     }
8301    /* update xpp and tp */
8302     if (realign) xp = (short *) *xpp;
8303     xp += ni;
8304     tp += ni;
8305     *xpp = (void*)xp;
8306   }
8307   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8308 
8309 #else   /* not SX */
8310 	const char *xp = (const char *) *xpp;
8311 	int status = NC_NOERR;
8312 
8313 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8314 	{
8315 		const int lstatus = ncx_get_short_uchar(xp, tp);
8316 		if (status == NC_NOERR) /* report the first encountered error */
8317 			status = lstatus;
8318 	}
8319 
8320 	*xpp = (const void *)xp;
8321 	return status;
8322 #endif
8323 }
8324 
8325 int
ncx_getn_short_ushort(const void ** xpp,size_t nelems,ushort * tp)8326 ncx_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8327 {
8328 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8329 
8330  /* basic algorithm is:
8331   *   - ensure sane alignment of input data
8332   *   - copy (conversion happens automatically) input data
8333   *     to output
8334   *   - update xpp to point at next unconverted input, and tp to point
8335   *     at next location for converted output
8336   */
8337   long i, j, ni;
8338   short tmp[LOOPCNT];        /* in case input is misaligned */
8339   short *xp;
8340   int nrange = 0;         /* number of range errors */
8341   int realign = 0;        /* "do we need to fix input data alignment?" */
8342   long cxp = (long) *((char**)xpp);
8343 
8344   realign = (cxp & 7) % SIZEOF_SHORT;
8345   /* sjl: manually stripmine so we can limit amount of
8346    * vector work space reserved to LOOPCNT elements. Also
8347    * makes vectorisation easy */
8348   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8349     ni=Min(nelems-j,LOOPCNT);
8350     if (realign) {
8351       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8352       xp = tmp;
8353     } else {
8354       xp = (short *) *xpp;
8355     }
8356    /* copy the next block */
8357 #pragma cdir loopcnt=LOOPCNT
8358 #pragma cdir shortloop
8359     for (i=0; i<ni; i++) {
8360       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
8361      /* test for range errors (not always needed but do it anyway) */
8362      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8363      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8364       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
8365     }
8366    /* update xpp and tp */
8367     if (realign) xp = (short *) *xpp;
8368     xp += ni;
8369     tp += ni;
8370     *xpp = (void*)xp;
8371   }
8372   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8373 
8374 #else   /* not SX */
8375 	const char *xp = (const char *) *xpp;
8376 	int status = NC_NOERR;
8377 
8378 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8379 	{
8380 		const int lstatus = ncx_get_short_ushort(xp, tp);
8381 		if (status == NC_NOERR) /* report the first encountered error */
8382 			status = lstatus;
8383 	}
8384 
8385 	*xpp = (const void *)xp;
8386 	return status;
8387 #endif
8388 }
8389 
8390 int
ncx_getn_short_uint(const void ** xpp,size_t nelems,uint * tp)8391 ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8392 {
8393 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8394 
8395  /* basic algorithm is:
8396   *   - ensure sane alignment of input data
8397   *   - copy (conversion happens automatically) input data
8398   *     to output
8399   *   - update xpp to point at next unconverted input, and tp to point
8400   *     at next location for converted output
8401   */
8402   long i, j, ni;
8403   short tmp[LOOPCNT];        /* in case input is misaligned */
8404   short *xp;
8405   int nrange = 0;         /* number of range errors */
8406   int realign = 0;        /* "do we need to fix input data alignment?" */
8407   long cxp = (long) *((char**)xpp);
8408 
8409   realign = (cxp & 7) % SIZEOF_SHORT;
8410   /* sjl: manually stripmine so we can limit amount of
8411    * vector work space reserved to LOOPCNT elements. Also
8412    * makes vectorisation easy */
8413   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8414     ni=Min(nelems-j,LOOPCNT);
8415     if (realign) {
8416       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8417       xp = tmp;
8418     } else {
8419       xp = (short *) *xpp;
8420     }
8421    /* copy the next block */
8422 #pragma cdir loopcnt=LOOPCNT
8423 #pragma cdir shortloop
8424     for (i=0; i<ni; i++) {
8425       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
8426      /* test for range errors (not always needed but do it anyway) */
8427      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8428      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8429       nrange += xp[i] > UINT_MAX || xp[i] < 0;
8430     }
8431    /* update xpp and tp */
8432     if (realign) xp = (short *) *xpp;
8433     xp += ni;
8434     tp += ni;
8435     *xpp = (void*)xp;
8436   }
8437   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8438 
8439 #else   /* not SX */
8440 	const char *xp = (const char *) *xpp;
8441 	int status = NC_NOERR;
8442 
8443 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8444 	{
8445 		const int lstatus = ncx_get_short_uint(xp, tp);
8446 		if (status == NC_NOERR) /* report the first encountered error */
8447 			status = lstatus;
8448 	}
8449 
8450 	*xpp = (const void *)xp;
8451 	return status;
8452 #endif
8453 }
8454 
8455 int
ncx_getn_short_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)8456 ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8457 {
8458 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8459 
8460  /* basic algorithm is:
8461   *   - ensure sane alignment of input data
8462   *   - copy (conversion happens automatically) input data
8463   *     to output
8464   *   - update xpp to point at next unconverted input, and tp to point
8465   *     at next location for converted output
8466   */
8467   long i, j, ni;
8468   short tmp[LOOPCNT];        /* in case input is misaligned */
8469   short *xp;
8470   int nrange = 0;         /* number of range errors */
8471   int realign = 0;        /* "do we need to fix input data alignment?" */
8472   long cxp = (long) *((char**)xpp);
8473 
8474   realign = (cxp & 7) % SIZEOF_SHORT;
8475   /* sjl: manually stripmine so we can limit amount of
8476    * vector work space reserved to LOOPCNT elements. Also
8477    * makes vectorisation easy */
8478   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8479     ni=Min(nelems-j,LOOPCNT);
8480     if (realign) {
8481       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
8482       xp = tmp;
8483     } else {
8484       xp = (short *) *xpp;
8485     }
8486    /* copy the next block */
8487 #pragma cdir loopcnt=LOOPCNT
8488 #pragma cdir shortloop
8489     for (i=0; i<ni; i++) {
8490       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
8491      /* test for range errors (not always needed but do it anyway) */
8492      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
8493      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
8494       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
8495     }
8496    /* update xpp and tp */
8497     if (realign) xp = (short *) *xpp;
8498     xp += ni;
8499     tp += ni;
8500     *xpp = (void*)xp;
8501   }
8502   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8503 
8504 #else   /* not SX */
8505 	const char *xp = (const char *) *xpp;
8506 	int status = NC_NOERR;
8507 
8508 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8509 	{
8510 		const int lstatus = ncx_get_short_ulonglong(xp, tp);
8511 		if (status == NC_NOERR) /* report the first encountered error */
8512 			status = lstatus;
8513 	}
8514 
8515 	*xpp = (const void *)xp;
8516 	return status;
8517 #endif
8518 }
8519 
8520 
8521 int
ncx_pad_getn_short_schar(const void ** xpp,size_t nelems,schar * tp)8522 ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
8523 {
8524 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8525 
8526 	const char *xp = (const char *) *xpp;
8527 	int status = NC_NOERR;
8528 
8529 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8530 	{
8531 		const int lstatus = ncx_get_short_schar(xp, tp);
8532 		if (status == NC_NOERR) /* report the first encountered error */
8533 			status = lstatus;
8534 	}
8535 
8536 	if (rndup != 0)
8537 		xp += X_SIZEOF_SHORT;
8538 
8539 	*xpp = (void *)xp;
8540 	return status;
8541 }
8542 
8543 int
ncx_pad_getn_short_uchar(const void ** xpp,size_t nelems,uchar * tp)8544 ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
8545 {
8546 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8547 
8548 	const char *xp = (const char *) *xpp;
8549 	int status = NC_NOERR;
8550 
8551 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8552 	{
8553 		const int lstatus = ncx_get_short_uchar(xp, tp);
8554 		if (status == NC_NOERR) /* report the first encountered error */
8555 			status = lstatus;
8556 	}
8557 
8558 	if (rndup != 0)
8559 		xp += X_SIZEOF_SHORT;
8560 
8561 	*xpp = (void *)xp;
8562 	return status;
8563 }
8564 
8565 int
ncx_pad_getn_short_short(const void ** xpp,size_t nelems,short * tp)8566 ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
8567 {
8568 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8569 
8570 	const char *xp = (const char *) *xpp;
8571 	int status = NC_NOERR;
8572 
8573 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8574 	{
8575 		const int lstatus = ncx_get_short_short(xp, tp);
8576 		if (status == NC_NOERR) /* report the first encountered error */
8577 			status = lstatus;
8578 	}
8579 
8580 	if (rndup != 0)
8581 		xp += X_SIZEOF_SHORT;
8582 
8583 	*xpp = (void *)xp;
8584 	return status;
8585 }
8586 
8587 int
ncx_pad_getn_short_int(const void ** xpp,size_t nelems,int * tp)8588 ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
8589 {
8590 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8591 
8592 	const char *xp = (const char *) *xpp;
8593 	int status = NC_NOERR;
8594 
8595 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8596 	{
8597 		const int lstatus = ncx_get_short_int(xp, tp);
8598 		if (status == NC_NOERR) /* report the first encountered error */
8599 			status = lstatus;
8600 	}
8601 
8602 	if (rndup != 0)
8603 		xp += X_SIZEOF_SHORT;
8604 
8605 	*xpp = (void *)xp;
8606 	return status;
8607 }
8608 
8609 int
ncx_pad_getn_short_long(const void ** xpp,size_t nelems,long * tp)8610 ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
8611 {
8612 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8613 
8614 	const char *xp = (const char *) *xpp;
8615 	int status = NC_NOERR;
8616 
8617 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8618 	{
8619 		const int lstatus = ncx_get_short_long(xp, tp);
8620 		if (status == NC_NOERR) /* report the first encountered error */
8621 			status = lstatus;
8622 	}
8623 
8624 	if (rndup != 0)
8625 		xp += X_SIZEOF_SHORT;
8626 
8627 	*xpp = (void *)xp;
8628 	return status;
8629 }
8630 
8631 int
ncx_pad_getn_short_float(const void ** xpp,size_t nelems,float * tp)8632 ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
8633 {
8634 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8635 
8636 	const char *xp = (const char *) *xpp;
8637 	int status = NC_NOERR;
8638 
8639 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8640 	{
8641 		const int lstatus = ncx_get_short_float(xp, tp);
8642 		if (status == NC_NOERR) /* report the first encountered error */
8643 			status = lstatus;
8644 	}
8645 
8646 	if (rndup != 0)
8647 		xp += X_SIZEOF_SHORT;
8648 
8649 	*xpp = (void *)xp;
8650 	return status;
8651 }
8652 
8653 int
ncx_pad_getn_short_double(const void ** xpp,size_t nelems,double * tp)8654 ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
8655 {
8656 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8657 
8658 	const char *xp = (const char *) *xpp;
8659 	int status = NC_NOERR;
8660 
8661 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8662 	{
8663 		const int lstatus = ncx_get_short_double(xp, tp);
8664 		if (status == NC_NOERR) /* report the first encountered error */
8665 			status = lstatus;
8666 	}
8667 
8668 	if (rndup != 0)
8669 		xp += X_SIZEOF_SHORT;
8670 
8671 	*xpp = (void *)xp;
8672 	return status;
8673 }
8674 
8675 int
ncx_pad_getn_short_uint(const void ** xpp,size_t nelems,uint * tp)8676 ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp)
8677 {
8678 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8679 
8680 	const char *xp = (const char *) *xpp;
8681 	int status = NC_NOERR;
8682 
8683 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8684 	{
8685 		const int lstatus = ncx_get_short_uint(xp, tp);
8686 		if (status == NC_NOERR) /* report the first encountered error */
8687 			status = lstatus;
8688 	}
8689 
8690 	if (rndup != 0)
8691 		xp += X_SIZEOF_SHORT;
8692 
8693 	*xpp = (void *)xp;
8694 	return status;
8695 }
8696 
8697 int
ncx_pad_getn_short_longlong(const void ** xpp,size_t nelems,longlong * tp)8698 ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp)
8699 {
8700 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8701 
8702 	const char *xp = (const char *) *xpp;
8703 	int status = NC_NOERR;
8704 
8705 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8706 	{
8707 		const int lstatus = ncx_get_short_longlong(xp, tp);
8708 		if (status == NC_NOERR) /* report the first encountered error */
8709 			status = lstatus;
8710 	}
8711 
8712 	if (rndup != 0)
8713 		xp += X_SIZEOF_SHORT;
8714 
8715 	*xpp = (void *)xp;
8716 	return status;
8717 }
8718 
8719 int
ncx_pad_getn_short_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)8720 ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
8721 {
8722 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8723 
8724 	const char *xp = (const char *) *xpp;
8725 	int status = NC_NOERR;
8726 
8727 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8728 	{
8729 		const int lstatus = ncx_get_short_ulonglong(xp, tp);
8730 		if (status == NC_NOERR) /* report the first encountered error */
8731 			status = lstatus;
8732 	}
8733 
8734 	if (rndup != 0)
8735 		xp += X_SIZEOF_SHORT;
8736 
8737 	*xpp = (void *)xp;
8738 	return status;
8739 }
8740 
8741 int
ncx_pad_getn_short_ushort(const void ** xpp,size_t nelems,ushort * tp)8742 ncx_pad_getn_short_ushort(const void **xpp, size_t nelems, ushort *tp)
8743 {
8744 	const size_t rndup = nelems % X_SIZEOF_SHORT;
8745 
8746 	const char *xp = (const char *) *xpp;
8747 	int status = NC_NOERR;
8748 
8749 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8750 	{
8751 		const int lstatus = ncx_get_short_ushort(xp, tp);
8752 		if (status == NC_NOERR) /* report the first encountered error */
8753 			status = lstatus;
8754 	}
8755 
8756 	if (rndup != 0)
8757 		xp += X_SIZEOF_SHORT;
8758 
8759 	*xpp = (void *)xp;
8760 	return status;
8761 }
8762 
8763 
8764 #if X_SIZEOF_SHORT == SIZEOF_SHORT
8765 /* optimized version */
8766 int
ncx_putn_short_short(void ** xpp,size_t nelems,const short * tp,void * fillp)8767 ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8768 {
8769 #ifdef WORDS_BIGENDIAN
8770 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
8771 # else
8772 	swapn2b(*xpp, tp, nelems);
8773 # endif
8774 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
8775 	return NC_NOERR;
8776 }
8777 #else
8778 int
ncx_putn_short_short(void ** xpp,size_t nelems,const short * tp,void * fillp)8779 ncx_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
8780 {
8781 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8782 
8783  /* basic algorithm is:
8784   *   - ensure sane alignment of output data
8785   *   - copy (conversion happens automatically) input data
8786   *     to output
8787   *   - update tp to point at next unconverted input, and xpp to point
8788   *     at next location for converted output
8789   */
8790   long i, j, ni;
8791   short tmp[LOOPCNT];        /* in case input is misaligned */
8792   short *xp;
8793   int nrange = 0;         /* number of range errors */
8794   int realign = 0;        /* "do we need to fix input data alignment?" */
8795   long cxp = (long) *((char**)xpp);
8796 
8797   realign = (cxp & 7) % SIZEOF_SHORT;
8798   /* sjl: manually stripmine so we can limit amount of
8799    * vector work space reserved to LOOPCNT elements. Also
8800    * makes vectorisation easy */
8801   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8802     ni=Min(nelems-j,LOOPCNT);
8803     if (realign) {
8804       xp = tmp;
8805     } else {
8806       xp = (short *) *xpp;
8807     }
8808    /* copy the next block */
8809 #pragma cdir loopcnt=LOOPCNT
8810 #pragma cdir shortloop
8811     for (i=0; i<ni; i++) {
8812       /* the normal case: */
8813       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8814      /* test for range errors (not always needed but do it anyway) */
8815      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8816      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8817       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8818     }
8819    /* copy workspace back if necessary */
8820     if (realign) {
8821       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8822       xp = (short *) *xpp;
8823     }
8824    /* update xpp and tp */
8825     xp += ni;
8826     tp += ni;
8827     *xpp = (void*)xp;
8828   }
8829   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8830 
8831 #else   /* not SX */
8832 
8833 	char *xp = (char *) *xpp;
8834 	int status = NC_NOERR;
8835 
8836 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8837 	{
8838 		int lstatus = ncx_put_short_short(xp, tp, fillp);
8839 		if (status == NC_NOERR) /* report the first encountered error */
8840 			status = lstatus;
8841 	}
8842 
8843 	*xpp = (void *)xp;
8844 	return status;
8845 #endif
8846 }
8847 
8848 #endif
8849 int
ncx_putn_short_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)8850 ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
8851 {
8852 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8853 
8854  /* basic algorithm is:
8855   *   - ensure sane alignment of output data
8856   *   - copy (conversion happens automatically) input data
8857   *     to output
8858   *   - update tp to point at next unconverted input, and xpp to point
8859   *     at next location for converted output
8860   */
8861   long i, j, ni;
8862   short tmp[LOOPCNT];        /* in case input is misaligned */
8863   short *xp;
8864   int nrange = 0;         /* number of range errors */
8865   int realign = 0;        /* "do we need to fix input data alignment?" */
8866   long cxp = (long) *((char**)xpp);
8867 
8868   realign = (cxp & 7) % SIZEOF_SHORT;
8869   /* sjl: manually stripmine so we can limit amount of
8870    * vector work space reserved to LOOPCNT elements. Also
8871    * makes vectorisation easy */
8872   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8873     ni=Min(nelems-j,LOOPCNT);
8874     if (realign) {
8875       xp = tmp;
8876     } else {
8877       xp = (short *) *xpp;
8878     }
8879    /* copy the next block */
8880 #pragma cdir loopcnt=LOOPCNT
8881 #pragma cdir shortloop
8882     for (i=0; i<ni; i++) {
8883       /* the normal case: */
8884       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8885      /* test for range errors (not always needed but do it anyway) */
8886      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8887      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8888       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8889     }
8890    /* copy workspace back if necessary */
8891     if (realign) {
8892       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8893       xp = (short *) *xpp;
8894     }
8895    /* update xpp and tp */
8896     xp += ni;
8897     tp += ni;
8898     *xpp = (void*)xp;
8899   }
8900   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8901 
8902 #else   /* not SX */
8903 
8904 	char *xp = (char *) *xpp;
8905 	int status = NC_NOERR;
8906 
8907 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8908 	{
8909 		int lstatus = ncx_put_short_schar(xp, tp, fillp);
8910 		if (status == NC_NOERR) /* report the first encountered error */
8911 			status = lstatus;
8912 	}
8913 
8914 	*xpp = (void *)xp;
8915 	return status;
8916 #endif
8917 }
8918 
8919 int
ncx_putn_short_int(void ** xpp,size_t nelems,const int * tp,void * fillp)8920 ncx_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
8921 {
8922 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8923 
8924  /* basic algorithm is:
8925   *   - ensure sane alignment of output data
8926   *   - copy (conversion happens automatically) input data
8927   *     to output
8928   *   - update tp to point at next unconverted input, and xpp to point
8929   *     at next location for converted output
8930   */
8931   long i, j, ni;
8932   short tmp[LOOPCNT];        /* in case input is misaligned */
8933   short *xp;
8934   int nrange = 0;         /* number of range errors */
8935   int realign = 0;        /* "do we need to fix input data alignment?" */
8936   long cxp = (long) *((char**)xpp);
8937 
8938   realign = (cxp & 7) % SIZEOF_SHORT;
8939   /* sjl: manually stripmine so we can limit amount of
8940    * vector work space reserved to LOOPCNT elements. Also
8941    * makes vectorisation easy */
8942   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
8943     ni=Min(nelems-j,LOOPCNT);
8944     if (realign) {
8945       xp = tmp;
8946     } else {
8947       xp = (short *) *xpp;
8948     }
8949    /* copy the next block */
8950 #pragma cdir loopcnt=LOOPCNT
8951 #pragma cdir shortloop
8952     for (i=0; i<ni; i++) {
8953       /* the normal case: */
8954       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
8955      /* test for range errors (not always needed but do it anyway) */
8956      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
8957      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
8958       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
8959     }
8960    /* copy workspace back if necessary */
8961     if (realign) {
8962       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
8963       xp = (short *) *xpp;
8964     }
8965    /* update xpp and tp */
8966     xp += ni;
8967     tp += ni;
8968     *xpp = (void*)xp;
8969   }
8970   return nrange == 0 ? NC_NOERR : NC_ERANGE;
8971 
8972 #else   /* not SX */
8973 
8974 	char *xp = (char *) *xpp;
8975 	int status = NC_NOERR;
8976 
8977 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
8978 	{
8979 		int lstatus = ncx_put_short_int(xp, tp, fillp);
8980 		if (status == NC_NOERR) /* report the first encountered error */
8981 			status = lstatus;
8982 	}
8983 
8984 	*xpp = (void *)xp;
8985 	return status;
8986 #endif
8987 }
8988 
8989 int
ncx_putn_short_long(void ** xpp,size_t nelems,const long * tp,void * fillp)8990 ncx_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
8991 {
8992 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
8993 
8994  /* basic algorithm is:
8995   *   - ensure sane alignment of output data
8996   *   - copy (conversion happens automatically) input data
8997   *     to output
8998   *   - update tp to point at next unconverted input, and xpp to point
8999   *     at next location for converted output
9000   */
9001   long i, j, ni;
9002   short tmp[LOOPCNT];        /* in case input is misaligned */
9003   short *xp;
9004   int nrange = 0;         /* number of range errors */
9005   int realign = 0;        /* "do we need to fix input data alignment?" */
9006   long cxp = (long) *((char**)xpp);
9007 
9008   realign = (cxp & 7) % SIZEOF_SHORT;
9009   /* sjl: manually stripmine so we can limit amount of
9010    * vector work space reserved to LOOPCNT elements. Also
9011    * makes vectorisation easy */
9012   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9013     ni=Min(nelems-j,LOOPCNT);
9014     if (realign) {
9015       xp = tmp;
9016     } else {
9017       xp = (short *) *xpp;
9018     }
9019    /* copy the next block */
9020 #pragma cdir loopcnt=LOOPCNT
9021 #pragma cdir shortloop
9022     for (i=0; i<ni; i++) {
9023       /* the normal case: */
9024       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9025      /* test for range errors (not always needed but do it anyway) */
9026      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9027      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9028       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9029     }
9030    /* copy workspace back if necessary */
9031     if (realign) {
9032       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9033       xp = (short *) *xpp;
9034     }
9035    /* update xpp and tp */
9036     xp += ni;
9037     tp += ni;
9038     *xpp = (void*)xp;
9039   }
9040   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9041 
9042 #else   /* not SX */
9043 
9044 	char *xp = (char *) *xpp;
9045 	int status = NC_NOERR;
9046 
9047 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9048 	{
9049 		int lstatus = ncx_put_short_long(xp, tp, fillp);
9050 		if (status == NC_NOERR) /* report the first encountered error */
9051 			status = lstatus;
9052 	}
9053 
9054 	*xpp = (void *)xp;
9055 	return status;
9056 #endif
9057 }
9058 
9059 int
ncx_putn_short_float(void ** xpp,size_t nelems,const float * tp,void * fillp)9060 ncx_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9061 {
9062 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9063 
9064  /* basic algorithm is:
9065   *   - ensure sane alignment of output data
9066   *   - copy (conversion happens automatically) input data
9067   *     to output
9068   *   - update tp to point at next unconverted input, and xpp to point
9069   *     at next location for converted output
9070   */
9071   long i, j, ni;
9072   short tmp[LOOPCNT];        /* in case input is misaligned */
9073   short *xp;
9074   int nrange = 0;         /* number of range errors */
9075   int realign = 0;        /* "do we need to fix input data alignment?" */
9076   long cxp = (long) *((char**)xpp);
9077 
9078   realign = (cxp & 7) % SIZEOF_SHORT;
9079   /* sjl: manually stripmine so we can limit amount of
9080    * vector work space reserved to LOOPCNT elements. Also
9081    * makes vectorisation easy */
9082   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9083     ni=Min(nelems-j,LOOPCNT);
9084     if (realign) {
9085       xp = tmp;
9086     } else {
9087       xp = (short *) *xpp;
9088     }
9089    /* copy the next block */
9090 #pragma cdir loopcnt=LOOPCNT
9091 #pragma cdir shortloop
9092     for (i=0; i<ni; i++) {
9093       /* the normal case: */
9094       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9095      /* test for range errors (not always needed but do it anyway) */
9096      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9097      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9098       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9099     }
9100    /* copy workspace back if necessary */
9101     if (realign) {
9102       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9103       xp = (short *) *xpp;
9104     }
9105    /* update xpp and tp */
9106     xp += ni;
9107     tp += ni;
9108     *xpp = (void*)xp;
9109   }
9110   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9111 
9112 #else   /* not SX */
9113 
9114 	char *xp = (char *) *xpp;
9115 	int status = NC_NOERR;
9116 
9117 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9118 	{
9119 		int lstatus = ncx_put_short_float(xp, tp, fillp);
9120 		if (status == NC_NOERR) /* report the first encountered error */
9121 			status = lstatus;
9122 	}
9123 
9124 	*xpp = (void *)xp;
9125 	return status;
9126 #endif
9127 }
9128 
9129 int
ncx_putn_short_double(void ** xpp,size_t nelems,const double * tp,void * fillp)9130 ncx_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9131 {
9132 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9133 
9134  /* basic algorithm is:
9135   *   - ensure sane alignment of output data
9136   *   - copy (conversion happens automatically) input data
9137   *     to output
9138   *   - update tp to point at next unconverted input, and xpp to point
9139   *     at next location for converted output
9140   */
9141   long i, j, ni;
9142   short tmp[LOOPCNT];        /* in case input is misaligned */
9143   short *xp;
9144   int nrange = 0;         /* number of range errors */
9145   int realign = 0;        /* "do we need to fix input data alignment?" */
9146   long cxp = (long) *((char**)xpp);
9147 
9148   realign = (cxp & 7) % SIZEOF_SHORT;
9149   /* sjl: manually stripmine so we can limit amount of
9150    * vector work space reserved to LOOPCNT elements. Also
9151    * makes vectorisation easy */
9152   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9153     ni=Min(nelems-j,LOOPCNT);
9154     if (realign) {
9155       xp = tmp;
9156     } else {
9157       xp = (short *) *xpp;
9158     }
9159    /* copy the next block */
9160 #pragma cdir loopcnt=LOOPCNT
9161 #pragma cdir shortloop
9162     for (i=0; i<ni; i++) {
9163       /* the normal case: */
9164       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9165      /* test for range errors (not always needed but do it anyway) */
9166      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9167      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9168       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9169     }
9170    /* copy workspace back if necessary */
9171     if (realign) {
9172       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9173       xp = (short *) *xpp;
9174     }
9175    /* update xpp and tp */
9176     xp += ni;
9177     tp += ni;
9178     *xpp = (void*)xp;
9179   }
9180   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9181 
9182 #else   /* not SX */
9183 
9184 	char *xp = (char *) *xpp;
9185 	int status = NC_NOERR;
9186 
9187 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9188 	{
9189 		int lstatus = ncx_put_short_double(xp, tp, fillp);
9190 		if (status == NC_NOERR) /* report the first encountered error */
9191 			status = lstatus;
9192 	}
9193 
9194 	*xpp = (void *)xp;
9195 	return status;
9196 #endif
9197 }
9198 
9199 int
ncx_putn_short_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)9200 ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9201 {
9202 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9203 
9204  /* basic algorithm is:
9205   *   - ensure sane alignment of output data
9206   *   - copy (conversion happens automatically) input data
9207   *     to output
9208   *   - update tp to point at next unconverted input, and xpp to point
9209   *     at next location for converted output
9210   */
9211   long i, j, ni;
9212   short tmp[LOOPCNT];        /* in case input is misaligned */
9213   short *xp;
9214   int nrange = 0;         /* number of range errors */
9215   int realign = 0;        /* "do we need to fix input data alignment?" */
9216   long cxp = (long) *((char**)xpp);
9217 
9218   realign = (cxp & 7) % SIZEOF_SHORT;
9219   /* sjl: manually stripmine so we can limit amount of
9220    * vector work space reserved to LOOPCNT elements. Also
9221    * makes vectorisation easy */
9222   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9223     ni=Min(nelems-j,LOOPCNT);
9224     if (realign) {
9225       xp = tmp;
9226     } else {
9227       xp = (short *) *xpp;
9228     }
9229    /* copy the next block */
9230 #pragma cdir loopcnt=LOOPCNT
9231 #pragma cdir shortloop
9232     for (i=0; i<ni; i++) {
9233       /* the normal case: */
9234       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9235      /* test for range errors (not always needed but do it anyway) */
9236      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9237      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9238       nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
9239     }
9240    /* copy workspace back if necessary */
9241     if (realign) {
9242       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9243       xp = (short *) *xpp;
9244     }
9245    /* update xpp and tp */
9246     xp += ni;
9247     tp += ni;
9248     *xpp = (void*)xp;
9249   }
9250   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9251 
9252 #else   /* not SX */
9253 
9254 	char *xp = (char *) *xpp;
9255 	int status = NC_NOERR;
9256 
9257 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9258 	{
9259 		int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9260 		if (status == NC_NOERR) /* report the first encountered error */
9261 			status = lstatus;
9262 	}
9263 
9264 	*xpp = (void *)xp;
9265 	return status;
9266 #endif
9267 }
9268 
9269 int
ncx_putn_short_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)9270 ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9271 {
9272 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9273 
9274  /* basic algorithm is:
9275   *   - ensure sane alignment of output data
9276   *   - copy (conversion happens automatically) input data
9277   *     to output
9278   *   - update tp to point at next unconverted input, and xpp to point
9279   *     at next location for converted output
9280   */
9281   long i, j, ni;
9282   short tmp[LOOPCNT];        /* in case input is misaligned */
9283   short *xp;
9284   int nrange = 0;         /* number of range errors */
9285   int realign = 0;        /* "do we need to fix input data alignment?" */
9286   long cxp = (long) *((char**)xpp);
9287 
9288   realign = (cxp & 7) % SIZEOF_SHORT;
9289   /* sjl: manually stripmine so we can limit amount of
9290    * vector work space reserved to LOOPCNT elements. Also
9291    * makes vectorisation easy */
9292   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9293     ni=Min(nelems-j,LOOPCNT);
9294     if (realign) {
9295       xp = tmp;
9296     } else {
9297       xp = (short *) *xpp;
9298     }
9299    /* copy the next block */
9300 #pragma cdir loopcnt=LOOPCNT
9301 #pragma cdir shortloop
9302     for (i=0; i<ni; i++) {
9303       /* the normal case: */
9304       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9305      /* test for range errors (not always needed but do it anyway) */
9306      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9307      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9308       nrange += tp[i] > X_SHORT_MAX ;
9309     }
9310    /* copy workspace back if necessary */
9311     if (realign) {
9312       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9313       xp = (short *) *xpp;
9314     }
9315    /* update xpp and tp */
9316     xp += ni;
9317     tp += ni;
9318     *xpp = (void*)xp;
9319   }
9320   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9321 
9322 #else   /* not SX */
9323 
9324 	char *xp = (char *) *xpp;
9325 	int status = NC_NOERR;
9326 
9327 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9328 	{
9329 		int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9330 		if (status == NC_NOERR) /* report the first encountered error */
9331 			status = lstatus;
9332 	}
9333 
9334 	*xpp = (void *)xp;
9335 	return status;
9336 #endif
9337 }
9338 
9339 int
ncx_putn_short_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)9340 ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9341 {
9342 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9343 
9344  /* basic algorithm is:
9345   *   - ensure sane alignment of output data
9346   *   - copy (conversion happens automatically) input data
9347   *     to output
9348   *   - update tp to point at next unconverted input, and xpp to point
9349   *     at next location for converted output
9350   */
9351   long i, j, ni;
9352   short tmp[LOOPCNT];        /* in case input is misaligned */
9353   short *xp;
9354   int nrange = 0;         /* number of range errors */
9355   int realign = 0;        /* "do we need to fix input data alignment?" */
9356   long cxp = (long) *((char**)xpp);
9357 
9358   realign = (cxp & 7) % SIZEOF_SHORT;
9359   /* sjl: manually stripmine so we can limit amount of
9360    * vector work space reserved to LOOPCNT elements. Also
9361    * makes vectorisation easy */
9362   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9363     ni=Min(nelems-j,LOOPCNT);
9364     if (realign) {
9365       xp = tmp;
9366     } else {
9367       xp = (short *) *xpp;
9368     }
9369    /* copy the next block */
9370 #pragma cdir loopcnt=LOOPCNT
9371 #pragma cdir shortloop
9372     for (i=0; i<ni; i++) {
9373       /* the normal case: */
9374       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9375      /* test for range errors (not always needed but do it anyway) */
9376      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9377      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9378       nrange += tp[i] > X_SHORT_MAX ;
9379     }
9380    /* copy workspace back if necessary */
9381     if (realign) {
9382       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9383       xp = (short *) *xpp;
9384     }
9385    /* update xpp and tp */
9386     xp += ni;
9387     tp += ni;
9388     *xpp = (void*)xp;
9389   }
9390   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9391 
9392 #else   /* not SX */
9393 
9394 	char *xp = (char *) *xpp;
9395 	int status = NC_NOERR;
9396 
9397 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9398 	{
9399 		int lstatus = ncx_put_short_uint(xp, tp, fillp);
9400 		if (status == NC_NOERR) /* report the first encountered error */
9401 			status = lstatus;
9402 	}
9403 
9404 	*xpp = (void *)xp;
9405 	return status;
9406 #endif
9407 }
9408 
9409 int
ncx_putn_short_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)9410 ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9411 {
9412 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9413 
9414  /* basic algorithm is:
9415   *   - ensure sane alignment of output data
9416   *   - copy (conversion happens automatically) input data
9417   *     to output
9418   *   - update tp to point at next unconverted input, and xpp to point
9419   *     at next location for converted output
9420   */
9421   long i, j, ni;
9422   short tmp[LOOPCNT];        /* in case input is misaligned */
9423   short *xp;
9424   int nrange = 0;         /* number of range errors */
9425   int realign = 0;        /* "do we need to fix input data alignment?" */
9426   long cxp = (long) *((char**)xpp);
9427 
9428   realign = (cxp & 7) % SIZEOF_SHORT;
9429   /* sjl: manually stripmine so we can limit amount of
9430    * vector work space reserved to LOOPCNT elements. Also
9431    * makes vectorisation easy */
9432   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9433     ni=Min(nelems-j,LOOPCNT);
9434     if (realign) {
9435       xp = tmp;
9436     } else {
9437       xp = (short *) *xpp;
9438     }
9439    /* copy the next block */
9440 #pragma cdir loopcnt=LOOPCNT
9441 #pragma cdir shortloop
9442     for (i=0; i<ni; i++) {
9443       /* the normal case: */
9444       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9445      /* test for range errors (not always needed but do it anyway) */
9446      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9447      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9448       nrange += tp[i] > X_SHORT_MAX ;
9449     }
9450    /* copy workspace back if necessary */
9451     if (realign) {
9452       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9453       xp = (short *) *xpp;
9454     }
9455    /* update xpp and tp */
9456     xp += ni;
9457     tp += ni;
9458     *xpp = (void*)xp;
9459   }
9460   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9461 
9462 #else   /* not SX */
9463 
9464 	char *xp = (char *) *xpp;
9465 	int status = NC_NOERR;
9466 
9467 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9468 	{
9469 		int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9470 		if (status == NC_NOERR) /* report the first encountered error */
9471 			status = lstatus;
9472 	}
9473 
9474 	*xpp = (void *)xp;
9475 	return status;
9476 #endif
9477 }
9478 
9479 int
ncx_putn_short_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)9480 ncx_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9481 {
9482 #if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT
9483 
9484  /* basic algorithm is:
9485   *   - ensure sane alignment of output data
9486   *   - copy (conversion happens automatically) input data
9487   *     to output
9488   *   - update tp to point at next unconverted input, and xpp to point
9489   *     at next location for converted output
9490   */
9491   long i, j, ni;
9492   short tmp[LOOPCNT];        /* in case input is misaligned */
9493   short *xp;
9494   int nrange = 0;         /* number of range errors */
9495   int realign = 0;        /* "do we need to fix input data alignment?" */
9496   long cxp = (long) *((char**)xpp);
9497 
9498   realign = (cxp & 7) % SIZEOF_SHORT;
9499   /* sjl: manually stripmine so we can limit amount of
9500    * vector work space reserved to LOOPCNT elements. Also
9501    * makes vectorisation easy */
9502   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9503     ni=Min(nelems-j,LOOPCNT);
9504     if (realign) {
9505       xp = tmp;
9506     } else {
9507       xp = (short *) *xpp;
9508     }
9509    /* copy the next block */
9510 #pragma cdir loopcnt=LOOPCNT
9511 #pragma cdir shortloop
9512     for (i=0; i<ni; i++) {
9513       /* the normal case: */
9514       xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
9515      /* test for range errors (not always needed but do it anyway) */
9516      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
9517      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
9518       nrange += tp[i] > X_SHORT_MAX ;
9519     }
9520    /* copy workspace back if necessary */
9521     if (realign) {
9522       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
9523       xp = (short *) *xpp;
9524     }
9525    /* update xpp and tp */
9526     xp += ni;
9527     tp += ni;
9528     *xpp = (void*)xp;
9529   }
9530   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9531 
9532 #else   /* not SX */
9533 
9534 	char *xp = (char *) *xpp;
9535 	int status = NC_NOERR;
9536 
9537 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9538 	{
9539 		int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9540 		if (status == NC_NOERR) /* report the first encountered error */
9541 			status = lstatus;
9542 	}
9543 
9544 	*xpp = (void *)xp;
9545 	return status;
9546 #endif
9547 }
9548 
9549 
9550 int
ncx_pad_putn_short_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)9551 ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
9552 {
9553 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9554 
9555 	char *xp = (char *) *xpp;
9556 	int status = NC_NOERR;
9557 
9558 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9559 	{
9560 		int lstatus = ncx_put_short_schar(xp, tp, fillp);
9561 		if (status == NC_NOERR) /* report the first encountered error */
9562 			status = lstatus;
9563 	}
9564 
9565 	if (rndup != 0)
9566 	{
9567 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9568 		xp += X_SIZEOF_SHORT;
9569 	}
9570 
9571 	*xpp = (void *)xp;
9572 	return status;
9573 }
9574 
9575 int
ncx_pad_putn_short_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)9576 ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
9577 {
9578 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9579 
9580 	char *xp = (char *) *xpp;
9581 	int status = NC_NOERR;
9582 
9583 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9584 	{
9585 		int lstatus = ncx_put_short_uchar(xp, tp, fillp);
9586 		if (status == NC_NOERR) /* report the first encountered error */
9587 			status = lstatus;
9588 	}
9589 
9590 	if (rndup != 0)
9591 	{
9592 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9593 		xp += X_SIZEOF_SHORT;
9594 	}
9595 
9596 	*xpp = (void *)xp;
9597 	return status;
9598 }
9599 
9600 int
ncx_pad_putn_short_short(void ** xpp,size_t nelems,const short * tp,void * fillp)9601 ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp, void *fillp)
9602 {
9603 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9604 
9605 	char *xp = (char *) *xpp;
9606 	int status = NC_NOERR;
9607 
9608 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9609 	{
9610 		int lstatus = ncx_put_short_short(xp, tp, fillp);
9611 		if (status == NC_NOERR) /* report the first encountered error */
9612 			status = lstatus;
9613 	}
9614 
9615 	if (rndup != 0)
9616 	{
9617 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9618 		xp += X_SIZEOF_SHORT;
9619 	}
9620 
9621 	*xpp = (void *)xp;
9622 	return status;
9623 }
9624 
9625 int
ncx_pad_putn_short_int(void ** xpp,size_t nelems,const int * tp,void * fillp)9626 ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp, void *fillp)
9627 {
9628 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9629 
9630 	char *xp = (char *) *xpp;
9631 	int status = NC_NOERR;
9632 
9633 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9634 	{
9635 		int lstatus = ncx_put_short_int(xp, tp, fillp);
9636 		if (status == NC_NOERR) /* report the first encountered error */
9637 			status = lstatus;
9638 	}
9639 
9640 	if (rndup != 0)
9641 	{
9642 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9643 		xp += X_SIZEOF_SHORT;
9644 	}
9645 
9646 	*xpp = (void *)xp;
9647 	return status;
9648 }
9649 
9650 int
ncx_pad_putn_short_long(void ** xpp,size_t nelems,const long * tp,void * fillp)9651 ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp, void *fillp)
9652 {
9653 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9654 
9655 	char *xp = (char *) *xpp;
9656 	int status = NC_NOERR;
9657 
9658 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9659 	{
9660 		int lstatus = ncx_put_short_long(xp, tp, fillp);
9661 		if (status == NC_NOERR) /* report the first encountered error */
9662 			status = lstatus;
9663 	}
9664 
9665 	if (rndup != 0)
9666 	{
9667 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9668 		xp += X_SIZEOF_SHORT;
9669 	}
9670 
9671 	*xpp = (void *)xp;
9672 	return status;
9673 }
9674 
9675 int
ncx_pad_putn_short_float(void ** xpp,size_t nelems,const float * tp,void * fillp)9676 ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp, void *fillp)
9677 {
9678 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9679 
9680 	char *xp = (char *) *xpp;
9681 	int status = NC_NOERR;
9682 
9683 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9684 	{
9685 		int lstatus = ncx_put_short_float(xp, tp, fillp);
9686 		if (status == NC_NOERR) /* report the first encountered error */
9687 			status = lstatus;
9688 	}
9689 
9690 	if (rndup != 0)
9691 	{
9692 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9693 		xp += X_SIZEOF_SHORT;
9694 	}
9695 
9696 	*xpp = (void *)xp;
9697 	return status;
9698 }
9699 
9700 int
ncx_pad_putn_short_double(void ** xpp,size_t nelems,const double * tp,void * fillp)9701 ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp, void *fillp)
9702 {
9703 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9704 
9705 	char *xp = (char *) *xpp;
9706 	int status = NC_NOERR;
9707 
9708 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9709 	{
9710 		int lstatus = ncx_put_short_double(xp, tp, fillp);
9711 		if (status == NC_NOERR) /* report the first encountered error */
9712 			status = lstatus;
9713 	}
9714 
9715 	if (rndup != 0)
9716 	{
9717 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9718 		xp += X_SIZEOF_SHORT;
9719 	}
9720 
9721 	*xpp = (void *)xp;
9722 	return status;
9723 }
9724 
9725 int
ncx_pad_putn_short_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)9726 ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
9727 {
9728 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9729 
9730 	char *xp = (char *) *xpp;
9731 	int status = NC_NOERR;
9732 
9733 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9734 	{
9735 		int lstatus = ncx_put_short_uint(xp, tp, fillp);
9736 		if (status == NC_NOERR) /* report the first encountered error */
9737 			status = lstatus;
9738 	}
9739 
9740 	if (rndup != 0)
9741 	{
9742 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9743 		xp += X_SIZEOF_SHORT;
9744 	}
9745 
9746 	*xpp = (void *)xp;
9747 	return status;
9748 }
9749 
9750 int
ncx_pad_putn_short_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)9751 ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
9752 {
9753 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9754 
9755 	char *xp = (char *) *xpp;
9756 	int status = NC_NOERR;
9757 
9758 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9759 	{
9760 		int lstatus = ncx_put_short_longlong(xp, tp, fillp);
9761 		if (status == NC_NOERR) /* report the first encountered error */
9762 			status = lstatus;
9763 	}
9764 
9765 	if (rndup != 0)
9766 	{
9767 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9768 		xp += X_SIZEOF_SHORT;
9769 	}
9770 
9771 	*xpp = (void *)xp;
9772 	return status;
9773 }
9774 
9775 int
ncx_pad_putn_short_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)9776 ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
9777 {
9778 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9779 
9780 	char *xp = (char *) *xpp;
9781 	int status = NC_NOERR;
9782 
9783 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9784 	{
9785 		int lstatus = ncx_put_short_ulonglong(xp, tp, fillp);
9786 		if (status == NC_NOERR) /* report the first encountered error */
9787 			status = lstatus;
9788 	}
9789 
9790 	if (rndup != 0)
9791 	{
9792 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9793 		xp += X_SIZEOF_SHORT;
9794 	}
9795 
9796 	*xpp = (void *)xp;
9797 	return status;
9798 }
9799 
9800 int
ncx_pad_putn_short_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)9801 ncx_pad_putn_short_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
9802 {
9803 	const size_t rndup = nelems % X_SIZEOF_SHORT;
9804 
9805 	char *xp = (char *) *xpp;
9806 	int status = NC_NOERR;
9807 
9808 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
9809 	{
9810 		int lstatus = ncx_put_short_ushort(xp, tp, fillp);
9811 		if (status == NC_NOERR) /* report the first encountered error */
9812 			status = lstatus;
9813 	}
9814 
9815 	if (rndup != 0)
9816 	{
9817 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
9818 		xp += X_SIZEOF_SHORT;
9819 	}
9820 
9821 	*xpp = (void *)xp;
9822 	return status;
9823 }
9824 
9825 
9826 
9827 /* ushort --------------------------------------------------------------------*/
9828 
9829 #if X_SIZEOF_USHORT == SIZEOF_USHORT
9830 /* optimized version */
9831 int
ncx_getn_ushort_ushort(const void ** xpp,size_t nelems,unsigned short * tp)9832 ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
9833 {
9834 #ifdef WORDS_BIGENDIAN
9835 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
9836 # else
9837 	swapn2b(tp, *xpp, nelems);
9838 # endif
9839 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
9840 	return NC_NOERR;
9841 }
9842 #else
9843 int
ncx_getn_ushort_ushort(const void ** xpp,size_t nelems,ushort * tp)9844 ncx_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
9845 {
9846 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9847 
9848  /* basic algorithm is:
9849   *   - ensure sane alignment of input data
9850   *   - copy (conversion happens automatically) input data
9851   *     to output
9852   *   - update xpp to point at next unconverted input, and tp to point
9853   *     at next location for converted output
9854   */
9855   long i, j, ni;
9856   ushort tmp[LOOPCNT];        /* in case input is misaligned */
9857   ushort *xp;
9858   int nrange = 0;         /* number of range errors */
9859   int realign = 0;        /* "do we need to fix input data alignment?" */
9860   long cxp = (long) *((char**)xpp);
9861 
9862   realign = (cxp & 7) % SIZEOF_USHORT;
9863   /* sjl: manually stripmine so we can limit amount of
9864    * vector work space reserved to LOOPCNT elements. Also
9865    * makes vectorisation easy */
9866   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9867     ni=Min(nelems-j,LOOPCNT);
9868     if (realign) {
9869       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9870       xp = tmp;
9871     } else {
9872       xp = (ushort *) *xpp;
9873     }
9874    /* copy the next block */
9875 #pragma cdir loopcnt=LOOPCNT
9876 #pragma cdir shortloop
9877     for (i=0; i<ni; i++) {
9878       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
9879      /* test for range errors (not always needed but do it anyway) */
9880      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9881      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9882       nrange += xp[i] > USHORT_MAX ;
9883     }
9884    /* update xpp and tp */
9885     if (realign) xp = (ushort *) *xpp;
9886     xp += ni;
9887     tp += ni;
9888     *xpp = (void*)xp;
9889   }
9890   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9891 
9892 #else   /* not SX */
9893 	const char *xp = (const char *) *xpp;
9894 	int status = NC_NOERR;
9895 
9896 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9897 	{
9898 		const int lstatus = ncx_get_ushort_ushort(xp, tp);
9899 		if (status == NC_NOERR) /* report the first encountered error */
9900 			status = lstatus;
9901 	}
9902 
9903 	*xpp = (const void *)xp;
9904 	return status;
9905 #endif
9906 }
9907 
9908 #endif
9909 int
ncx_getn_ushort_schar(const void ** xpp,size_t nelems,schar * tp)9910 ncx_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
9911 {
9912 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9913 
9914  /* basic algorithm is:
9915   *   - ensure sane alignment of input data
9916   *   - copy (conversion happens automatically) input data
9917   *     to output
9918   *   - update xpp to point at next unconverted input, and tp to point
9919   *     at next location for converted output
9920   */
9921   long i, j, ni;
9922   ushort tmp[LOOPCNT];        /* in case input is misaligned */
9923   ushort *xp;
9924   int nrange = 0;         /* number of range errors */
9925   int realign = 0;        /* "do we need to fix input data alignment?" */
9926   long cxp = (long) *((char**)xpp);
9927 
9928   realign = (cxp & 7) % SIZEOF_USHORT;
9929   /* sjl: manually stripmine so we can limit amount of
9930    * vector work space reserved to LOOPCNT elements. Also
9931    * makes vectorisation easy */
9932   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9933     ni=Min(nelems-j,LOOPCNT);
9934     if (realign) {
9935       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
9936       xp = tmp;
9937     } else {
9938       xp = (ushort *) *xpp;
9939     }
9940    /* copy the next block */
9941 #pragma cdir loopcnt=LOOPCNT
9942 #pragma cdir shortloop
9943     for (i=0; i<ni; i++) {
9944       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
9945      /* test for range errors (not always needed but do it anyway) */
9946      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
9947      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
9948       nrange += xp[i] > SCHAR_MAX ;
9949     }
9950    /* update xpp and tp */
9951     if (realign) xp = (ushort *) *xpp;
9952     xp += ni;
9953     tp += ni;
9954     *xpp = (void*)xp;
9955   }
9956   return nrange == 0 ? NC_NOERR : NC_ERANGE;
9957 
9958 #else   /* not SX */
9959 	const char *xp = (const char *) *xpp;
9960 	int status = NC_NOERR;
9961 
9962 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
9963 	{
9964 		const int lstatus = ncx_get_ushort_schar(xp, tp);
9965 		if (status == NC_NOERR) /* report the first encountered error */
9966 			status = lstatus;
9967 	}
9968 
9969 	*xpp = (const void *)xp;
9970 	return status;
9971 #endif
9972 }
9973 
9974 int
ncx_getn_ushort_short(const void ** xpp,size_t nelems,short * tp)9975 ncx_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
9976 {
9977 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
9978 
9979  /* basic algorithm is:
9980   *   - ensure sane alignment of input data
9981   *   - copy (conversion happens automatically) input data
9982   *     to output
9983   *   - update xpp to point at next unconverted input, and tp to point
9984   *     at next location for converted output
9985   */
9986   long i, j, ni;
9987   ushort tmp[LOOPCNT];        /* in case input is misaligned */
9988   ushort *xp;
9989   int nrange = 0;         /* number of range errors */
9990   int realign = 0;        /* "do we need to fix input data alignment?" */
9991   long cxp = (long) *((char**)xpp);
9992 
9993   realign = (cxp & 7) % SIZEOF_USHORT;
9994   /* sjl: manually stripmine so we can limit amount of
9995    * vector work space reserved to LOOPCNT elements. Also
9996    * makes vectorisation easy */
9997   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
9998     ni=Min(nelems-j,LOOPCNT);
9999     if (realign) {
10000       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10001       xp = tmp;
10002     } else {
10003       xp = (ushort *) *xpp;
10004     }
10005    /* copy the next block */
10006 #pragma cdir loopcnt=LOOPCNT
10007 #pragma cdir shortloop
10008     for (i=0; i<ni; i++) {
10009       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
10010      /* test for range errors (not always needed but do it anyway) */
10011      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10012      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10013       nrange += xp[i] > SHORT_MAX ;
10014     }
10015    /* update xpp and tp */
10016     if (realign) xp = (ushort *) *xpp;
10017     xp += ni;
10018     tp += ni;
10019     *xpp = (void*)xp;
10020   }
10021   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10022 
10023 #else   /* not SX */
10024 	const char *xp = (const char *) *xpp;
10025 	int status = NC_NOERR;
10026 
10027 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10028 	{
10029 		const int lstatus = ncx_get_ushort_short(xp, tp);
10030 		if (status == NC_NOERR) /* report the first encountered error */
10031 			status = lstatus;
10032 	}
10033 
10034 	*xpp = (const void *)xp;
10035 	return status;
10036 #endif
10037 }
10038 
10039 int
ncx_getn_ushort_int(const void ** xpp,size_t nelems,int * tp)10040 ncx_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10041 {
10042 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10043 
10044  /* basic algorithm is:
10045   *   - ensure sane alignment of input data
10046   *   - copy (conversion happens automatically) input data
10047   *     to output
10048   *   - update xpp to point at next unconverted input, and tp to point
10049   *     at next location for converted output
10050   */
10051   long i, j, ni;
10052   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10053   ushort *xp;
10054   int nrange = 0;         /* number of range errors */
10055   int realign = 0;        /* "do we need to fix input data alignment?" */
10056   long cxp = (long) *((char**)xpp);
10057 
10058   realign = (cxp & 7) % SIZEOF_USHORT;
10059   /* sjl: manually stripmine so we can limit amount of
10060    * vector work space reserved to LOOPCNT elements. Also
10061    * makes vectorisation easy */
10062   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10063     ni=Min(nelems-j,LOOPCNT);
10064     if (realign) {
10065       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10066       xp = tmp;
10067     } else {
10068       xp = (ushort *) *xpp;
10069     }
10070    /* copy the next block */
10071 #pragma cdir loopcnt=LOOPCNT
10072 #pragma cdir shortloop
10073     for (i=0; i<ni; i++) {
10074       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
10075      /* test for range errors (not always needed but do it anyway) */
10076      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10077      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10078       nrange += xp[i] > INT_MAX ;
10079     }
10080    /* update xpp and tp */
10081     if (realign) xp = (ushort *) *xpp;
10082     xp += ni;
10083     tp += ni;
10084     *xpp = (void*)xp;
10085   }
10086   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10087 
10088 #else   /* not SX */
10089 	const char *xp = (const char *) *xpp;
10090 	int status = NC_NOERR;
10091 
10092 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10093 	{
10094 		const int lstatus = ncx_get_ushort_int(xp, tp);
10095 		if (status == NC_NOERR) /* report the first encountered error */
10096 			status = lstatus;
10097 	}
10098 
10099 	*xpp = (const void *)xp;
10100 	return status;
10101 #endif
10102 }
10103 
10104 int
ncx_getn_ushort_long(const void ** xpp,size_t nelems,long * tp)10105 ncx_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10106 {
10107 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10108 
10109  /* basic algorithm is:
10110   *   - ensure sane alignment of input data
10111   *   - copy (conversion happens automatically) input data
10112   *     to output
10113   *   - update xpp to point at next unconverted input, and tp to point
10114   *     at next location for converted output
10115   */
10116   long i, j, ni;
10117   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10118   ushort *xp;
10119   int nrange = 0;         /* number of range errors */
10120   int realign = 0;        /* "do we need to fix input data alignment?" */
10121   long cxp = (long) *((char**)xpp);
10122 
10123   realign = (cxp & 7) % SIZEOF_USHORT;
10124   /* sjl: manually stripmine so we can limit amount of
10125    * vector work space reserved to LOOPCNT elements. Also
10126    * makes vectorisation easy */
10127   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10128     ni=Min(nelems-j,LOOPCNT);
10129     if (realign) {
10130       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10131       xp = tmp;
10132     } else {
10133       xp = (ushort *) *xpp;
10134     }
10135    /* copy the next block */
10136 #pragma cdir loopcnt=LOOPCNT
10137 #pragma cdir shortloop
10138     for (i=0; i<ni; i++) {
10139       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
10140      /* test for range errors (not always needed but do it anyway) */
10141      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10142      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10143       nrange += xp[i] > LONG_MAX ;
10144     }
10145    /* update xpp and tp */
10146     if (realign) xp = (ushort *) *xpp;
10147     xp += ni;
10148     tp += ni;
10149     *xpp = (void*)xp;
10150   }
10151   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10152 
10153 #else   /* not SX */
10154 	const char *xp = (const char *) *xpp;
10155 	int status = NC_NOERR;
10156 
10157 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10158 	{
10159 		const int lstatus = ncx_get_ushort_long(xp, tp);
10160 		if (status == NC_NOERR) /* report the first encountered error */
10161 			status = lstatus;
10162 	}
10163 
10164 	*xpp = (const void *)xp;
10165 	return status;
10166 #endif
10167 }
10168 
10169 int
ncx_getn_ushort_float(const void ** xpp,size_t nelems,float * tp)10170 ncx_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10171 {
10172 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10173 
10174  /* basic algorithm is:
10175   *   - ensure sane alignment of input data
10176   *   - copy (conversion happens automatically) input data
10177   *     to output
10178   *   - update xpp to point at next unconverted input, and tp to point
10179   *     at next location for converted output
10180   */
10181   long i, j, ni;
10182   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10183   ushort *xp;
10184   int nrange = 0;         /* number of range errors */
10185   int realign = 0;        /* "do we need to fix input data alignment?" */
10186   long cxp = (long) *((char**)xpp);
10187 
10188   realign = (cxp & 7) % SIZEOF_USHORT;
10189   /* sjl: manually stripmine so we can limit amount of
10190    * vector work space reserved to LOOPCNT elements. Also
10191    * makes vectorisation easy */
10192   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10193     ni=Min(nelems-j,LOOPCNT);
10194     if (realign) {
10195       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10196       xp = tmp;
10197     } else {
10198       xp = (ushort *) *xpp;
10199     }
10200    /* copy the next block */
10201 #pragma cdir loopcnt=LOOPCNT
10202 #pragma cdir shortloop
10203     for (i=0; i<ni; i++) {
10204       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
10205      /* test for range errors (not always needed but do it anyway) */
10206      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10207      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10208       nrange += xp[i] > FLOAT_MAX ;
10209     }
10210    /* update xpp and tp */
10211     if (realign) xp = (ushort *) *xpp;
10212     xp += ni;
10213     tp += ni;
10214     *xpp = (void*)xp;
10215   }
10216   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10217 
10218 #else   /* not SX */
10219 	const char *xp = (const char *) *xpp;
10220 	int status = NC_NOERR;
10221 
10222 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10223 	{
10224 		const int lstatus = ncx_get_ushort_float(xp, tp);
10225 		if (status == NC_NOERR) /* report the first encountered error */
10226 			status = lstatus;
10227 	}
10228 
10229 	*xpp = (const void *)xp;
10230 	return status;
10231 #endif
10232 }
10233 
10234 int
ncx_getn_ushort_double(const void ** xpp,size_t nelems,double * tp)10235 ncx_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10236 {
10237 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10238 
10239  /* basic algorithm is:
10240   *   - ensure sane alignment of input data
10241   *   - copy (conversion happens automatically) input data
10242   *     to output
10243   *   - update xpp to point at next unconverted input, and tp to point
10244   *     at next location for converted output
10245   */
10246   long i, j, ni;
10247   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10248   ushort *xp;
10249   int nrange = 0;         /* number of range errors */
10250   int realign = 0;        /* "do we need to fix input data alignment?" */
10251   long cxp = (long) *((char**)xpp);
10252 
10253   realign = (cxp & 7) % SIZEOF_USHORT;
10254   /* sjl: manually stripmine so we can limit amount of
10255    * vector work space reserved to LOOPCNT elements. Also
10256    * makes vectorisation easy */
10257   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10258     ni=Min(nelems-j,LOOPCNT);
10259     if (realign) {
10260       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10261       xp = tmp;
10262     } else {
10263       xp = (ushort *) *xpp;
10264     }
10265    /* copy the next block */
10266 #pragma cdir loopcnt=LOOPCNT
10267 #pragma cdir shortloop
10268     for (i=0; i<ni; i++) {
10269       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
10270      /* test for range errors (not always needed but do it anyway) */
10271      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10272      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10273       nrange += xp[i] > DOUBLE_MAX ;
10274     }
10275    /* update xpp and tp */
10276     if (realign) xp = (ushort *) *xpp;
10277     xp += ni;
10278     tp += ni;
10279     *xpp = (void*)xp;
10280   }
10281   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10282 
10283 #else   /* not SX */
10284 	const char *xp = (const char *) *xpp;
10285 	int status = NC_NOERR;
10286 
10287 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10288 	{
10289 		const int lstatus = ncx_get_ushort_double(xp, tp);
10290 		if (status == NC_NOERR) /* report the first encountered error */
10291 			status = lstatus;
10292 	}
10293 
10294 	*xpp = (const void *)xp;
10295 	return status;
10296 #endif
10297 }
10298 
10299 int
ncx_getn_ushort_longlong(const void ** xpp,size_t nelems,longlong * tp)10300 ncx_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10301 {
10302 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10303 
10304  /* basic algorithm is:
10305   *   - ensure sane alignment of input data
10306   *   - copy (conversion happens automatically) input data
10307   *     to output
10308   *   - update xpp to point at next unconverted input, and tp to point
10309   *     at next location for converted output
10310   */
10311   long i, j, ni;
10312   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10313   ushort *xp;
10314   int nrange = 0;         /* number of range errors */
10315   int realign = 0;        /* "do we need to fix input data alignment?" */
10316   long cxp = (long) *((char**)xpp);
10317 
10318   realign = (cxp & 7) % SIZEOF_USHORT;
10319   /* sjl: manually stripmine so we can limit amount of
10320    * vector work space reserved to LOOPCNT elements. Also
10321    * makes vectorisation easy */
10322   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10323     ni=Min(nelems-j,LOOPCNT);
10324     if (realign) {
10325       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10326       xp = tmp;
10327     } else {
10328       xp = (ushort *) *xpp;
10329     }
10330    /* copy the next block */
10331 #pragma cdir loopcnt=LOOPCNT
10332 #pragma cdir shortloop
10333     for (i=0; i<ni; i++) {
10334       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
10335      /* test for range errors (not always needed but do it anyway) */
10336      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10337      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10338       nrange += xp[i] > LONGLONG_MAX ;
10339     }
10340    /* update xpp and tp */
10341     if (realign) xp = (ushort *) *xpp;
10342     xp += ni;
10343     tp += ni;
10344     *xpp = (void*)xp;
10345   }
10346   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10347 
10348 #else   /* not SX */
10349 	const char *xp = (const char *) *xpp;
10350 	int status = NC_NOERR;
10351 
10352 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10353 	{
10354 		const int lstatus = ncx_get_ushort_longlong(xp, tp);
10355 		if (status == NC_NOERR) /* report the first encountered error */
10356 			status = lstatus;
10357 	}
10358 
10359 	*xpp = (const void *)xp;
10360 	return status;
10361 #endif
10362 }
10363 
10364 int
ncx_getn_ushort_uchar(const void ** xpp,size_t nelems,uchar * tp)10365 ncx_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10366 {
10367 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10368 
10369  /* basic algorithm is:
10370   *   - ensure sane alignment of input data
10371   *   - copy (conversion happens automatically) input data
10372   *     to output
10373   *   - update xpp to point at next unconverted input, and tp to point
10374   *     at next location for converted output
10375   */
10376   long i, j, ni;
10377   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10378   ushort *xp;
10379   int nrange = 0;         /* number of range errors */
10380   int realign = 0;        /* "do we need to fix input data alignment?" */
10381   long cxp = (long) *((char**)xpp);
10382 
10383   realign = (cxp & 7) % SIZEOF_USHORT;
10384   /* sjl: manually stripmine so we can limit amount of
10385    * vector work space reserved to LOOPCNT elements. Also
10386    * makes vectorisation easy */
10387   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10388     ni=Min(nelems-j,LOOPCNT);
10389     if (realign) {
10390       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10391       xp = tmp;
10392     } else {
10393       xp = (ushort *) *xpp;
10394     }
10395    /* copy the next block */
10396 #pragma cdir loopcnt=LOOPCNT
10397 #pragma cdir shortloop
10398     for (i=0; i<ni; i++) {
10399       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
10400      /* test for range errors (not always needed but do it anyway) */
10401      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10402      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10403       nrange += xp[i] > UCHAR_MAX ;
10404     }
10405    /* update xpp and tp */
10406     if (realign) xp = (ushort *) *xpp;
10407     xp += ni;
10408     tp += ni;
10409     *xpp = (void*)xp;
10410   }
10411   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10412 
10413 #else   /* not SX */
10414 	const char *xp = (const char *) *xpp;
10415 	int status = NC_NOERR;
10416 
10417 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10418 	{
10419 		const int lstatus = ncx_get_ushort_uchar(xp, tp);
10420 		if (status == NC_NOERR) /* report the first encountered error */
10421 			status = lstatus;
10422 	}
10423 
10424 	*xpp = (const void *)xp;
10425 	return status;
10426 #endif
10427 }
10428 
10429 int
ncx_getn_ushort_uint(const void ** xpp,size_t nelems,uint * tp)10430 ncx_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10431 {
10432 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10433 
10434  /* basic algorithm is:
10435   *   - ensure sane alignment of input data
10436   *   - copy (conversion happens automatically) input data
10437   *     to output
10438   *   - update xpp to point at next unconverted input, and tp to point
10439   *     at next location for converted output
10440   */
10441   long i, j, ni;
10442   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10443   ushort *xp;
10444   int nrange = 0;         /* number of range errors */
10445   int realign = 0;        /* "do we need to fix input data alignment?" */
10446   long cxp = (long) *((char**)xpp);
10447 
10448   realign = (cxp & 7) % SIZEOF_USHORT;
10449   /* sjl: manually stripmine so we can limit amount of
10450    * vector work space reserved to LOOPCNT elements. Also
10451    * makes vectorisation easy */
10452   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10453     ni=Min(nelems-j,LOOPCNT);
10454     if (realign) {
10455       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10456       xp = tmp;
10457     } else {
10458       xp = (ushort *) *xpp;
10459     }
10460    /* copy the next block */
10461 #pragma cdir loopcnt=LOOPCNT
10462 #pragma cdir shortloop
10463     for (i=0; i<ni; i++) {
10464       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
10465      /* test for range errors (not always needed but do it anyway) */
10466      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10467      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10468       nrange += xp[i] > UINT_MAX ;
10469     }
10470    /* update xpp and tp */
10471     if (realign) xp = (ushort *) *xpp;
10472     xp += ni;
10473     tp += ni;
10474     *xpp = (void*)xp;
10475   }
10476   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10477 
10478 #else   /* not SX */
10479 	const char *xp = (const char *) *xpp;
10480 	int status = NC_NOERR;
10481 
10482 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10483 	{
10484 		const int lstatus = ncx_get_ushort_uint(xp, tp);
10485 		if (status == NC_NOERR) /* report the first encountered error */
10486 			status = lstatus;
10487 	}
10488 
10489 	*xpp = (const void *)xp;
10490 	return status;
10491 #endif
10492 }
10493 
10494 int
ncx_getn_ushort_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)10495 ncx_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10496 {
10497 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10498 
10499  /* basic algorithm is:
10500   *   - ensure sane alignment of input data
10501   *   - copy (conversion happens automatically) input data
10502   *     to output
10503   *   - update xpp to point at next unconverted input, and tp to point
10504   *     at next location for converted output
10505   */
10506   long i, j, ni;
10507   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10508   ushort *xp;
10509   int nrange = 0;         /* number of range errors */
10510   int realign = 0;        /* "do we need to fix input data alignment?" */
10511   long cxp = (long) *((char**)xpp);
10512 
10513   realign = (cxp & 7) % SIZEOF_USHORT;
10514   /* sjl: manually stripmine so we can limit amount of
10515    * vector work space reserved to LOOPCNT elements. Also
10516    * makes vectorisation easy */
10517   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10518     ni=Min(nelems-j,LOOPCNT);
10519     if (realign) {
10520       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
10521       xp = tmp;
10522     } else {
10523       xp = (ushort *) *xpp;
10524     }
10525    /* copy the next block */
10526 #pragma cdir loopcnt=LOOPCNT
10527 #pragma cdir shortloop
10528     for (i=0; i<ni; i++) {
10529       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
10530      /* test for range errors (not always needed but do it anyway) */
10531      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
10532      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
10533       nrange += xp[i] > ULONGLONG_MAX ;
10534     }
10535    /* update xpp and tp */
10536     if (realign) xp = (ushort *) *xpp;
10537     xp += ni;
10538     tp += ni;
10539     *xpp = (void*)xp;
10540   }
10541   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10542 
10543 #else   /* not SX */
10544 	const char *xp = (const char *) *xpp;
10545 	int status = NC_NOERR;
10546 
10547 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10548 	{
10549 		const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10550 		if (status == NC_NOERR) /* report the first encountered error */
10551 			status = lstatus;
10552 	}
10553 
10554 	*xpp = (const void *)xp;
10555 	return status;
10556 #endif
10557 }
10558 
10559 
10560 int
ncx_pad_getn_ushort_schar(const void ** xpp,size_t nelems,schar * tp)10561 ncx_pad_getn_ushort_schar(const void **xpp, size_t nelems, schar *tp)
10562 {
10563 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10564 
10565 	const char *xp = (const char *) *xpp;
10566 	int status = NC_NOERR;
10567 
10568 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10569 	{
10570 		const int lstatus = ncx_get_ushort_schar(xp, tp);
10571 		if (status == NC_NOERR) /* report the first encountered error */
10572 			status = lstatus;
10573 	}
10574 
10575 	if (rndup != 0)
10576 		xp += X_SIZEOF_USHORT;
10577 
10578 	*xpp = (void *)xp;
10579 	return status;
10580 }
10581 
10582 int
ncx_pad_getn_ushort_short(const void ** xpp,size_t nelems,short * tp)10583 ncx_pad_getn_ushort_short(const void **xpp, size_t nelems, short *tp)
10584 {
10585 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10586 
10587 	const char *xp = (const char *) *xpp;
10588 	int status = NC_NOERR;
10589 
10590 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10591 	{
10592 		const int lstatus = ncx_get_ushort_short(xp, tp);
10593 		if (status == NC_NOERR) /* report the first encountered error */
10594 			status = lstatus;
10595 	}
10596 
10597 	if (rndup != 0)
10598 		xp += X_SIZEOF_USHORT;
10599 
10600 	*xpp = (void *)xp;
10601 	return status;
10602 }
10603 
10604 int
ncx_pad_getn_ushort_int(const void ** xpp,size_t nelems,int * tp)10605 ncx_pad_getn_ushort_int(const void **xpp, size_t nelems, int *tp)
10606 {
10607 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10608 
10609 	const char *xp = (const char *) *xpp;
10610 	int status = NC_NOERR;
10611 
10612 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10613 	{
10614 		const int lstatus = ncx_get_ushort_int(xp, tp);
10615 		if (status == NC_NOERR) /* report the first encountered error */
10616 			status = lstatus;
10617 	}
10618 
10619 	if (rndup != 0)
10620 		xp += X_SIZEOF_USHORT;
10621 
10622 	*xpp = (void *)xp;
10623 	return status;
10624 }
10625 
10626 int
ncx_pad_getn_ushort_long(const void ** xpp,size_t nelems,long * tp)10627 ncx_pad_getn_ushort_long(const void **xpp, size_t nelems, long *tp)
10628 {
10629 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10630 
10631 	const char *xp = (const char *) *xpp;
10632 	int status = NC_NOERR;
10633 
10634 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10635 	{
10636 		const int lstatus = ncx_get_ushort_long(xp, tp);
10637 		if (status == NC_NOERR) /* report the first encountered error */
10638 			status = lstatus;
10639 	}
10640 
10641 	if (rndup != 0)
10642 		xp += X_SIZEOF_USHORT;
10643 
10644 	*xpp = (void *)xp;
10645 	return status;
10646 }
10647 
10648 int
ncx_pad_getn_ushort_float(const void ** xpp,size_t nelems,float * tp)10649 ncx_pad_getn_ushort_float(const void **xpp, size_t nelems, float *tp)
10650 {
10651 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10652 
10653 	const char *xp = (const char *) *xpp;
10654 	int status = NC_NOERR;
10655 
10656 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10657 	{
10658 		const int lstatus = ncx_get_ushort_float(xp, tp);
10659 		if (status == NC_NOERR) /* report the first encountered error */
10660 			status = lstatus;
10661 	}
10662 
10663 	if (rndup != 0)
10664 		xp += X_SIZEOF_USHORT;
10665 
10666 	*xpp = (void *)xp;
10667 	return status;
10668 }
10669 
10670 int
ncx_pad_getn_ushort_double(const void ** xpp,size_t nelems,double * tp)10671 ncx_pad_getn_ushort_double(const void **xpp, size_t nelems, double *tp)
10672 {
10673 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10674 
10675 	const char *xp = (const char *) *xpp;
10676 	int status = NC_NOERR;
10677 
10678 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10679 	{
10680 		const int lstatus = ncx_get_ushort_double(xp, tp);
10681 		if (status == NC_NOERR) /* report the first encountered error */
10682 			status = lstatus;
10683 	}
10684 
10685 	if (rndup != 0)
10686 		xp += X_SIZEOF_USHORT;
10687 
10688 	*xpp = (void *)xp;
10689 	return status;
10690 }
10691 
10692 int
ncx_pad_getn_ushort_uchar(const void ** xpp,size_t nelems,uchar * tp)10693 ncx_pad_getn_ushort_uchar(const void **xpp, size_t nelems, uchar *tp)
10694 {
10695 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10696 
10697 	const char *xp = (const char *) *xpp;
10698 	int status = NC_NOERR;
10699 
10700 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10701 	{
10702 		const int lstatus = ncx_get_ushort_uchar(xp, tp);
10703 		if (status == NC_NOERR) /* report the first encountered error */
10704 			status = lstatus;
10705 	}
10706 
10707 	if (rndup != 0)
10708 		xp += X_SIZEOF_USHORT;
10709 
10710 	*xpp = (void *)xp;
10711 	return status;
10712 }
10713 
10714 int
ncx_pad_getn_ushort_ushort(const void ** xpp,size_t nelems,ushort * tp)10715 ncx_pad_getn_ushort_ushort(const void **xpp, size_t nelems, ushort *tp)
10716 {
10717 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10718 
10719 	const char *xp = (const char *) *xpp;
10720 	int status = NC_NOERR;
10721 
10722 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10723 	{
10724 		const int lstatus = ncx_get_ushort_ushort(xp, tp);
10725 		if (status == NC_NOERR) /* report the first encountered error */
10726 			status = lstatus;
10727 	}
10728 
10729 	if (rndup != 0)
10730 		xp += X_SIZEOF_USHORT;
10731 
10732 	*xpp = (void *)xp;
10733 	return status;
10734 }
10735 
10736 int
ncx_pad_getn_ushort_uint(const void ** xpp,size_t nelems,uint * tp)10737 ncx_pad_getn_ushort_uint(const void **xpp, size_t nelems, uint *tp)
10738 {
10739 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10740 
10741 	const char *xp = (const char *) *xpp;
10742 	int status = NC_NOERR;
10743 
10744 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10745 	{
10746 		const int lstatus = ncx_get_ushort_uint(xp, tp);
10747 		if (status == NC_NOERR) /* report the first encountered error */
10748 			status = lstatus;
10749 	}
10750 
10751 	if (rndup != 0)
10752 		xp += X_SIZEOF_USHORT;
10753 
10754 	*xpp = (void *)xp;
10755 	return status;
10756 }
10757 
10758 int
ncx_pad_getn_ushort_longlong(const void ** xpp,size_t nelems,longlong * tp)10759 ncx_pad_getn_ushort_longlong(const void **xpp, size_t nelems, longlong *tp)
10760 {
10761 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10762 
10763 	const char *xp = (const char *) *xpp;
10764 	int status = NC_NOERR;
10765 
10766 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10767 	{
10768 		const int lstatus = ncx_get_ushort_longlong(xp, tp);
10769 		if (status == NC_NOERR) /* report the first encountered error */
10770 			status = lstatus;
10771 	}
10772 
10773 	if (rndup != 0)
10774 		xp += X_SIZEOF_USHORT;
10775 
10776 	*xpp = (void *)xp;
10777 	return status;
10778 }
10779 
10780 int
ncx_pad_getn_ushort_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)10781 ncx_pad_getn_ushort_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
10782 {
10783 	const size_t rndup = nelems % X_SIZEOF_SHORT;
10784 
10785 	const char *xp = (const char *) *xpp;
10786 	int status = NC_NOERR;
10787 
10788 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10789 	{
10790 		const int lstatus = ncx_get_ushort_ulonglong(xp, tp);
10791 		if (status == NC_NOERR) /* report the first encountered error */
10792 			status = lstatus;
10793 	}
10794 
10795 	if (rndup != 0)
10796 		xp += X_SIZEOF_USHORT;
10797 
10798 	*xpp = (void *)xp;
10799 	return status;
10800 }
10801 
10802 
10803 #if X_SIZEOF_USHORT == SIZEOF_USHORT
10804 /* optimized version */
10805 int
ncx_putn_ushort_ushort(void ** xpp,size_t nelems,const unsigned short * tp,void * fillp)10806 ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp, void *fillp)
10807 {
10808 #ifdef WORDS_BIGENDIAN
10809 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
10810 # else
10811 	swapn2b(*xpp, tp, nelems);
10812 # endif
10813 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
10814 	return NC_NOERR;
10815 }
10816 #else
10817 int
ncx_putn_ushort_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)10818 ncx_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
10819 {
10820 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10821 
10822  /* basic algorithm is:
10823   *   - ensure sane alignment of output data
10824   *   - copy (conversion happens automatically) input data
10825   *     to output
10826   *   - update tp to point at next unconverted input, and xpp to point
10827   *     at next location for converted output
10828   */
10829   long i, j, ni;
10830   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10831   ushort *xp;
10832   int nrange = 0;         /* number of range errors */
10833   int realign = 0;        /* "do we need to fix input data alignment?" */
10834   long cxp = (long) *((char**)xpp);
10835 
10836   realign = (cxp & 7) % SIZEOF_USHORT;
10837   /* sjl: manually stripmine so we can limit amount of
10838    * vector work space reserved to LOOPCNT elements. Also
10839    * makes vectorisation easy */
10840   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10841     ni=Min(nelems-j,LOOPCNT);
10842     if (realign) {
10843       xp = tmp;
10844     } else {
10845       xp = (ushort *) *xpp;
10846     }
10847    /* copy the next block */
10848 #pragma cdir loopcnt=LOOPCNT
10849 #pragma cdir shortloop
10850     for (i=0; i<ni; i++) {
10851       /* the normal case: */
10852       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10853      /* test for range errors (not always needed but do it anyway) */
10854      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10855      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10856       nrange += tp[i] > X_USHORT_MAX ;
10857     }
10858    /* copy workspace back if necessary */
10859     if (realign) {
10860       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10861       xp = (ushort *) *xpp;
10862     }
10863    /* update xpp and tp */
10864     xp += ni;
10865     tp += ni;
10866     *xpp = (void*)xp;
10867   }
10868   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10869 
10870 #else   /* not SX */
10871 
10872 	char *xp = (char *) *xpp;
10873 	int status = NC_NOERR;
10874 
10875 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10876 	{
10877 		int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
10878 		if (status == NC_NOERR) /* report the first encountered error */
10879 			status = lstatus;
10880 	}
10881 
10882 	*xpp = (void *)xp;
10883 	return status;
10884 #endif
10885 }
10886 
10887 #endif
10888 int
ncx_putn_ushort_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)10889 ncx_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
10890 {
10891 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10892 
10893  /* basic algorithm is:
10894   *   - ensure sane alignment of output data
10895   *   - copy (conversion happens automatically) input data
10896   *     to output
10897   *   - update tp to point at next unconverted input, and xpp to point
10898   *     at next location for converted output
10899   */
10900   long i, j, ni;
10901   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10902   ushort *xp;
10903   int nrange = 0;         /* number of range errors */
10904   int realign = 0;        /* "do we need to fix input data alignment?" */
10905   long cxp = (long) *((char**)xpp);
10906 
10907   realign = (cxp & 7) % SIZEOF_USHORT;
10908   /* sjl: manually stripmine so we can limit amount of
10909    * vector work space reserved to LOOPCNT elements. Also
10910    * makes vectorisation easy */
10911   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10912     ni=Min(nelems-j,LOOPCNT);
10913     if (realign) {
10914       xp = tmp;
10915     } else {
10916       xp = (ushort *) *xpp;
10917     }
10918    /* copy the next block */
10919 #pragma cdir loopcnt=LOOPCNT
10920 #pragma cdir shortloop
10921     for (i=0; i<ni; i++) {
10922       /* the normal case: */
10923       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10924      /* test for range errors (not always needed but do it anyway) */
10925      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10926      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10927       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10928     }
10929    /* copy workspace back if necessary */
10930     if (realign) {
10931       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
10932       xp = (ushort *) *xpp;
10933     }
10934    /* update xpp and tp */
10935     xp += ni;
10936     tp += ni;
10937     *xpp = (void*)xp;
10938   }
10939   return nrange == 0 ? NC_NOERR : NC_ERANGE;
10940 
10941 #else   /* not SX */
10942 
10943 	char *xp = (char *) *xpp;
10944 	int status = NC_NOERR;
10945 
10946 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
10947 	{
10948 		int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
10949 		if (status == NC_NOERR) /* report the first encountered error */
10950 			status = lstatus;
10951 	}
10952 
10953 	*xpp = (void *)xp;
10954 	return status;
10955 #endif
10956 }
10957 
10958 int
ncx_putn_ushort_short(void ** xpp,size_t nelems,const short * tp,void * fillp)10959 ncx_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
10960 {
10961 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
10962 
10963  /* basic algorithm is:
10964   *   - ensure sane alignment of output data
10965   *   - copy (conversion happens automatically) input data
10966   *     to output
10967   *   - update tp to point at next unconverted input, and xpp to point
10968   *     at next location for converted output
10969   */
10970   long i, j, ni;
10971   ushort tmp[LOOPCNT];        /* in case input is misaligned */
10972   ushort *xp;
10973   int nrange = 0;         /* number of range errors */
10974   int realign = 0;        /* "do we need to fix input data alignment?" */
10975   long cxp = (long) *((char**)xpp);
10976 
10977   realign = (cxp & 7) % SIZEOF_USHORT;
10978   /* sjl: manually stripmine so we can limit amount of
10979    * vector work space reserved to LOOPCNT elements. Also
10980    * makes vectorisation easy */
10981   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
10982     ni=Min(nelems-j,LOOPCNT);
10983     if (realign) {
10984       xp = tmp;
10985     } else {
10986       xp = (ushort *) *xpp;
10987     }
10988    /* copy the next block */
10989 #pragma cdir loopcnt=LOOPCNT
10990 #pragma cdir shortloop
10991     for (i=0; i<ni; i++) {
10992       /* the normal case: */
10993       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
10994      /* test for range errors (not always needed but do it anyway) */
10995      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
10996      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
10997       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
10998     }
10999    /* copy workspace back if necessary */
11000     if (realign) {
11001       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11002       xp = (ushort *) *xpp;
11003     }
11004    /* update xpp and tp */
11005     xp += ni;
11006     tp += ni;
11007     *xpp = (void*)xp;
11008   }
11009   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11010 
11011 #else   /* not SX */
11012 
11013 	char *xp = (char *) *xpp;
11014 	int status = NC_NOERR;
11015 
11016 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11017 	{
11018 		int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11019 		if (status == NC_NOERR) /* report the first encountered error */
11020 			status = lstatus;
11021 	}
11022 
11023 	*xpp = (void *)xp;
11024 	return status;
11025 #endif
11026 }
11027 
11028 int
ncx_putn_ushort_int(void ** xpp,size_t nelems,const int * tp,void * fillp)11029 ncx_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11030 {
11031 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11032 
11033  /* basic algorithm is:
11034   *   - ensure sane alignment of output data
11035   *   - copy (conversion happens automatically) input data
11036   *     to output
11037   *   - update tp to point at next unconverted input, and xpp to point
11038   *     at next location for converted output
11039   */
11040   long i, j, ni;
11041   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11042   ushort *xp;
11043   int nrange = 0;         /* number of range errors */
11044   int realign = 0;        /* "do we need to fix input data alignment?" */
11045   long cxp = (long) *((char**)xpp);
11046 
11047   realign = (cxp & 7) % SIZEOF_USHORT;
11048   /* sjl: manually stripmine so we can limit amount of
11049    * vector work space reserved to LOOPCNT elements. Also
11050    * makes vectorisation easy */
11051   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11052     ni=Min(nelems-j,LOOPCNT);
11053     if (realign) {
11054       xp = tmp;
11055     } else {
11056       xp = (ushort *) *xpp;
11057     }
11058    /* copy the next block */
11059 #pragma cdir loopcnt=LOOPCNT
11060 #pragma cdir shortloop
11061     for (i=0; i<ni; i++) {
11062       /* the normal case: */
11063       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11064      /* test for range errors (not always needed but do it anyway) */
11065      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11066      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11067       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11068     }
11069    /* copy workspace back if necessary */
11070     if (realign) {
11071       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11072       xp = (ushort *) *xpp;
11073     }
11074    /* update xpp and tp */
11075     xp += ni;
11076     tp += ni;
11077     *xpp = (void*)xp;
11078   }
11079   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11080 
11081 #else   /* not SX */
11082 
11083 	char *xp = (char *) *xpp;
11084 	int status = NC_NOERR;
11085 
11086 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11087 	{
11088 		int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11089 		if (status == NC_NOERR) /* report the first encountered error */
11090 			status = lstatus;
11091 	}
11092 
11093 	*xpp = (void *)xp;
11094 	return status;
11095 #endif
11096 }
11097 
11098 int
ncx_putn_ushort_long(void ** xpp,size_t nelems,const long * tp,void * fillp)11099 ncx_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11100 {
11101 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11102 
11103  /* basic algorithm is:
11104   *   - ensure sane alignment of output data
11105   *   - copy (conversion happens automatically) input data
11106   *     to output
11107   *   - update tp to point at next unconverted input, and xpp to point
11108   *     at next location for converted output
11109   */
11110   long i, j, ni;
11111   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11112   ushort *xp;
11113   int nrange = 0;         /* number of range errors */
11114   int realign = 0;        /* "do we need to fix input data alignment?" */
11115   long cxp = (long) *((char**)xpp);
11116 
11117   realign = (cxp & 7) % SIZEOF_USHORT;
11118   /* sjl: manually stripmine so we can limit amount of
11119    * vector work space reserved to LOOPCNT elements. Also
11120    * makes vectorisation easy */
11121   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11122     ni=Min(nelems-j,LOOPCNT);
11123     if (realign) {
11124       xp = tmp;
11125     } else {
11126       xp = (ushort *) *xpp;
11127     }
11128    /* copy the next block */
11129 #pragma cdir loopcnt=LOOPCNT
11130 #pragma cdir shortloop
11131     for (i=0; i<ni; i++) {
11132       /* the normal case: */
11133       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11134      /* test for range errors (not always needed but do it anyway) */
11135      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11136      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11137       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11138     }
11139    /* copy workspace back if necessary */
11140     if (realign) {
11141       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11142       xp = (ushort *) *xpp;
11143     }
11144    /* update xpp and tp */
11145     xp += ni;
11146     tp += ni;
11147     *xpp = (void*)xp;
11148   }
11149   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11150 
11151 #else   /* not SX */
11152 
11153 	char *xp = (char *) *xpp;
11154 	int status = NC_NOERR;
11155 
11156 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11157 	{
11158 		int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11159 		if (status == NC_NOERR) /* report the first encountered error */
11160 			status = lstatus;
11161 	}
11162 
11163 	*xpp = (void *)xp;
11164 	return status;
11165 #endif
11166 }
11167 
11168 int
ncx_putn_ushort_float(void ** xpp,size_t nelems,const float * tp,void * fillp)11169 ncx_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11170 {
11171 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11172 
11173  /* basic algorithm is:
11174   *   - ensure sane alignment of output data
11175   *   - copy (conversion happens automatically) input data
11176   *     to output
11177   *   - update tp to point at next unconverted input, and xpp to point
11178   *     at next location for converted output
11179   */
11180   long i, j, ni;
11181   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11182   ushort *xp;
11183   int nrange = 0;         /* number of range errors */
11184   int realign = 0;        /* "do we need to fix input data alignment?" */
11185   long cxp = (long) *((char**)xpp);
11186 
11187   realign = (cxp & 7) % SIZEOF_USHORT;
11188   /* sjl: manually stripmine so we can limit amount of
11189    * vector work space reserved to LOOPCNT elements. Also
11190    * makes vectorisation easy */
11191   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11192     ni=Min(nelems-j,LOOPCNT);
11193     if (realign) {
11194       xp = tmp;
11195     } else {
11196       xp = (ushort *) *xpp;
11197     }
11198    /* copy the next block */
11199 #pragma cdir loopcnt=LOOPCNT
11200 #pragma cdir shortloop
11201     for (i=0; i<ni; i++) {
11202       /* the normal case: */
11203       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11204      /* test for range errors (not always needed but do it anyway) */
11205      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11206      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11207       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11208     }
11209    /* copy workspace back if necessary */
11210     if (realign) {
11211       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11212       xp = (ushort *) *xpp;
11213     }
11214    /* update xpp and tp */
11215     xp += ni;
11216     tp += ni;
11217     *xpp = (void*)xp;
11218   }
11219   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11220 
11221 #else   /* not SX */
11222 
11223 	char *xp = (char *) *xpp;
11224 	int status = NC_NOERR;
11225 
11226 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11227 	{
11228 		int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11229 		if (status == NC_NOERR) /* report the first encountered error */
11230 			status = lstatus;
11231 	}
11232 
11233 	*xpp = (void *)xp;
11234 	return status;
11235 #endif
11236 }
11237 
11238 int
ncx_putn_ushort_double(void ** xpp,size_t nelems,const double * tp,void * fillp)11239 ncx_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11240 {
11241 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11242 
11243  /* basic algorithm is:
11244   *   - ensure sane alignment of output data
11245   *   - copy (conversion happens automatically) input data
11246   *     to output
11247   *   - update tp to point at next unconverted input, and xpp to point
11248   *     at next location for converted output
11249   */
11250   long i, j, ni;
11251   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11252   ushort *xp;
11253   int nrange = 0;         /* number of range errors */
11254   int realign = 0;        /* "do we need to fix input data alignment?" */
11255   long cxp = (long) *((char**)xpp);
11256 
11257   realign = (cxp & 7) % SIZEOF_USHORT;
11258   /* sjl: manually stripmine so we can limit amount of
11259    * vector work space reserved to LOOPCNT elements. Also
11260    * makes vectorisation easy */
11261   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11262     ni=Min(nelems-j,LOOPCNT);
11263     if (realign) {
11264       xp = tmp;
11265     } else {
11266       xp = (ushort *) *xpp;
11267     }
11268    /* copy the next block */
11269 #pragma cdir loopcnt=LOOPCNT
11270 #pragma cdir shortloop
11271     for (i=0; i<ni; i++) {
11272       /* the normal case: */
11273       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11274      /* test for range errors (not always needed but do it anyway) */
11275      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11276      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11277       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11278     }
11279    /* copy workspace back if necessary */
11280     if (realign) {
11281       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11282       xp = (ushort *) *xpp;
11283     }
11284    /* update xpp and tp */
11285     xp += ni;
11286     tp += ni;
11287     *xpp = (void*)xp;
11288   }
11289   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11290 
11291 #else   /* not SX */
11292 
11293 	char *xp = (char *) *xpp;
11294 	int status = NC_NOERR;
11295 
11296 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11297 	{
11298 		int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11299 		if (status == NC_NOERR) /* report the first encountered error */
11300 			status = lstatus;
11301 	}
11302 
11303 	*xpp = (void *)xp;
11304 	return status;
11305 #endif
11306 }
11307 
11308 int
ncx_putn_ushort_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)11309 ncx_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11310 {
11311 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11312 
11313  /* basic algorithm is:
11314   *   - ensure sane alignment of output data
11315   *   - copy (conversion happens automatically) input data
11316   *     to output
11317   *   - update tp to point at next unconverted input, and xpp to point
11318   *     at next location for converted output
11319   */
11320   long i, j, ni;
11321   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11322   ushort *xp;
11323   int nrange = 0;         /* number of range errors */
11324   int realign = 0;        /* "do we need to fix input data alignment?" */
11325   long cxp = (long) *((char**)xpp);
11326 
11327   realign = (cxp & 7) % SIZEOF_USHORT;
11328   /* sjl: manually stripmine so we can limit amount of
11329    * vector work space reserved to LOOPCNT elements. Also
11330    * makes vectorisation easy */
11331   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11332     ni=Min(nelems-j,LOOPCNT);
11333     if (realign) {
11334       xp = tmp;
11335     } else {
11336       xp = (ushort *) *xpp;
11337     }
11338    /* copy the next block */
11339 #pragma cdir loopcnt=LOOPCNT
11340 #pragma cdir shortloop
11341     for (i=0; i<ni; i++) {
11342       /* the normal case: */
11343       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11344      /* test for range errors (not always needed but do it anyway) */
11345      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11346      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11347       nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
11348     }
11349    /* copy workspace back if necessary */
11350     if (realign) {
11351       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11352       xp = (ushort *) *xpp;
11353     }
11354    /* update xpp and tp */
11355     xp += ni;
11356     tp += ni;
11357     *xpp = (void*)xp;
11358   }
11359   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11360 
11361 #else   /* not SX */
11362 
11363 	char *xp = (char *) *xpp;
11364 	int status = NC_NOERR;
11365 
11366 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11367 	{
11368 		int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11369 		if (status == NC_NOERR) /* report the first encountered error */
11370 			status = lstatus;
11371 	}
11372 
11373 	*xpp = (void *)xp;
11374 	return status;
11375 #endif
11376 }
11377 
11378 int
ncx_putn_ushort_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)11379 ncx_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11380 {
11381 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11382 
11383  /* basic algorithm is:
11384   *   - ensure sane alignment of output data
11385   *   - copy (conversion happens automatically) input data
11386   *     to output
11387   *   - update tp to point at next unconverted input, and xpp to point
11388   *     at next location for converted output
11389   */
11390   long i, j, ni;
11391   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11392   ushort *xp;
11393   int nrange = 0;         /* number of range errors */
11394   int realign = 0;        /* "do we need to fix input data alignment?" */
11395   long cxp = (long) *((char**)xpp);
11396 
11397   realign = (cxp & 7) % SIZEOF_USHORT;
11398   /* sjl: manually stripmine so we can limit amount of
11399    * vector work space reserved to LOOPCNT elements. Also
11400    * makes vectorisation easy */
11401   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11402     ni=Min(nelems-j,LOOPCNT);
11403     if (realign) {
11404       xp = tmp;
11405     } else {
11406       xp = (ushort *) *xpp;
11407     }
11408    /* copy the next block */
11409 #pragma cdir loopcnt=LOOPCNT
11410 #pragma cdir shortloop
11411     for (i=0; i<ni; i++) {
11412       /* the normal case: */
11413       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11414      /* test for range errors (not always needed but do it anyway) */
11415      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11416      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11417       nrange += tp[i] > X_USHORT_MAX ;
11418     }
11419    /* copy workspace back if necessary */
11420     if (realign) {
11421       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11422       xp = (ushort *) *xpp;
11423     }
11424    /* update xpp and tp */
11425     xp += ni;
11426     tp += ni;
11427     *xpp = (void*)xp;
11428   }
11429   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11430 
11431 #else   /* not SX */
11432 
11433 	char *xp = (char *) *xpp;
11434 	int status = NC_NOERR;
11435 
11436 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11437 	{
11438 		int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11439 		if (status == NC_NOERR) /* report the first encountered error */
11440 			status = lstatus;
11441 	}
11442 
11443 	*xpp = (void *)xp;
11444 	return status;
11445 #endif
11446 }
11447 
11448 int
ncx_putn_ushort_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)11449 ncx_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11450 {
11451 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11452 
11453  /* basic algorithm is:
11454   *   - ensure sane alignment of output data
11455   *   - copy (conversion happens automatically) input data
11456   *     to output
11457   *   - update tp to point at next unconverted input, and xpp to point
11458   *     at next location for converted output
11459   */
11460   long i, j, ni;
11461   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11462   ushort *xp;
11463   int nrange = 0;         /* number of range errors */
11464   int realign = 0;        /* "do we need to fix input data alignment?" */
11465   long cxp = (long) *((char**)xpp);
11466 
11467   realign = (cxp & 7) % SIZEOF_USHORT;
11468   /* sjl: manually stripmine so we can limit amount of
11469    * vector work space reserved to LOOPCNT elements. Also
11470    * makes vectorisation easy */
11471   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11472     ni=Min(nelems-j,LOOPCNT);
11473     if (realign) {
11474       xp = tmp;
11475     } else {
11476       xp = (ushort *) *xpp;
11477     }
11478    /* copy the next block */
11479 #pragma cdir loopcnt=LOOPCNT
11480 #pragma cdir shortloop
11481     for (i=0; i<ni; i++) {
11482       /* the normal case: */
11483       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11484      /* test for range errors (not always needed but do it anyway) */
11485      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11486      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11487       nrange += tp[i] > X_USHORT_MAX ;
11488     }
11489    /* copy workspace back if necessary */
11490     if (realign) {
11491       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11492       xp = (ushort *) *xpp;
11493     }
11494    /* update xpp and tp */
11495     xp += ni;
11496     tp += ni;
11497     *xpp = (void*)xp;
11498   }
11499   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11500 
11501 #else   /* not SX */
11502 
11503 	char *xp = (char *) *xpp;
11504 	int status = NC_NOERR;
11505 
11506 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11507 	{
11508 		int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11509 		if (status == NC_NOERR) /* report the first encountered error */
11510 			status = lstatus;
11511 	}
11512 
11513 	*xpp = (void *)xp;
11514 	return status;
11515 #endif
11516 }
11517 
11518 int
ncx_putn_ushort_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)11519 ncx_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11520 {
11521 #if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT
11522 
11523  /* basic algorithm is:
11524   *   - ensure sane alignment of output data
11525   *   - copy (conversion happens automatically) input data
11526   *     to output
11527   *   - update tp to point at next unconverted input, and xpp to point
11528   *     at next location for converted output
11529   */
11530   long i, j, ni;
11531   ushort tmp[LOOPCNT];        /* in case input is misaligned */
11532   ushort *xp;
11533   int nrange = 0;         /* number of range errors */
11534   int realign = 0;        /* "do we need to fix input data alignment?" */
11535   long cxp = (long) *((char**)xpp);
11536 
11537   realign = (cxp & 7) % SIZEOF_USHORT;
11538   /* sjl: manually stripmine so we can limit amount of
11539    * vector work space reserved to LOOPCNT elements. Also
11540    * makes vectorisation easy */
11541   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11542     ni=Min(nelems-j,LOOPCNT);
11543     if (realign) {
11544       xp = tmp;
11545     } else {
11546       xp = (ushort *) *xpp;
11547     }
11548    /* copy the next block */
11549 #pragma cdir loopcnt=LOOPCNT
11550 #pragma cdir shortloop
11551     for (i=0; i<ni; i++) {
11552       /* the normal case: */
11553       xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
11554      /* test for range errors (not always needed but do it anyway) */
11555      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
11556      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
11557       nrange += tp[i] > X_USHORT_MAX ;
11558     }
11559    /* copy workspace back if necessary */
11560     if (realign) {
11561       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
11562       xp = (ushort *) *xpp;
11563     }
11564    /* update xpp and tp */
11565     xp += ni;
11566     tp += ni;
11567     *xpp = (void*)xp;
11568   }
11569   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11570 
11571 #else   /* not SX */
11572 
11573 	char *xp = (char *) *xpp;
11574 	int status = NC_NOERR;
11575 
11576 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11577 	{
11578 		int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11579 		if (status == NC_NOERR) /* report the first encountered error */
11580 			status = lstatus;
11581 	}
11582 
11583 	*xpp = (void *)xp;
11584 	return status;
11585 #endif
11586 }
11587 
11588 
11589 int
ncx_pad_putn_ushort_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)11590 ncx_pad_putn_ushort_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
11591 {
11592 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11593 
11594 	char *xp = (char *) *xpp;
11595 	int status = NC_NOERR;
11596 
11597 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11598 	{
11599 		int lstatus = ncx_put_ushort_schar(xp, tp, fillp);
11600 		if (status == NC_NOERR) /* report the first encountered error */
11601 			status = lstatus;
11602 	}
11603 
11604 	if (rndup != 0)
11605 	{
11606 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11607 		xp += X_SIZEOF_USHORT;
11608 	}
11609 
11610 	*xpp = (void *)xp;
11611 	return status;
11612 }
11613 
11614 int
ncx_pad_putn_ushort_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)11615 ncx_pad_putn_ushort_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
11616 {
11617 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11618 
11619 	char *xp = (char *) *xpp;
11620 	int status = NC_NOERR;
11621 
11622 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11623 	{
11624 		int lstatus = ncx_put_ushort_uchar(xp, tp, fillp);
11625 		if (status == NC_NOERR) /* report the first encountered error */
11626 			status = lstatus;
11627 	}
11628 
11629 	if (rndup != 0)
11630 	{
11631 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11632 		xp += X_SIZEOF_USHORT;
11633 	}
11634 
11635 	*xpp = (void *)xp;
11636 	return status;
11637 }
11638 
11639 int
ncx_pad_putn_ushort_short(void ** xpp,size_t nelems,const short * tp,void * fillp)11640 ncx_pad_putn_ushort_short(void **xpp, size_t nelems, const short *tp, void *fillp)
11641 {
11642 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11643 
11644 	char *xp = (char *) *xpp;
11645 	int status = NC_NOERR;
11646 
11647 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11648 	{
11649 		int lstatus = ncx_put_ushort_short(xp, tp, fillp);
11650 		if (status == NC_NOERR) /* report the first encountered error */
11651 			status = lstatus;
11652 	}
11653 
11654 	if (rndup != 0)
11655 	{
11656 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11657 		xp += X_SIZEOF_USHORT;
11658 	}
11659 
11660 	*xpp = (void *)xp;
11661 	return status;
11662 }
11663 
11664 int
ncx_pad_putn_ushort_int(void ** xpp,size_t nelems,const int * tp,void * fillp)11665 ncx_pad_putn_ushort_int(void **xpp, size_t nelems, const int *tp, void *fillp)
11666 {
11667 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11668 
11669 	char *xp = (char *) *xpp;
11670 	int status = NC_NOERR;
11671 
11672 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11673 	{
11674 		int lstatus = ncx_put_ushort_int(xp, tp, fillp);
11675 		if (status == NC_NOERR) /* report the first encountered error */
11676 			status = lstatus;
11677 	}
11678 
11679 	if (rndup != 0)
11680 	{
11681 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11682 		xp += X_SIZEOF_USHORT;
11683 	}
11684 
11685 	*xpp = (void *)xp;
11686 	return status;
11687 }
11688 
11689 int
ncx_pad_putn_ushort_long(void ** xpp,size_t nelems,const long * tp,void * fillp)11690 ncx_pad_putn_ushort_long(void **xpp, size_t nelems, const long *tp, void *fillp)
11691 {
11692 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11693 
11694 	char *xp = (char *) *xpp;
11695 	int status = NC_NOERR;
11696 
11697 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11698 	{
11699 		int lstatus = ncx_put_ushort_long(xp, tp, fillp);
11700 		if (status == NC_NOERR) /* report the first encountered error */
11701 			status = lstatus;
11702 	}
11703 
11704 	if (rndup != 0)
11705 	{
11706 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11707 		xp += X_SIZEOF_USHORT;
11708 	}
11709 
11710 	*xpp = (void *)xp;
11711 	return status;
11712 }
11713 
11714 int
ncx_pad_putn_ushort_float(void ** xpp,size_t nelems,const float * tp,void * fillp)11715 ncx_pad_putn_ushort_float(void **xpp, size_t nelems, const float *tp, void *fillp)
11716 {
11717 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11718 
11719 	char *xp = (char *) *xpp;
11720 	int status = NC_NOERR;
11721 
11722 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11723 	{
11724 		int lstatus = ncx_put_ushort_float(xp, tp, fillp);
11725 		if (status == NC_NOERR) /* report the first encountered error */
11726 			status = lstatus;
11727 	}
11728 
11729 	if (rndup != 0)
11730 	{
11731 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11732 		xp += X_SIZEOF_USHORT;
11733 	}
11734 
11735 	*xpp = (void *)xp;
11736 	return status;
11737 }
11738 
11739 int
ncx_pad_putn_ushort_double(void ** xpp,size_t nelems,const double * tp,void * fillp)11740 ncx_pad_putn_ushort_double(void **xpp, size_t nelems, const double *tp, void *fillp)
11741 {
11742 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11743 
11744 	char *xp = (char *) *xpp;
11745 	int status = NC_NOERR;
11746 
11747 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11748 	{
11749 		int lstatus = ncx_put_ushort_double(xp, tp, fillp);
11750 		if (status == NC_NOERR) /* report the first encountered error */
11751 			status = lstatus;
11752 	}
11753 
11754 	if (rndup != 0)
11755 	{
11756 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11757 		xp += X_SIZEOF_USHORT;
11758 	}
11759 
11760 	*xpp = (void *)xp;
11761 	return status;
11762 }
11763 
11764 int
ncx_pad_putn_ushort_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)11765 ncx_pad_putn_ushort_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
11766 {
11767 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11768 
11769 	char *xp = (char *) *xpp;
11770 	int status = NC_NOERR;
11771 
11772 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11773 	{
11774 		int lstatus = ncx_put_ushort_uint(xp, tp, fillp);
11775 		if (status == NC_NOERR) /* report the first encountered error */
11776 			status = lstatus;
11777 	}
11778 
11779 	if (rndup != 0)
11780 	{
11781 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11782 		xp += X_SIZEOF_USHORT;
11783 	}
11784 
11785 	*xpp = (void *)xp;
11786 	return status;
11787 }
11788 
11789 int
ncx_pad_putn_ushort_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)11790 ncx_pad_putn_ushort_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
11791 {
11792 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11793 
11794 	char *xp = (char *) *xpp;
11795 	int status = NC_NOERR;
11796 
11797 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11798 	{
11799 		int lstatus = ncx_put_ushort_longlong(xp, tp, fillp);
11800 		if (status == NC_NOERR) /* report the first encountered error */
11801 			status = lstatus;
11802 	}
11803 
11804 	if (rndup != 0)
11805 	{
11806 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11807 		xp += X_SIZEOF_USHORT;
11808 	}
11809 
11810 	*xpp = (void *)xp;
11811 	return status;
11812 }
11813 
11814 int
ncx_pad_putn_ushort_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)11815 ncx_pad_putn_ushort_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
11816 {
11817 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11818 
11819 	char *xp = (char *) *xpp;
11820 	int status = NC_NOERR;
11821 
11822 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11823 	{
11824 		int lstatus = ncx_put_ushort_ulonglong(xp, tp, fillp);
11825 		if (status == NC_NOERR) /* report the first encountered error */
11826 			status = lstatus;
11827 	}
11828 
11829 	if (rndup != 0)
11830 	{
11831 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11832 		xp += X_SIZEOF_USHORT;
11833 	}
11834 
11835 	*xpp = (void *)xp;
11836 	return status;
11837 }
11838 
11839 int
ncx_pad_putn_ushort_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)11840 ncx_pad_putn_ushort_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
11841 {
11842 	const size_t rndup = nelems % X_SIZEOF_SHORT;
11843 
11844 	char *xp = (char *) *xpp;
11845 	int status = NC_NOERR;
11846 
11847 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
11848 	{
11849 		int lstatus = ncx_put_ushort_ushort(xp, tp, fillp);
11850 		if (status == NC_NOERR) /* report the first encountered error */
11851 			status = lstatus;
11852 	}
11853 
11854 	if (rndup != 0)
11855 	{
11856 		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
11857 		xp += X_SIZEOF_USHORT;
11858 	}
11859 
11860 	*xpp = (void *)xp;
11861 	return status;
11862 }
11863 
11864 
11865 
11866 /* int -----------------------------------------------------------------------*/
11867 
11868 #if X_SIZEOF_INT == SIZEOF_INT
11869 /* optimized version */
11870 int
ncx_getn_int_int(const void ** xpp,size_t nelems,int * tp)11871 ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11872 {
11873 #ifdef WORDS_BIGENDIAN
11874 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
11875 # else
11876 	swapn4b(tp, *xpp, nelems);
11877 # endif
11878 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
11879 	return NC_NOERR;
11880 }
11881 #else
11882 int
ncx_getn_int_int(const void ** xpp,size_t nelems,int * tp)11883 ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
11884 {
11885 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11886 
11887  /* basic algorithm is:
11888   *   - ensure sane alignment of input data
11889   *   - copy (conversion happens automatically) input data
11890   *     to output
11891   *   - update xpp to point at next unconverted input, and tp to point
11892   *     at next location for converted output
11893   */
11894   long i, j, ni;
11895   int tmp[LOOPCNT];        /* in case input is misaligned */
11896   int *xp;
11897   int nrange = 0;         /* number of range errors */
11898   int realign = 0;        /* "do we need to fix input data alignment?" */
11899   long cxp = (long) *((char**)xpp);
11900 
11901   realign = (cxp & 7) % SIZEOF_INT;
11902   /* sjl: manually stripmine so we can limit amount of
11903    * vector work space reserved to LOOPCNT elements. Also
11904    * makes vectorisation easy */
11905   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11906     ni=Min(nelems-j,LOOPCNT);
11907     if (realign) {
11908       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11909       xp = tmp;
11910     } else {
11911       xp = (int *) *xpp;
11912     }
11913    /* copy the next block */
11914 #pragma cdir loopcnt=LOOPCNT
11915 #pragma cdir shortloop
11916     for (i=0; i<ni; i++) {
11917       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
11918      /* test for range errors (not always needed but do it anyway) */
11919      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11920      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11921       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
11922     }
11923    /* update xpp and tp */
11924     if (realign) xp = (int *) *xpp;
11925     xp += ni;
11926     tp += ni;
11927     *xpp = (void*)xp;
11928   }
11929   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11930 
11931 #else   /* not SX */
11932 	const char *xp = (const char *) *xpp;
11933 	int status = NC_NOERR;
11934 
11935 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
11936 	{
11937 		const int lstatus = ncx_get_int_int(xp, tp);
11938 		if (status == NC_NOERR) /* report the first encountered error */
11939 			status = lstatus;
11940 	}
11941 
11942 	*xpp = (const void *)xp;
11943 	return status;
11944 #endif
11945 }
11946 
11947 #endif
11948 int
ncx_getn_int_schar(const void ** xpp,size_t nelems,schar * tp)11949 ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
11950 {
11951 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
11952 
11953  /* basic algorithm is:
11954   *   - ensure sane alignment of input data
11955   *   - copy (conversion happens automatically) input data
11956   *     to output
11957   *   - update xpp to point at next unconverted input, and tp to point
11958   *     at next location for converted output
11959   */
11960   long i, j, ni;
11961   int tmp[LOOPCNT];        /* in case input is misaligned */
11962   int *xp;
11963   int nrange = 0;         /* number of range errors */
11964   int realign = 0;        /* "do we need to fix input data alignment?" */
11965   long cxp = (long) *((char**)xpp);
11966 
11967   realign = (cxp & 7) % SIZEOF_INT;
11968   /* sjl: manually stripmine so we can limit amount of
11969    * vector work space reserved to LOOPCNT elements. Also
11970    * makes vectorisation easy */
11971   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
11972     ni=Min(nelems-j,LOOPCNT);
11973     if (realign) {
11974       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
11975       xp = tmp;
11976     } else {
11977       xp = (int *) *xpp;
11978     }
11979    /* copy the next block */
11980 #pragma cdir loopcnt=LOOPCNT
11981 #pragma cdir shortloop
11982     for (i=0; i<ni; i++) {
11983       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
11984      /* test for range errors (not always needed but do it anyway) */
11985      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
11986      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
11987       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
11988     }
11989    /* update xpp and tp */
11990     if (realign) xp = (int *) *xpp;
11991     xp += ni;
11992     tp += ni;
11993     *xpp = (void*)xp;
11994   }
11995   return nrange == 0 ? NC_NOERR : NC_ERANGE;
11996 
11997 #else   /* not SX */
11998 	const char *xp = (const char *) *xpp;
11999 	int status = NC_NOERR;
12000 
12001 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12002 	{
12003 		const int lstatus = ncx_get_int_schar(xp, tp);
12004 		if (status == NC_NOERR) /* report the first encountered error */
12005 			status = lstatus;
12006 	}
12007 
12008 	*xpp = (const void *)xp;
12009 	return status;
12010 #endif
12011 }
12012 
12013 int
ncx_getn_int_short(const void ** xpp,size_t nelems,short * tp)12014 ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
12015 {
12016 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12017 
12018  /* basic algorithm is:
12019   *   - ensure sane alignment of input data
12020   *   - copy (conversion happens automatically) input data
12021   *     to output
12022   *   - update xpp to point at next unconverted input, and tp to point
12023   *     at next location for converted output
12024   */
12025   long i, j, ni;
12026   int tmp[LOOPCNT];        /* in case input is misaligned */
12027   int *xp;
12028   int nrange = 0;         /* number of range errors */
12029   int realign = 0;        /* "do we need to fix input data alignment?" */
12030   long cxp = (long) *((char**)xpp);
12031 
12032   realign = (cxp & 7) % SIZEOF_INT;
12033   /* sjl: manually stripmine so we can limit amount of
12034    * vector work space reserved to LOOPCNT elements. Also
12035    * makes vectorisation easy */
12036   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12037     ni=Min(nelems-j,LOOPCNT);
12038     if (realign) {
12039       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12040       xp = tmp;
12041     } else {
12042       xp = (int *) *xpp;
12043     }
12044    /* copy the next block */
12045 #pragma cdir loopcnt=LOOPCNT
12046 #pragma cdir shortloop
12047     for (i=0; i<ni; i++) {
12048       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
12049      /* test for range errors (not always needed but do it anyway) */
12050      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12051      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12052       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
12053     }
12054    /* update xpp and tp */
12055     if (realign) xp = (int *) *xpp;
12056     xp += ni;
12057     tp += ni;
12058     *xpp = (void*)xp;
12059   }
12060   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12061 
12062 #else   /* not SX */
12063 	const char *xp = (const char *) *xpp;
12064 	int status = NC_NOERR;
12065 
12066 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12067 	{
12068 		const int lstatus = ncx_get_int_short(xp, tp);
12069 		if (status == NC_NOERR) /* report the first encountered error */
12070 			status = lstatus;
12071 	}
12072 
12073 	*xpp = (const void *)xp;
12074 	return status;
12075 #endif
12076 }
12077 
12078 int
ncx_getn_int_long(const void ** xpp,size_t nelems,long * tp)12079 ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
12080 {
12081 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12082 
12083  /* basic algorithm is:
12084   *   - ensure sane alignment of input data
12085   *   - copy (conversion happens automatically) input data
12086   *     to output
12087   *   - update xpp to point at next unconverted input, and tp to point
12088   *     at next location for converted output
12089   */
12090   long i, j, ni;
12091   int tmp[LOOPCNT];        /* in case input is misaligned */
12092   int *xp;
12093   int nrange = 0;         /* number of range errors */
12094   int realign = 0;        /* "do we need to fix input data alignment?" */
12095   long cxp = (long) *((char**)xpp);
12096 
12097   realign = (cxp & 7) % SIZEOF_INT;
12098   /* sjl: manually stripmine so we can limit amount of
12099    * vector work space reserved to LOOPCNT elements. Also
12100    * makes vectorisation easy */
12101   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12102     ni=Min(nelems-j,LOOPCNT);
12103     if (realign) {
12104       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12105       xp = tmp;
12106     } else {
12107       xp = (int *) *xpp;
12108     }
12109    /* copy the next block */
12110 #pragma cdir loopcnt=LOOPCNT
12111 #pragma cdir shortloop
12112     for (i=0; i<ni; i++) {
12113       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
12114      /* test for range errors (not always needed but do it anyway) */
12115      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12116      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12117       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
12118     }
12119    /* update xpp and tp */
12120     if (realign) xp = (int *) *xpp;
12121     xp += ni;
12122     tp += ni;
12123     *xpp = (void*)xp;
12124   }
12125   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12126 
12127 #else   /* not SX */
12128 	const char *xp = (const char *) *xpp;
12129 	int status = NC_NOERR;
12130 
12131 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12132 	{
12133 		const int lstatus = ncx_get_int_long(xp, tp);
12134 		if (status == NC_NOERR) /* report the first encountered error */
12135 			status = lstatus;
12136 	}
12137 
12138 	*xpp = (const void *)xp;
12139 	return status;
12140 #endif
12141 }
12142 
12143 int
ncx_getn_int_float(const void ** xpp,size_t nelems,float * tp)12144 ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
12145 {
12146 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12147 
12148  /* basic algorithm is:
12149   *   - ensure sane alignment of input data
12150   *   - copy (conversion happens automatically) input data
12151   *     to output
12152   *   - update xpp to point at next unconverted input, and tp to point
12153   *     at next location for converted output
12154   */
12155   long i, j, ni;
12156   int tmp[LOOPCNT];        /* in case input is misaligned */
12157   int *xp;
12158   int nrange = 0;         /* number of range errors */
12159   int realign = 0;        /* "do we need to fix input data alignment?" */
12160   long cxp = (long) *((char**)xpp);
12161 
12162   realign = (cxp & 7) % SIZEOF_INT;
12163   /* sjl: manually stripmine so we can limit amount of
12164    * vector work space reserved to LOOPCNT elements. Also
12165    * makes vectorisation easy */
12166   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12167     ni=Min(nelems-j,LOOPCNT);
12168     if (realign) {
12169       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12170       xp = tmp;
12171     } else {
12172       xp = (int *) *xpp;
12173     }
12174    /* copy the next block */
12175 #pragma cdir loopcnt=LOOPCNT
12176 #pragma cdir shortloop
12177     for (i=0; i<ni; i++) {
12178       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
12179      /* test for range errors (not always needed but do it anyway) */
12180      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12181      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12182       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
12183     }
12184    /* update xpp and tp */
12185     if (realign) xp = (int *) *xpp;
12186     xp += ni;
12187     tp += ni;
12188     *xpp = (void*)xp;
12189   }
12190   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12191 
12192 #else   /* not SX */
12193 	const char *xp = (const char *) *xpp;
12194 	int status = NC_NOERR;
12195 
12196 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12197 	{
12198 		const int lstatus = ncx_get_int_float(xp, tp);
12199 		if (status == NC_NOERR) /* report the first encountered error */
12200 			status = lstatus;
12201 	}
12202 
12203 	*xpp = (const void *)xp;
12204 	return status;
12205 #endif
12206 }
12207 
12208 int
ncx_getn_int_double(const void ** xpp,size_t nelems,double * tp)12209 ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
12210 {
12211 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12212 
12213  /* basic algorithm is:
12214   *   - ensure sane alignment of input data
12215   *   - copy (conversion happens automatically) input data
12216   *     to output
12217   *   - update xpp to point at next unconverted input, and tp to point
12218   *     at next location for converted output
12219   */
12220   long i, j, ni;
12221   int tmp[LOOPCNT];        /* in case input is misaligned */
12222   int *xp;
12223   int nrange = 0;         /* number of range errors */
12224   int realign = 0;        /* "do we need to fix input data alignment?" */
12225   long cxp = (long) *((char**)xpp);
12226 
12227   realign = (cxp & 7) % SIZEOF_INT;
12228   /* sjl: manually stripmine so we can limit amount of
12229    * vector work space reserved to LOOPCNT elements. Also
12230    * makes vectorisation easy */
12231   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12232     ni=Min(nelems-j,LOOPCNT);
12233     if (realign) {
12234       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12235       xp = tmp;
12236     } else {
12237       xp = (int *) *xpp;
12238     }
12239    /* copy the next block */
12240 #pragma cdir loopcnt=LOOPCNT
12241 #pragma cdir shortloop
12242     for (i=0; i<ni; i++) {
12243       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
12244      /* test for range errors (not always needed but do it anyway) */
12245      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12246      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12247       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
12248     }
12249    /* update xpp and tp */
12250     if (realign) xp = (int *) *xpp;
12251     xp += ni;
12252     tp += ni;
12253     *xpp = (void*)xp;
12254   }
12255   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12256 
12257 #else   /* not SX */
12258 	const char *xp = (const char *) *xpp;
12259 	int status = NC_NOERR;
12260 
12261 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12262 	{
12263 		const int lstatus = ncx_get_int_double(xp, tp);
12264 		if (status == NC_NOERR) /* report the first encountered error */
12265 			status = lstatus;
12266 	}
12267 
12268 	*xpp = (const void *)xp;
12269 	return status;
12270 #endif
12271 }
12272 
12273 int
ncx_getn_int_longlong(const void ** xpp,size_t nelems,longlong * tp)12274 ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp)
12275 {
12276 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12277 
12278  /* basic algorithm is:
12279   *   - ensure sane alignment of input data
12280   *   - copy (conversion happens automatically) input data
12281   *     to output
12282   *   - update xpp to point at next unconverted input, and tp to point
12283   *     at next location for converted output
12284   */
12285   long i, j, ni;
12286   int tmp[LOOPCNT];        /* in case input is misaligned */
12287   int *xp;
12288   int nrange = 0;         /* number of range errors */
12289   int realign = 0;        /* "do we need to fix input data alignment?" */
12290   long cxp = (long) *((char**)xpp);
12291 
12292   realign = (cxp & 7) % SIZEOF_INT;
12293   /* sjl: manually stripmine so we can limit amount of
12294    * vector work space reserved to LOOPCNT elements. Also
12295    * makes vectorisation easy */
12296   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12297     ni=Min(nelems-j,LOOPCNT);
12298     if (realign) {
12299       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12300       xp = tmp;
12301     } else {
12302       xp = (int *) *xpp;
12303     }
12304    /* copy the next block */
12305 #pragma cdir loopcnt=LOOPCNT
12306 #pragma cdir shortloop
12307     for (i=0; i<ni; i++) {
12308       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
12309      /* test for range errors (not always needed but do it anyway) */
12310      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12311      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12312       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
12313     }
12314    /* update xpp and tp */
12315     if (realign) xp = (int *) *xpp;
12316     xp += ni;
12317     tp += ni;
12318     *xpp = (void*)xp;
12319   }
12320   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12321 
12322 #else   /* not SX */
12323 	const char *xp = (const char *) *xpp;
12324 	int status = NC_NOERR;
12325 
12326 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12327 	{
12328 		const int lstatus = ncx_get_int_longlong(xp, tp);
12329 		if (status == NC_NOERR) /* report the first encountered error */
12330 			status = lstatus;
12331 	}
12332 
12333 	*xpp = (const void *)xp;
12334 	return status;
12335 #endif
12336 }
12337 
12338 int
ncx_getn_int_uchar(const void ** xpp,size_t nelems,uchar * tp)12339 ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
12340 {
12341 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12342 
12343  /* basic algorithm is:
12344   *   - ensure sane alignment of input data
12345   *   - copy (conversion happens automatically) input data
12346   *     to output
12347   *   - update xpp to point at next unconverted input, and tp to point
12348   *     at next location for converted output
12349   */
12350   long i, j, ni;
12351   int tmp[LOOPCNT];        /* in case input is misaligned */
12352   int *xp;
12353   int nrange = 0;         /* number of range errors */
12354   int realign = 0;        /* "do we need to fix input data alignment?" */
12355   long cxp = (long) *((char**)xpp);
12356 
12357   realign = (cxp & 7) % SIZEOF_INT;
12358   /* sjl: manually stripmine so we can limit amount of
12359    * vector work space reserved to LOOPCNT elements. Also
12360    * makes vectorisation easy */
12361   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12362     ni=Min(nelems-j,LOOPCNT);
12363     if (realign) {
12364       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12365       xp = tmp;
12366     } else {
12367       xp = (int *) *xpp;
12368     }
12369    /* copy the next block */
12370 #pragma cdir loopcnt=LOOPCNT
12371 #pragma cdir shortloop
12372     for (i=0; i<ni; i++) {
12373       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
12374      /* test for range errors (not always needed but do it anyway) */
12375      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12376      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12377       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
12378     }
12379    /* update xpp and tp */
12380     if (realign) xp = (int *) *xpp;
12381     xp += ni;
12382     tp += ni;
12383     *xpp = (void*)xp;
12384   }
12385   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12386 
12387 #else   /* not SX */
12388 	const char *xp = (const char *) *xpp;
12389 	int status = NC_NOERR;
12390 
12391 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12392 	{
12393 		const int lstatus = ncx_get_int_uchar(xp, tp);
12394 		if (status == NC_NOERR) /* report the first encountered error */
12395 			status = lstatus;
12396 	}
12397 
12398 	*xpp = (const void *)xp;
12399 	return status;
12400 #endif
12401 }
12402 
12403 int
ncx_getn_int_ushort(const void ** xpp,size_t nelems,ushort * tp)12404 ncx_getn_int_ushort(const void **xpp, size_t nelems, ushort *tp)
12405 {
12406 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12407 
12408  /* basic algorithm is:
12409   *   - ensure sane alignment of input data
12410   *   - copy (conversion happens automatically) input data
12411   *     to output
12412   *   - update xpp to point at next unconverted input, and tp to point
12413   *     at next location for converted output
12414   */
12415   long i, j, ni;
12416   int tmp[LOOPCNT];        /* in case input is misaligned */
12417   int *xp;
12418   int nrange = 0;         /* number of range errors */
12419   int realign = 0;        /* "do we need to fix input data alignment?" */
12420   long cxp = (long) *((char**)xpp);
12421 
12422   realign = (cxp & 7) % SIZEOF_INT;
12423   /* sjl: manually stripmine so we can limit amount of
12424    * vector work space reserved to LOOPCNT elements. Also
12425    * makes vectorisation easy */
12426   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12427     ni=Min(nelems-j,LOOPCNT);
12428     if (realign) {
12429       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12430       xp = tmp;
12431     } else {
12432       xp = (int *) *xpp;
12433     }
12434    /* copy the next block */
12435 #pragma cdir loopcnt=LOOPCNT
12436 #pragma cdir shortloop
12437     for (i=0; i<ni; i++) {
12438       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
12439      /* test for range errors (not always needed but do it anyway) */
12440      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12441      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12442       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
12443     }
12444    /* update xpp and tp */
12445     if (realign) xp = (int *) *xpp;
12446     xp += ni;
12447     tp += ni;
12448     *xpp = (void*)xp;
12449   }
12450   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12451 
12452 #else   /* not SX */
12453 	const char *xp = (const char *) *xpp;
12454 	int status = NC_NOERR;
12455 
12456 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12457 	{
12458 		const int lstatus = ncx_get_int_ushort(xp, tp);
12459 		if (status == NC_NOERR) /* report the first encountered error */
12460 			status = lstatus;
12461 	}
12462 
12463 	*xpp = (const void *)xp;
12464 	return status;
12465 #endif
12466 }
12467 
12468 int
ncx_getn_int_uint(const void ** xpp,size_t nelems,uint * tp)12469 ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp)
12470 {
12471 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12472 
12473  /* basic algorithm is:
12474   *   - ensure sane alignment of input data
12475   *   - copy (conversion happens automatically) input data
12476   *     to output
12477   *   - update xpp to point at next unconverted input, and tp to point
12478   *     at next location for converted output
12479   */
12480   long i, j, ni;
12481   int tmp[LOOPCNT];        /* in case input is misaligned */
12482   int *xp;
12483   int nrange = 0;         /* number of range errors */
12484   int realign = 0;        /* "do we need to fix input data alignment?" */
12485   long cxp = (long) *((char**)xpp);
12486 
12487   realign = (cxp & 7) % SIZEOF_INT;
12488   /* sjl: manually stripmine so we can limit amount of
12489    * vector work space reserved to LOOPCNT elements. Also
12490    * makes vectorisation easy */
12491   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12492     ni=Min(nelems-j,LOOPCNT);
12493     if (realign) {
12494       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12495       xp = tmp;
12496     } else {
12497       xp = (int *) *xpp;
12498     }
12499    /* copy the next block */
12500 #pragma cdir loopcnt=LOOPCNT
12501 #pragma cdir shortloop
12502     for (i=0; i<ni; i++) {
12503       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
12504      /* test for range errors (not always needed but do it anyway) */
12505      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12506      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12507       nrange += xp[i] > UINT_MAX || xp[i] < 0;
12508     }
12509    /* update xpp and tp */
12510     if (realign) xp = (int *) *xpp;
12511     xp += ni;
12512     tp += ni;
12513     *xpp = (void*)xp;
12514   }
12515   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12516 
12517 #else   /* not SX */
12518 	const char *xp = (const char *) *xpp;
12519 	int status = NC_NOERR;
12520 
12521 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12522 	{
12523 		const int lstatus = ncx_get_int_uint(xp, tp);
12524 		if (status == NC_NOERR) /* report the first encountered error */
12525 			status = lstatus;
12526 	}
12527 
12528 	*xpp = (const void *)xp;
12529 	return status;
12530 #endif
12531 }
12532 
12533 int
ncx_getn_int_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)12534 ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
12535 {
12536 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12537 
12538  /* basic algorithm is:
12539   *   - ensure sane alignment of input data
12540   *   - copy (conversion happens automatically) input data
12541   *     to output
12542   *   - update xpp to point at next unconverted input, and tp to point
12543   *     at next location for converted output
12544   */
12545   long i, j, ni;
12546   int tmp[LOOPCNT];        /* in case input is misaligned */
12547   int *xp;
12548   int nrange = 0;         /* number of range errors */
12549   int realign = 0;        /* "do we need to fix input data alignment?" */
12550   long cxp = (long) *((char**)xpp);
12551 
12552   realign = (cxp & 7) % SIZEOF_INT;
12553   /* sjl: manually stripmine so we can limit amount of
12554    * vector work space reserved to LOOPCNT elements. Also
12555    * makes vectorisation easy */
12556   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12557     ni=Min(nelems-j,LOOPCNT);
12558     if (realign) {
12559       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
12560       xp = tmp;
12561     } else {
12562       xp = (int *) *xpp;
12563     }
12564    /* copy the next block */
12565 #pragma cdir loopcnt=LOOPCNT
12566 #pragma cdir shortloop
12567     for (i=0; i<ni; i++) {
12568       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
12569      /* test for range errors (not always needed but do it anyway) */
12570      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
12571      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
12572       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
12573     }
12574    /* update xpp and tp */
12575     if (realign) xp = (int *) *xpp;
12576     xp += ni;
12577     tp += ni;
12578     *xpp = (void*)xp;
12579   }
12580   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12581 
12582 #else   /* not SX */
12583 	const char *xp = (const char *) *xpp;
12584 	int status = NC_NOERR;
12585 
12586 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12587 	{
12588 		const int lstatus = ncx_get_int_ulonglong(xp, tp);
12589 		if (status == NC_NOERR) /* report the first encountered error */
12590 			status = lstatus;
12591 	}
12592 
12593 	*xpp = (const void *)xp;
12594 	return status;
12595 #endif
12596 }
12597 
12598 
12599 #if X_SIZEOF_INT == SIZEOF_INT
12600 /* optimized version */
12601 int
ncx_putn_int_int(void ** xpp,size_t nelems,const int * tp,void * fillp)12602 ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12603 {
12604 #ifdef WORDS_BIGENDIAN
12605 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
12606 # else
12607 	swapn4b(*xpp, tp, nelems);
12608 # endif
12609 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
12610 	return NC_NOERR;
12611 }
12612 #else
12613 int
ncx_putn_int_int(void ** xpp,size_t nelems,const int * tp,void * fillp)12614 ncx_putn_int_int(void **xpp, size_t nelems, const int *tp, void *fillp)
12615 {
12616 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12617 
12618  /* basic algorithm is:
12619   *   - ensure sane alignment of output data
12620   *   - copy (conversion happens automatically) input data
12621   *     to output
12622   *   - update tp to point at next unconverted input, and xpp to point
12623   *     at next location for converted output
12624   */
12625   long i, j, ni;
12626   int tmp[LOOPCNT];        /* in case input is misaligned */
12627   int *xp;
12628   int nrange = 0;         /* number of range errors */
12629   int realign = 0;        /* "do we need to fix input data alignment?" */
12630   long cxp = (long) *((char**)xpp);
12631 
12632   realign = (cxp & 7) % SIZEOF_INT;
12633   /* sjl: manually stripmine so we can limit amount of
12634    * vector work space reserved to LOOPCNT elements. Also
12635    * makes vectorisation easy */
12636   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12637     ni=Min(nelems-j,LOOPCNT);
12638     if (realign) {
12639       xp = tmp;
12640     } else {
12641       xp = (int *) *xpp;
12642     }
12643    /* copy the next block */
12644 #pragma cdir loopcnt=LOOPCNT
12645 #pragma cdir shortloop
12646     for (i=0; i<ni; i++) {
12647       /* the normal case: */
12648       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12649      /* test for range errors (not always needed but do it anyway) */
12650      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12651      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12652       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12653     }
12654    /* copy workspace back if necessary */
12655     if (realign) {
12656       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12657       xp = (int *) *xpp;
12658     }
12659    /* update xpp and tp */
12660     xp += ni;
12661     tp += ni;
12662     *xpp = (void*)xp;
12663   }
12664   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12665 
12666 #else   /* not SX */
12667 
12668 	char *xp = (char *) *xpp;
12669 	int status = NC_NOERR;
12670 
12671 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12672 	{
12673 		int lstatus = ncx_put_int_int(xp, tp, fillp);
12674 		if (status == NC_NOERR) /* report the first encountered error */
12675 			status = lstatus;
12676 	}
12677 
12678 	*xpp = (void *)xp;
12679 	return status;
12680 #endif
12681 }
12682 
12683 #endif
12684 int
ncx_putn_int_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)12685 ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
12686 {
12687 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12688 
12689  /* basic algorithm is:
12690   *   - ensure sane alignment of output data
12691   *   - copy (conversion happens automatically) input data
12692   *     to output
12693   *   - update tp to point at next unconverted input, and xpp to point
12694   *     at next location for converted output
12695   */
12696   long i, j, ni;
12697   int tmp[LOOPCNT];        /* in case input is misaligned */
12698   int *xp;
12699   int nrange = 0;         /* number of range errors */
12700   int realign = 0;        /* "do we need to fix input data alignment?" */
12701   long cxp = (long) *((char**)xpp);
12702 
12703   realign = (cxp & 7) % SIZEOF_INT;
12704   /* sjl: manually stripmine so we can limit amount of
12705    * vector work space reserved to LOOPCNT elements. Also
12706    * makes vectorisation easy */
12707   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12708     ni=Min(nelems-j,LOOPCNT);
12709     if (realign) {
12710       xp = tmp;
12711     } else {
12712       xp = (int *) *xpp;
12713     }
12714    /* copy the next block */
12715 #pragma cdir loopcnt=LOOPCNT
12716 #pragma cdir shortloop
12717     for (i=0; i<ni; i++) {
12718       /* the normal case: */
12719       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12720      /* test for range errors (not always needed but do it anyway) */
12721      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12722      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12723       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12724     }
12725    /* copy workspace back if necessary */
12726     if (realign) {
12727       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12728       xp = (int *) *xpp;
12729     }
12730    /* update xpp and tp */
12731     xp += ni;
12732     tp += ni;
12733     *xpp = (void*)xp;
12734   }
12735   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12736 
12737 #else   /* not SX */
12738 
12739 	char *xp = (char *) *xpp;
12740 	int status = NC_NOERR;
12741 
12742 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12743 	{
12744 		int lstatus = ncx_put_int_schar(xp, tp, fillp);
12745 		if (status == NC_NOERR) /* report the first encountered error */
12746 			status = lstatus;
12747 	}
12748 
12749 	*xpp = (void *)xp;
12750 	return status;
12751 #endif
12752 }
12753 
12754 int
ncx_putn_int_short(void ** xpp,size_t nelems,const short * tp,void * fillp)12755 ncx_putn_int_short(void **xpp, size_t nelems, const short *tp, void *fillp)
12756 {
12757 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12758 
12759  /* basic algorithm is:
12760   *   - ensure sane alignment of output data
12761   *   - copy (conversion happens automatically) input data
12762   *     to output
12763   *   - update tp to point at next unconverted input, and xpp to point
12764   *     at next location for converted output
12765   */
12766   long i, j, ni;
12767   int tmp[LOOPCNT];        /* in case input is misaligned */
12768   int *xp;
12769   int nrange = 0;         /* number of range errors */
12770   int realign = 0;        /* "do we need to fix input data alignment?" */
12771   long cxp = (long) *((char**)xpp);
12772 
12773   realign = (cxp & 7) % SIZEOF_INT;
12774   /* sjl: manually stripmine so we can limit amount of
12775    * vector work space reserved to LOOPCNT elements. Also
12776    * makes vectorisation easy */
12777   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12778     ni=Min(nelems-j,LOOPCNT);
12779     if (realign) {
12780       xp = tmp;
12781     } else {
12782       xp = (int *) *xpp;
12783     }
12784    /* copy the next block */
12785 #pragma cdir loopcnt=LOOPCNT
12786 #pragma cdir shortloop
12787     for (i=0; i<ni; i++) {
12788       /* the normal case: */
12789       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12790      /* test for range errors (not always needed but do it anyway) */
12791      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12792      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12793       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12794     }
12795    /* copy workspace back if necessary */
12796     if (realign) {
12797       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12798       xp = (int *) *xpp;
12799     }
12800    /* update xpp and tp */
12801     xp += ni;
12802     tp += ni;
12803     *xpp = (void*)xp;
12804   }
12805   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12806 
12807 #else   /* not SX */
12808 
12809 	char *xp = (char *) *xpp;
12810 	int status = NC_NOERR;
12811 
12812 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12813 	{
12814 		int lstatus = ncx_put_int_short(xp, tp, fillp);
12815 		if (status == NC_NOERR) /* report the first encountered error */
12816 			status = lstatus;
12817 	}
12818 
12819 	*xpp = (void *)xp;
12820 	return status;
12821 #endif
12822 }
12823 
12824 int
ncx_putn_int_long(void ** xpp,size_t nelems,const long * tp,void * fillp)12825 ncx_putn_int_long(void **xpp, size_t nelems, const long *tp, void *fillp)
12826 {
12827 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12828 
12829  /* basic algorithm is:
12830   *   - ensure sane alignment of output data
12831   *   - copy (conversion happens automatically) input data
12832   *     to output
12833   *   - update tp to point at next unconverted input, and xpp to point
12834   *     at next location for converted output
12835   */
12836   long i, j, ni;
12837   int tmp[LOOPCNT];        /* in case input is misaligned */
12838   int *xp;
12839   int nrange = 0;         /* number of range errors */
12840   int realign = 0;        /* "do we need to fix input data alignment?" */
12841   long cxp = (long) *((char**)xpp);
12842 
12843   realign = (cxp & 7) % SIZEOF_INT;
12844   /* sjl: manually stripmine so we can limit amount of
12845    * vector work space reserved to LOOPCNT elements. Also
12846    * makes vectorisation easy */
12847   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12848     ni=Min(nelems-j,LOOPCNT);
12849     if (realign) {
12850       xp = tmp;
12851     } else {
12852       xp = (int *) *xpp;
12853     }
12854    /* copy the next block */
12855 #pragma cdir loopcnt=LOOPCNT
12856 #pragma cdir shortloop
12857     for (i=0; i<ni; i++) {
12858       /* the normal case: */
12859       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12860      /* test for range errors (not always needed but do it anyway) */
12861      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
12862      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
12863       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12864     }
12865    /* copy workspace back if necessary */
12866     if (realign) {
12867       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12868       xp = (int *) *xpp;
12869     }
12870    /* update xpp and tp */
12871     xp += ni;
12872     tp += ni;
12873     *xpp = (void*)xp;
12874   }
12875   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12876 
12877 #else   /* not SX */
12878 
12879 	char *xp = (char *) *xpp;
12880 	int status = NC_NOERR;
12881 
12882 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12883 	{
12884 		int lstatus = ncx_put_int_long(xp, tp, fillp);
12885 		if (status == NC_NOERR) /* report the first encountered error */
12886 			status = lstatus;
12887 	}
12888 
12889 	*xpp = (void *)xp;
12890 	return status;
12891 #endif
12892 }
12893 
12894 int
ncx_putn_int_float(void ** xpp,size_t nelems,const float * tp,void * fillp)12895 ncx_putn_int_float(void **xpp, size_t nelems, const float *tp, void *fillp)
12896 {
12897 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12898 
12899  /* basic algorithm is:
12900   *   - ensure sane alignment of output data
12901   *   - copy (conversion happens automatically) input data
12902   *     to output
12903   *   - update tp to point at next unconverted input, and xpp to point
12904   *     at next location for converted output
12905   */
12906   long i, j, ni;
12907   int tmp[LOOPCNT];        /* in case input is misaligned */
12908   int *xp;
12909   double d;               /* special case for ncx_putn_int_float */
12910   int nrange = 0;         /* number of range errors */
12911   int realign = 0;        /* "do we need to fix input data alignment?" */
12912   long cxp = (long) *((char**)xpp);
12913 
12914   realign = (cxp & 7) % SIZEOF_INT;
12915   /* sjl: manually stripmine so we can limit amount of
12916    * vector work space reserved to LOOPCNT elements. Also
12917    * makes vectorisation easy */
12918   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12919     ni=Min(nelems-j,LOOPCNT);
12920     if (realign) {
12921       xp = tmp;
12922     } else {
12923       xp = (int *) *xpp;
12924     }
12925    /* copy the next block */
12926 #pragma cdir loopcnt=LOOPCNT
12927 #pragma cdir shortloop
12928     for (i=0; i<ni; i++) {
12929       /* for some reason int to float, for putn, requires a special case */
12930       d = tp[i];
12931       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
12932       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
12933     }
12934    /* copy workspace back if necessary */
12935     if (realign) {
12936       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
12937       xp = (int *) *xpp;
12938     }
12939    /* update xpp and tp */
12940     xp += ni;
12941     tp += ni;
12942     *xpp = (void*)xp;
12943   }
12944   return nrange == 0 ? NC_NOERR : NC_ERANGE;
12945 
12946 #else   /* not SX */
12947 
12948 	char *xp = (char *) *xpp;
12949 	int status = NC_NOERR;
12950 
12951 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
12952 	{
12953 		int lstatus = ncx_put_int_float(xp, tp, fillp);
12954 		if (status == NC_NOERR) /* report the first encountered error */
12955 			status = lstatus;
12956 	}
12957 
12958 	*xpp = (void *)xp;
12959 	return status;
12960 #endif
12961 }
12962 
12963 int
ncx_putn_int_double(void ** xpp,size_t nelems,const double * tp,void * fillp)12964 ncx_putn_int_double(void **xpp, size_t nelems, const double *tp, void *fillp)
12965 {
12966 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
12967 
12968  /* basic algorithm is:
12969   *   - ensure sane alignment of output data
12970   *   - copy (conversion happens automatically) input data
12971   *     to output
12972   *   - update tp to point at next unconverted input, and xpp to point
12973   *     at next location for converted output
12974   */
12975   long i, j, ni;
12976   int tmp[LOOPCNT];        /* in case input is misaligned */
12977   int *xp;
12978   int nrange = 0;         /* number of range errors */
12979   int realign = 0;        /* "do we need to fix input data alignment?" */
12980   long cxp = (long) *((char**)xpp);
12981 
12982   realign = (cxp & 7) % SIZEOF_INT;
12983   /* sjl: manually stripmine so we can limit amount of
12984    * vector work space reserved to LOOPCNT elements. Also
12985    * makes vectorisation easy */
12986   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
12987     ni=Min(nelems-j,LOOPCNT);
12988     if (realign) {
12989       xp = tmp;
12990     } else {
12991       xp = (int *) *xpp;
12992     }
12993    /* copy the next block */
12994 #pragma cdir loopcnt=LOOPCNT
12995 #pragma cdir shortloop
12996     for (i=0; i<ni; i++) {
12997       /* the normal case: */
12998       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
12999      /* test for range errors (not always needed but do it anyway) */
13000      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13001      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13002       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
13003     }
13004    /* copy workspace back if necessary */
13005     if (realign) {
13006       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13007       xp = (int *) *xpp;
13008     }
13009    /* update xpp and tp */
13010     xp += ni;
13011     tp += ni;
13012     *xpp = (void*)xp;
13013   }
13014   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13015 
13016 #else   /* not SX */
13017 
13018 	char *xp = (char *) *xpp;
13019 	int status = NC_NOERR;
13020 
13021 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13022 	{
13023 		int lstatus = ncx_put_int_double(xp, tp, fillp);
13024 		if (status == NC_NOERR) /* report the first encountered error */
13025 			status = lstatus;
13026 	}
13027 
13028 	*xpp = (void *)xp;
13029 	return status;
13030 #endif
13031 }
13032 
13033 int
ncx_putn_int_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)13034 ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
13035 {
13036 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13037 
13038  /* basic algorithm is:
13039   *   - ensure sane alignment of output data
13040   *   - copy (conversion happens automatically) input data
13041   *     to output
13042   *   - update tp to point at next unconverted input, and xpp to point
13043   *     at next location for converted output
13044   */
13045   long i, j, ni;
13046   int tmp[LOOPCNT];        /* in case input is misaligned */
13047   int *xp;
13048   int nrange = 0;         /* number of range errors */
13049   int realign = 0;        /* "do we need to fix input data alignment?" */
13050   long cxp = (long) *((char**)xpp);
13051 
13052   realign = (cxp & 7) % SIZEOF_INT;
13053   /* sjl: manually stripmine so we can limit amount of
13054    * vector work space reserved to LOOPCNT elements. Also
13055    * makes vectorisation easy */
13056   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13057     ni=Min(nelems-j,LOOPCNT);
13058     if (realign) {
13059       xp = tmp;
13060     } else {
13061       xp = (int *) *xpp;
13062     }
13063    /* copy the next block */
13064 #pragma cdir loopcnt=LOOPCNT
13065 #pragma cdir shortloop
13066     for (i=0; i<ni; i++) {
13067       /* the normal case: */
13068       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13069      /* test for range errors (not always needed but do it anyway) */
13070      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13071      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13072       nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
13073     }
13074    /* copy workspace back if necessary */
13075     if (realign) {
13076       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13077       xp = (int *) *xpp;
13078     }
13079    /* update xpp and tp */
13080     xp += ni;
13081     tp += ni;
13082     *xpp = (void*)xp;
13083   }
13084   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13085 
13086 #else   /* not SX */
13087 
13088 	char *xp = (char *) *xpp;
13089 	int status = NC_NOERR;
13090 
13091 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13092 	{
13093 		int lstatus = ncx_put_int_longlong(xp, tp, fillp);
13094 		if (status == NC_NOERR) /* report the first encountered error */
13095 			status = lstatus;
13096 	}
13097 
13098 	*xpp = (void *)xp;
13099 	return status;
13100 #endif
13101 }
13102 
13103 int
ncx_putn_int_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)13104 ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
13105 {
13106 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13107 
13108  /* basic algorithm is:
13109   *   - ensure sane alignment of output data
13110   *   - copy (conversion happens automatically) input data
13111   *     to output
13112   *   - update tp to point at next unconverted input, and xpp to point
13113   *     at next location for converted output
13114   */
13115   long i, j, ni;
13116   int tmp[LOOPCNT];        /* in case input is misaligned */
13117   int *xp;
13118   int nrange = 0;         /* number of range errors */
13119   int realign = 0;        /* "do we need to fix input data alignment?" */
13120   long cxp = (long) *((char**)xpp);
13121 
13122   realign = (cxp & 7) % SIZEOF_INT;
13123   /* sjl: manually stripmine so we can limit amount of
13124    * vector work space reserved to LOOPCNT elements. Also
13125    * makes vectorisation easy */
13126   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13127     ni=Min(nelems-j,LOOPCNT);
13128     if (realign) {
13129       xp = tmp;
13130     } else {
13131       xp = (int *) *xpp;
13132     }
13133    /* copy the next block */
13134 #pragma cdir loopcnt=LOOPCNT
13135 #pragma cdir shortloop
13136     for (i=0; i<ni; i++) {
13137       /* the normal case: */
13138       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13139      /* test for range errors (not always needed but do it anyway) */
13140      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13141      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13142       nrange += tp[i] > X_INT_MAX ;
13143     }
13144    /* copy workspace back if necessary */
13145     if (realign) {
13146       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13147       xp = (int *) *xpp;
13148     }
13149    /* update xpp and tp */
13150     xp += ni;
13151     tp += ni;
13152     *xpp = (void*)xp;
13153   }
13154   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13155 
13156 #else   /* not SX */
13157 
13158 	char *xp = (char *) *xpp;
13159 	int status = NC_NOERR;
13160 
13161 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13162 	{
13163 		int lstatus = ncx_put_int_uchar(xp, tp, fillp);
13164 		if (status == NC_NOERR) /* report the first encountered error */
13165 			status = lstatus;
13166 	}
13167 
13168 	*xpp = (void *)xp;
13169 	return status;
13170 #endif
13171 }
13172 
13173 int
ncx_putn_int_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)13174 ncx_putn_int_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
13175 {
13176 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13177 
13178  /* basic algorithm is:
13179   *   - ensure sane alignment of output data
13180   *   - copy (conversion happens automatically) input data
13181   *     to output
13182   *   - update tp to point at next unconverted input, and xpp to point
13183   *     at next location for converted output
13184   */
13185   long i, j, ni;
13186   int tmp[LOOPCNT];        /* in case input is misaligned */
13187   int *xp;
13188   int nrange = 0;         /* number of range errors */
13189   int realign = 0;        /* "do we need to fix input data alignment?" */
13190   long cxp = (long) *((char**)xpp);
13191 
13192   realign = (cxp & 7) % SIZEOF_INT;
13193   /* sjl: manually stripmine so we can limit amount of
13194    * vector work space reserved to LOOPCNT elements. Also
13195    * makes vectorisation easy */
13196   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13197     ni=Min(nelems-j,LOOPCNT);
13198     if (realign) {
13199       xp = tmp;
13200     } else {
13201       xp = (int *) *xpp;
13202     }
13203    /* copy the next block */
13204 #pragma cdir loopcnt=LOOPCNT
13205 #pragma cdir shortloop
13206     for (i=0; i<ni; i++) {
13207       /* the normal case: */
13208       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13209      /* test for range errors (not always needed but do it anyway) */
13210      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13211      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13212       nrange += tp[i] > X_INT_MAX ;
13213     }
13214    /* copy workspace back if necessary */
13215     if (realign) {
13216       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13217       xp = (int *) *xpp;
13218     }
13219    /* update xpp and tp */
13220     xp += ni;
13221     tp += ni;
13222     *xpp = (void*)xp;
13223   }
13224   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13225 
13226 #else   /* not SX */
13227 
13228 	char *xp = (char *) *xpp;
13229 	int status = NC_NOERR;
13230 
13231 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13232 	{
13233 		int lstatus = ncx_put_int_ushort(xp, tp, fillp);
13234 		if (status == NC_NOERR) /* report the first encountered error */
13235 			status = lstatus;
13236 	}
13237 
13238 	*xpp = (void *)xp;
13239 	return status;
13240 #endif
13241 }
13242 
13243 int
ncx_putn_int_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)13244 ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
13245 {
13246 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13247 
13248  /* basic algorithm is:
13249   *   - ensure sane alignment of output data
13250   *   - copy (conversion happens automatically) input data
13251   *     to output
13252   *   - update tp to point at next unconverted input, and xpp to point
13253   *     at next location for converted output
13254   */
13255   long i, j, ni;
13256   int tmp[LOOPCNT];        /* in case input is misaligned */
13257   int *xp;
13258   int nrange = 0;         /* number of range errors */
13259   int realign = 0;        /* "do we need to fix input data alignment?" */
13260   long cxp = (long) *((char**)xpp);
13261 
13262   realign = (cxp & 7) % SIZEOF_INT;
13263   /* sjl: manually stripmine so we can limit amount of
13264    * vector work space reserved to LOOPCNT elements. Also
13265    * makes vectorisation easy */
13266   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13267     ni=Min(nelems-j,LOOPCNT);
13268     if (realign) {
13269       xp = tmp;
13270     } else {
13271       xp = (int *) *xpp;
13272     }
13273    /* copy the next block */
13274 #pragma cdir loopcnt=LOOPCNT
13275 #pragma cdir shortloop
13276     for (i=0; i<ni; i++) {
13277       /* the normal case: */
13278       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13279      /* test for range errors (not always needed but do it anyway) */
13280      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13281      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13282       nrange += tp[i] > X_INT_MAX ;
13283     }
13284    /* copy workspace back if necessary */
13285     if (realign) {
13286       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13287       xp = (int *) *xpp;
13288     }
13289    /* update xpp and tp */
13290     xp += ni;
13291     tp += ni;
13292     *xpp = (void*)xp;
13293   }
13294   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13295 
13296 #else   /* not SX */
13297 
13298 	char *xp = (char *) *xpp;
13299 	int status = NC_NOERR;
13300 
13301 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13302 	{
13303 		int lstatus = ncx_put_int_uint(xp, tp, fillp);
13304 		if (status == NC_NOERR) /* report the first encountered error */
13305 			status = lstatus;
13306 	}
13307 
13308 	*xpp = (void *)xp;
13309 	return status;
13310 #endif
13311 }
13312 
13313 int
ncx_putn_int_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)13314 ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
13315 {
13316 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT
13317 
13318  /* basic algorithm is:
13319   *   - ensure sane alignment of output data
13320   *   - copy (conversion happens automatically) input data
13321   *     to output
13322   *   - update tp to point at next unconverted input, and xpp to point
13323   *     at next location for converted output
13324   */
13325   long i, j, ni;
13326   int tmp[LOOPCNT];        /* in case input is misaligned */
13327   int *xp;
13328   int nrange = 0;         /* number of range errors */
13329   int realign = 0;        /* "do we need to fix input data alignment?" */
13330   long cxp = (long) *((char**)xpp);
13331 
13332   realign = (cxp & 7) % SIZEOF_INT;
13333   /* sjl: manually stripmine so we can limit amount of
13334    * vector work space reserved to LOOPCNT elements. Also
13335    * makes vectorisation easy */
13336   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13337     ni=Min(nelems-j,LOOPCNT);
13338     if (realign) {
13339       xp = tmp;
13340     } else {
13341       xp = (int *) *xpp;
13342     }
13343    /* copy the next block */
13344 #pragma cdir loopcnt=LOOPCNT
13345 #pragma cdir shortloop
13346     for (i=0; i<ni; i++) {
13347       /* the normal case: */
13348       xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
13349      /* test for range errors (not always needed but do it anyway) */
13350      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
13351      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
13352       nrange += tp[i] > X_INT_MAX ;
13353     }
13354    /* copy workspace back if necessary */
13355     if (realign) {
13356       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
13357       xp = (int *) *xpp;
13358     }
13359    /* update xpp and tp */
13360     xp += ni;
13361     tp += ni;
13362     *xpp = (void*)xp;
13363   }
13364   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13365 
13366 #else   /* not SX */
13367 
13368 	char *xp = (char *) *xpp;
13369 	int status = NC_NOERR;
13370 
13371 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
13372 	{
13373 		int lstatus = ncx_put_int_ulonglong(xp, tp, fillp);
13374 		if (status == NC_NOERR) /* report the first encountered error */
13375 			status = lstatus;
13376 	}
13377 
13378 	*xpp = (void *)xp;
13379 	return status;
13380 #endif
13381 }
13382 
13383 
13384 /* uint ----------------------------------------------------------------------*/
13385 
13386 #if X_SIZEOF_UINT == SIZEOF_UINT
13387 /* optimized version */
13388 int
ncx_getn_uint_uint(const void ** xpp,size_t nelems,unsigned int * tp)13389 ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
13390 {
13391 #ifdef WORDS_BIGENDIAN
13392 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
13393 # else
13394 	swapn4b(tp, *xpp, nelems);
13395 # endif
13396 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
13397 	return NC_NOERR;
13398 }
13399 #else
13400 int
ncx_getn_uint_uint(const void ** xpp,size_t nelems,uint * tp)13401 ncx_getn_uint_uint(const void **xpp, size_t nelems, uint *tp)
13402 {
13403 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13404 
13405  /* basic algorithm is:
13406   *   - ensure sane alignment of input data
13407   *   - copy (conversion happens automatically) input data
13408   *     to output
13409   *   - update xpp to point at next unconverted input, and tp to point
13410   *     at next location for converted output
13411   */
13412   long i, j, ni;
13413   uint tmp[LOOPCNT];        /* in case input is misaligned */
13414   uint *xp;
13415   int nrange = 0;         /* number of range errors */
13416   int realign = 0;        /* "do we need to fix input data alignment?" */
13417   long cxp = (long) *((char**)xpp);
13418 
13419   realign = (cxp & 7) % SIZEOF_UINT;
13420   /* sjl: manually stripmine so we can limit amount of
13421    * vector work space reserved to LOOPCNT elements. Also
13422    * makes vectorisation easy */
13423   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13424     ni=Min(nelems-j,LOOPCNT);
13425     if (realign) {
13426       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13427       xp = tmp;
13428     } else {
13429       xp = (uint *) *xpp;
13430     }
13431    /* copy the next block */
13432 #pragma cdir loopcnt=LOOPCNT
13433 #pragma cdir shortloop
13434     for (i=0; i<ni; i++) {
13435       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
13436      /* test for range errors (not always needed but do it anyway) */
13437      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13438      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13439       nrange += xp[i] > UINT_MAX ;
13440     }
13441    /* update xpp and tp */
13442     if (realign) xp = (uint *) *xpp;
13443     xp += ni;
13444     tp += ni;
13445     *xpp = (void*)xp;
13446   }
13447   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13448 
13449 #else   /* not SX */
13450 	const char *xp = (const char *) *xpp;
13451 	int status = NC_NOERR;
13452 
13453 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13454 	{
13455 		const int lstatus = ncx_get_uint_uint(xp, tp);
13456 		if (status == NC_NOERR) /* report the first encountered error */
13457 			status = lstatus;
13458 	}
13459 
13460 	*xpp = (const void *)xp;
13461 	return status;
13462 #endif
13463 }
13464 
13465 #endif
13466 int
ncx_getn_uint_schar(const void ** xpp,size_t nelems,schar * tp)13467 ncx_getn_uint_schar(const void **xpp, size_t nelems, schar *tp)
13468 {
13469 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13470 
13471  /* basic algorithm is:
13472   *   - ensure sane alignment of input data
13473   *   - copy (conversion happens automatically) input data
13474   *     to output
13475   *   - update xpp to point at next unconverted input, and tp to point
13476   *     at next location for converted output
13477   */
13478   long i, j, ni;
13479   uint tmp[LOOPCNT];        /* in case input is misaligned */
13480   uint *xp;
13481   int nrange = 0;         /* number of range errors */
13482   int realign = 0;        /* "do we need to fix input data alignment?" */
13483   long cxp = (long) *((char**)xpp);
13484 
13485   realign = (cxp & 7) % SIZEOF_UINT;
13486   /* sjl: manually stripmine so we can limit amount of
13487    * vector work space reserved to LOOPCNT elements. Also
13488    * makes vectorisation easy */
13489   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13490     ni=Min(nelems-j,LOOPCNT);
13491     if (realign) {
13492       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13493       xp = tmp;
13494     } else {
13495       xp = (uint *) *xpp;
13496     }
13497    /* copy the next block */
13498 #pragma cdir loopcnt=LOOPCNT
13499 #pragma cdir shortloop
13500     for (i=0; i<ni; i++) {
13501       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
13502      /* test for range errors (not always needed but do it anyway) */
13503      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13504      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13505       nrange += xp[i] > SCHAR_MAX ;
13506     }
13507    /* update xpp and tp */
13508     if (realign) xp = (uint *) *xpp;
13509     xp += ni;
13510     tp += ni;
13511     *xpp = (void*)xp;
13512   }
13513   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13514 
13515 #else   /* not SX */
13516 	const char *xp = (const char *) *xpp;
13517 	int status = NC_NOERR;
13518 
13519 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13520 	{
13521 		const int lstatus = ncx_get_uint_schar(xp, tp);
13522 		if (status == NC_NOERR) /* report the first encountered error */
13523 			status = lstatus;
13524 	}
13525 
13526 	*xpp = (const void *)xp;
13527 	return status;
13528 #endif
13529 }
13530 
13531 int
ncx_getn_uint_short(const void ** xpp,size_t nelems,short * tp)13532 ncx_getn_uint_short(const void **xpp, size_t nelems, short *tp)
13533 {
13534 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13535 
13536  /* basic algorithm is:
13537   *   - ensure sane alignment of input data
13538   *   - copy (conversion happens automatically) input data
13539   *     to output
13540   *   - update xpp to point at next unconverted input, and tp to point
13541   *     at next location for converted output
13542   */
13543   long i, j, ni;
13544   uint tmp[LOOPCNT];        /* in case input is misaligned */
13545   uint *xp;
13546   int nrange = 0;         /* number of range errors */
13547   int realign = 0;        /* "do we need to fix input data alignment?" */
13548   long cxp = (long) *((char**)xpp);
13549 
13550   realign = (cxp & 7) % SIZEOF_UINT;
13551   /* sjl: manually stripmine so we can limit amount of
13552    * vector work space reserved to LOOPCNT elements. Also
13553    * makes vectorisation easy */
13554   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13555     ni=Min(nelems-j,LOOPCNT);
13556     if (realign) {
13557       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13558       xp = tmp;
13559     } else {
13560       xp = (uint *) *xpp;
13561     }
13562    /* copy the next block */
13563 #pragma cdir loopcnt=LOOPCNT
13564 #pragma cdir shortloop
13565     for (i=0; i<ni; i++) {
13566       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
13567      /* test for range errors (not always needed but do it anyway) */
13568      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13569      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13570       nrange += xp[i] > SHORT_MAX ;
13571     }
13572    /* update xpp and tp */
13573     if (realign) xp = (uint *) *xpp;
13574     xp += ni;
13575     tp += ni;
13576     *xpp = (void*)xp;
13577   }
13578   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13579 
13580 #else   /* not SX */
13581 	const char *xp = (const char *) *xpp;
13582 	int status = NC_NOERR;
13583 
13584 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13585 	{
13586 		const int lstatus = ncx_get_uint_short(xp, tp);
13587 		if (status == NC_NOERR) /* report the first encountered error */
13588 			status = lstatus;
13589 	}
13590 
13591 	*xpp = (const void *)xp;
13592 	return status;
13593 #endif
13594 }
13595 
13596 int
ncx_getn_uint_int(const void ** xpp,size_t nelems,int * tp)13597 ncx_getn_uint_int(const void **xpp, size_t nelems, int *tp)
13598 {
13599 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13600 
13601  /* basic algorithm is:
13602   *   - ensure sane alignment of input data
13603   *   - copy (conversion happens automatically) input data
13604   *     to output
13605   *   - update xpp to point at next unconverted input, and tp to point
13606   *     at next location for converted output
13607   */
13608   long i, j, ni;
13609   uint tmp[LOOPCNT];        /* in case input is misaligned */
13610   uint *xp;
13611   int nrange = 0;         /* number of range errors */
13612   int realign = 0;        /* "do we need to fix input data alignment?" */
13613   long cxp = (long) *((char**)xpp);
13614 
13615   realign = (cxp & 7) % SIZEOF_UINT;
13616   /* sjl: manually stripmine so we can limit amount of
13617    * vector work space reserved to LOOPCNT elements. Also
13618    * makes vectorisation easy */
13619   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13620     ni=Min(nelems-j,LOOPCNT);
13621     if (realign) {
13622       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13623       xp = tmp;
13624     } else {
13625       xp = (uint *) *xpp;
13626     }
13627    /* copy the next block */
13628 #pragma cdir loopcnt=LOOPCNT
13629 #pragma cdir shortloop
13630     for (i=0; i<ni; i++) {
13631       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
13632      /* test for range errors (not always needed but do it anyway) */
13633      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13634      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13635       nrange += xp[i] > INT_MAX ;
13636     }
13637    /* update xpp and tp */
13638     if (realign) xp = (uint *) *xpp;
13639     xp += ni;
13640     tp += ni;
13641     *xpp = (void*)xp;
13642   }
13643   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13644 
13645 #else   /* not SX */
13646 	const char *xp = (const char *) *xpp;
13647 	int status = NC_NOERR;
13648 
13649 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13650 	{
13651 		const int lstatus = ncx_get_uint_int(xp, tp);
13652 		if (status == NC_NOERR) /* report the first encountered error */
13653 			status = lstatus;
13654 	}
13655 
13656 	*xpp = (const void *)xp;
13657 	return status;
13658 #endif
13659 }
13660 
13661 int
ncx_getn_uint_long(const void ** xpp,size_t nelems,long * tp)13662 ncx_getn_uint_long(const void **xpp, size_t nelems, long *tp)
13663 {
13664 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13665 
13666  /* basic algorithm is:
13667   *   - ensure sane alignment of input data
13668   *   - copy (conversion happens automatically) input data
13669   *     to output
13670   *   - update xpp to point at next unconverted input, and tp to point
13671   *     at next location for converted output
13672   */
13673   long i, j, ni;
13674   uint tmp[LOOPCNT];        /* in case input is misaligned */
13675   uint *xp;
13676   int nrange = 0;         /* number of range errors */
13677   int realign = 0;        /* "do we need to fix input data alignment?" */
13678   long cxp = (long) *((char**)xpp);
13679 
13680   realign = (cxp & 7) % SIZEOF_UINT;
13681   /* sjl: manually stripmine so we can limit amount of
13682    * vector work space reserved to LOOPCNT elements. Also
13683    * makes vectorisation easy */
13684   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13685     ni=Min(nelems-j,LOOPCNT);
13686     if (realign) {
13687       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13688       xp = tmp;
13689     } else {
13690       xp = (uint *) *xpp;
13691     }
13692    /* copy the next block */
13693 #pragma cdir loopcnt=LOOPCNT
13694 #pragma cdir shortloop
13695     for (i=0; i<ni; i++) {
13696       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
13697      /* test for range errors (not always needed but do it anyway) */
13698      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13699      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13700       nrange += xp[i] > LONG_MAX ;
13701     }
13702    /* update xpp and tp */
13703     if (realign) xp = (uint *) *xpp;
13704     xp += ni;
13705     tp += ni;
13706     *xpp = (void*)xp;
13707   }
13708   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13709 
13710 #else   /* not SX */
13711 	const char *xp = (const char *) *xpp;
13712 	int status = NC_NOERR;
13713 
13714 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13715 	{
13716 		const int lstatus = ncx_get_uint_long(xp, tp);
13717 		if (status == NC_NOERR) /* report the first encountered error */
13718 			status = lstatus;
13719 	}
13720 
13721 	*xpp = (const void *)xp;
13722 	return status;
13723 #endif
13724 }
13725 
13726 int
ncx_getn_uint_float(const void ** xpp,size_t nelems,float * tp)13727 ncx_getn_uint_float(const void **xpp, size_t nelems, float *tp)
13728 {
13729 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13730 
13731  /* basic algorithm is:
13732   *   - ensure sane alignment of input data
13733   *   - copy (conversion happens automatically) input data
13734   *     to output
13735   *   - update xpp to point at next unconverted input, and tp to point
13736   *     at next location for converted output
13737   */
13738   long i, j, ni;
13739   uint tmp[LOOPCNT];        /* in case input is misaligned */
13740   uint *xp;
13741   int nrange = 0;         /* number of range errors */
13742   int realign = 0;        /* "do we need to fix input data alignment?" */
13743   long cxp = (long) *((char**)xpp);
13744 
13745   realign = (cxp & 7) % SIZEOF_UINT;
13746   /* sjl: manually stripmine so we can limit amount of
13747    * vector work space reserved to LOOPCNT elements. Also
13748    * makes vectorisation easy */
13749   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13750     ni=Min(nelems-j,LOOPCNT);
13751     if (realign) {
13752       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13753       xp = tmp;
13754     } else {
13755       xp = (uint *) *xpp;
13756     }
13757    /* copy the next block */
13758 #pragma cdir loopcnt=LOOPCNT
13759 #pragma cdir shortloop
13760     for (i=0; i<ni; i++) {
13761       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
13762      /* test for range errors (not always needed but do it anyway) */
13763      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13764      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13765       nrange += xp[i] > FLOAT_MAX ;
13766     }
13767    /* update xpp and tp */
13768     if (realign) xp = (uint *) *xpp;
13769     xp += ni;
13770     tp += ni;
13771     *xpp = (void*)xp;
13772   }
13773   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13774 
13775 #else   /* not SX */
13776 	const char *xp = (const char *) *xpp;
13777 	int status = NC_NOERR;
13778 
13779 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13780 	{
13781 		const int lstatus = ncx_get_uint_float(xp, tp);
13782 		if (status == NC_NOERR) /* report the first encountered error */
13783 			status = lstatus;
13784 	}
13785 
13786 	*xpp = (const void *)xp;
13787 	return status;
13788 #endif
13789 }
13790 
13791 int
ncx_getn_uint_double(const void ** xpp,size_t nelems,double * tp)13792 ncx_getn_uint_double(const void **xpp, size_t nelems, double *tp)
13793 {
13794 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13795 
13796  /* basic algorithm is:
13797   *   - ensure sane alignment of input data
13798   *   - copy (conversion happens automatically) input data
13799   *     to output
13800   *   - update xpp to point at next unconverted input, and tp to point
13801   *     at next location for converted output
13802   */
13803   long i, j, ni;
13804   uint tmp[LOOPCNT];        /* in case input is misaligned */
13805   uint *xp;
13806   int nrange = 0;         /* number of range errors */
13807   int realign = 0;        /* "do we need to fix input data alignment?" */
13808   long cxp = (long) *((char**)xpp);
13809 
13810   realign = (cxp & 7) % SIZEOF_UINT;
13811   /* sjl: manually stripmine so we can limit amount of
13812    * vector work space reserved to LOOPCNT elements. Also
13813    * makes vectorisation easy */
13814   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13815     ni=Min(nelems-j,LOOPCNT);
13816     if (realign) {
13817       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13818       xp = tmp;
13819     } else {
13820       xp = (uint *) *xpp;
13821     }
13822    /* copy the next block */
13823 #pragma cdir loopcnt=LOOPCNT
13824 #pragma cdir shortloop
13825     for (i=0; i<ni; i++) {
13826       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
13827      /* test for range errors (not always needed but do it anyway) */
13828      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13829      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13830       nrange += xp[i] > DOUBLE_MAX ;
13831     }
13832    /* update xpp and tp */
13833     if (realign) xp = (uint *) *xpp;
13834     xp += ni;
13835     tp += ni;
13836     *xpp = (void*)xp;
13837   }
13838   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13839 
13840 #else   /* not SX */
13841 	const char *xp = (const char *) *xpp;
13842 	int status = NC_NOERR;
13843 
13844 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13845 	{
13846 		const int lstatus = ncx_get_uint_double(xp, tp);
13847 		if (status == NC_NOERR) /* report the first encountered error */
13848 			status = lstatus;
13849 	}
13850 
13851 	*xpp = (const void *)xp;
13852 	return status;
13853 #endif
13854 }
13855 
13856 int
ncx_getn_uint_longlong(const void ** xpp,size_t nelems,longlong * tp)13857 ncx_getn_uint_longlong(const void **xpp, size_t nelems, longlong *tp)
13858 {
13859 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13860 
13861  /* basic algorithm is:
13862   *   - ensure sane alignment of input data
13863   *   - copy (conversion happens automatically) input data
13864   *     to output
13865   *   - update xpp to point at next unconverted input, and tp to point
13866   *     at next location for converted output
13867   */
13868   long i, j, ni;
13869   uint tmp[LOOPCNT];        /* in case input is misaligned */
13870   uint *xp;
13871   int nrange = 0;         /* number of range errors */
13872   int realign = 0;        /* "do we need to fix input data alignment?" */
13873   long cxp = (long) *((char**)xpp);
13874 
13875   realign = (cxp & 7) % SIZEOF_UINT;
13876   /* sjl: manually stripmine so we can limit amount of
13877    * vector work space reserved to LOOPCNT elements. Also
13878    * makes vectorisation easy */
13879   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13880     ni=Min(nelems-j,LOOPCNT);
13881     if (realign) {
13882       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13883       xp = tmp;
13884     } else {
13885       xp = (uint *) *xpp;
13886     }
13887    /* copy the next block */
13888 #pragma cdir loopcnt=LOOPCNT
13889 #pragma cdir shortloop
13890     for (i=0; i<ni; i++) {
13891       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
13892      /* test for range errors (not always needed but do it anyway) */
13893      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13894      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13895       nrange += xp[i] > LONGLONG_MAX ;
13896     }
13897    /* update xpp and tp */
13898     if (realign) xp = (uint *) *xpp;
13899     xp += ni;
13900     tp += ni;
13901     *xpp = (void*)xp;
13902   }
13903   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13904 
13905 #else   /* not SX */
13906 	const char *xp = (const char *) *xpp;
13907 	int status = NC_NOERR;
13908 
13909 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13910 	{
13911 		const int lstatus = ncx_get_uint_longlong(xp, tp);
13912 		if (status == NC_NOERR) /* report the first encountered error */
13913 			status = lstatus;
13914 	}
13915 
13916 	*xpp = (const void *)xp;
13917 	return status;
13918 #endif
13919 }
13920 
13921 int
ncx_getn_uint_uchar(const void ** xpp,size_t nelems,uchar * tp)13922 ncx_getn_uint_uchar(const void **xpp, size_t nelems, uchar *tp)
13923 {
13924 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13925 
13926  /* basic algorithm is:
13927   *   - ensure sane alignment of input data
13928   *   - copy (conversion happens automatically) input data
13929   *     to output
13930   *   - update xpp to point at next unconverted input, and tp to point
13931   *     at next location for converted output
13932   */
13933   long i, j, ni;
13934   uint tmp[LOOPCNT];        /* in case input is misaligned */
13935   uint *xp;
13936   int nrange = 0;         /* number of range errors */
13937   int realign = 0;        /* "do we need to fix input data alignment?" */
13938   long cxp = (long) *((char**)xpp);
13939 
13940   realign = (cxp & 7) % SIZEOF_UINT;
13941   /* sjl: manually stripmine so we can limit amount of
13942    * vector work space reserved to LOOPCNT elements. Also
13943    * makes vectorisation easy */
13944   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
13945     ni=Min(nelems-j,LOOPCNT);
13946     if (realign) {
13947       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
13948       xp = tmp;
13949     } else {
13950       xp = (uint *) *xpp;
13951     }
13952    /* copy the next block */
13953 #pragma cdir loopcnt=LOOPCNT
13954 #pragma cdir shortloop
13955     for (i=0; i<ni; i++) {
13956       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
13957      /* test for range errors (not always needed but do it anyway) */
13958      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
13959      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
13960       nrange += xp[i] > UCHAR_MAX ;
13961     }
13962    /* update xpp and tp */
13963     if (realign) xp = (uint *) *xpp;
13964     xp += ni;
13965     tp += ni;
13966     *xpp = (void*)xp;
13967   }
13968   return nrange == 0 ? NC_NOERR : NC_ERANGE;
13969 
13970 #else   /* not SX */
13971 	const char *xp = (const char *) *xpp;
13972 	int status = NC_NOERR;
13973 
13974 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
13975 	{
13976 		const int lstatus = ncx_get_uint_uchar(xp, tp);
13977 		if (status == NC_NOERR) /* report the first encountered error */
13978 			status = lstatus;
13979 	}
13980 
13981 	*xpp = (const void *)xp;
13982 	return status;
13983 #endif
13984 }
13985 
13986 int
ncx_getn_uint_ushort(const void ** xpp,size_t nelems,ushort * tp)13987 ncx_getn_uint_ushort(const void **xpp, size_t nelems, ushort *tp)
13988 {
13989 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
13990 
13991  /* basic algorithm is:
13992   *   - ensure sane alignment of input data
13993   *   - copy (conversion happens automatically) input data
13994   *     to output
13995   *   - update xpp to point at next unconverted input, and tp to point
13996   *     at next location for converted output
13997   */
13998   long i, j, ni;
13999   uint tmp[LOOPCNT];        /* in case input is misaligned */
14000   uint *xp;
14001   int nrange = 0;         /* number of range errors */
14002   int realign = 0;        /* "do we need to fix input data alignment?" */
14003   long cxp = (long) *((char**)xpp);
14004 
14005   realign = (cxp & 7) % SIZEOF_UINT;
14006   /* sjl: manually stripmine so we can limit amount of
14007    * vector work space reserved to LOOPCNT elements. Also
14008    * makes vectorisation easy */
14009   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14010     ni=Min(nelems-j,LOOPCNT);
14011     if (realign) {
14012       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
14013       xp = tmp;
14014     } else {
14015       xp = (uint *) *xpp;
14016     }
14017    /* copy the next block */
14018 #pragma cdir loopcnt=LOOPCNT
14019 #pragma cdir shortloop
14020     for (i=0; i<ni; i++) {
14021       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
14022      /* test for range errors (not always needed but do it anyway) */
14023      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14024      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14025       nrange += xp[i] > USHORT_MAX ;
14026     }
14027    /* update xpp and tp */
14028     if (realign) xp = (uint *) *xpp;
14029     xp += ni;
14030     tp += ni;
14031     *xpp = (void*)xp;
14032   }
14033   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14034 
14035 #else   /* not SX */
14036 	const char *xp = (const char *) *xpp;
14037 	int status = NC_NOERR;
14038 
14039 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14040 	{
14041 		const int lstatus = ncx_get_uint_ushort(xp, tp);
14042 		if (status == NC_NOERR) /* report the first encountered error */
14043 			status = lstatus;
14044 	}
14045 
14046 	*xpp = (const void *)xp;
14047 	return status;
14048 #endif
14049 }
14050 
14051 int
ncx_getn_uint_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)14052 ncx_getn_uint_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
14053 {
14054 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14055 
14056  /* basic algorithm is:
14057   *   - ensure sane alignment of input data
14058   *   - copy (conversion happens automatically) input data
14059   *     to output
14060   *   - update xpp to point at next unconverted input, and tp to point
14061   *     at next location for converted output
14062   */
14063   long i, j, ni;
14064   uint tmp[LOOPCNT];        /* in case input is misaligned */
14065   uint *xp;
14066   int nrange = 0;         /* number of range errors */
14067   int realign = 0;        /* "do we need to fix input data alignment?" */
14068   long cxp = (long) *((char**)xpp);
14069 
14070   realign = (cxp & 7) % SIZEOF_UINT;
14071   /* sjl: manually stripmine so we can limit amount of
14072    * vector work space reserved to LOOPCNT elements. Also
14073    * makes vectorisation easy */
14074   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14075     ni=Min(nelems-j,LOOPCNT);
14076     if (realign) {
14077       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
14078       xp = tmp;
14079     } else {
14080       xp = (uint *) *xpp;
14081     }
14082    /* copy the next block */
14083 #pragma cdir loopcnt=LOOPCNT
14084 #pragma cdir shortloop
14085     for (i=0; i<ni; i++) {
14086       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
14087      /* test for range errors (not always needed but do it anyway) */
14088      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
14089      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
14090       nrange += xp[i] > ULONGLONG_MAX ;
14091     }
14092    /* update xpp and tp */
14093     if (realign) xp = (uint *) *xpp;
14094     xp += ni;
14095     tp += ni;
14096     *xpp = (void*)xp;
14097   }
14098   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14099 
14100 #else   /* not SX */
14101 	const char *xp = (const char *) *xpp;
14102 	int status = NC_NOERR;
14103 
14104 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14105 	{
14106 		const int lstatus = ncx_get_uint_ulonglong(xp, tp);
14107 		if (status == NC_NOERR) /* report the first encountered error */
14108 			status = lstatus;
14109 	}
14110 
14111 	*xpp = (const void *)xp;
14112 	return status;
14113 #endif
14114 }
14115 
14116 
14117 #if X_SIZEOF_UINT == SIZEOF_UINT
14118 /* optimized version */
14119 int
ncx_putn_uint_uint(void ** xpp,size_t nelems,const unsigned int * tp,void * fillp)14120 ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp, void *fillp)
14121 {
14122 #ifdef WORDS_BIGENDIAN
14123 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
14124 # else
14125 	swapn4b(*xpp, tp, nelems);
14126 # endif
14127 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
14128 	return NC_NOERR;
14129 }
14130 #else
14131 int
ncx_putn_uint_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)14132 ncx_putn_uint_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
14133 {
14134 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14135 
14136  /* basic algorithm is:
14137   *   - ensure sane alignment of output data
14138   *   - copy (conversion happens automatically) input data
14139   *     to output
14140   *   - update tp to point at next unconverted input, and xpp to point
14141   *     at next location for converted output
14142   */
14143   long i, j, ni;
14144   uint tmp[LOOPCNT];        /* in case input is misaligned */
14145   uint *xp;
14146   int nrange = 0;         /* number of range errors */
14147   int realign = 0;        /* "do we need to fix input data alignment?" */
14148   long cxp = (long) *((char**)xpp);
14149 
14150   realign = (cxp & 7) % SIZEOF_UINT;
14151   /* sjl: manually stripmine so we can limit amount of
14152    * vector work space reserved to LOOPCNT elements. Also
14153    * makes vectorisation easy */
14154   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14155     ni=Min(nelems-j,LOOPCNT);
14156     if (realign) {
14157       xp = tmp;
14158     } else {
14159       xp = (uint *) *xpp;
14160     }
14161    /* copy the next block */
14162 #pragma cdir loopcnt=LOOPCNT
14163 #pragma cdir shortloop
14164     for (i=0; i<ni; i++) {
14165       /* the normal case: */
14166       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14167      /* test for range errors (not always needed but do it anyway) */
14168      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14169      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14170       nrange += tp[i] > X_UINT_MAX ;
14171     }
14172    /* copy workspace back if necessary */
14173     if (realign) {
14174       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14175       xp = (uint *) *xpp;
14176     }
14177    /* update xpp and tp */
14178     xp += ni;
14179     tp += ni;
14180     *xpp = (void*)xp;
14181   }
14182   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14183 
14184 #else   /* not SX */
14185 
14186 	char *xp = (char *) *xpp;
14187 	int status = NC_NOERR;
14188 
14189 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14190 	{
14191 		int lstatus = ncx_put_uint_uint(xp, tp, fillp);
14192 		if (status == NC_NOERR) /* report the first encountered error */
14193 			status = lstatus;
14194 	}
14195 
14196 	*xpp = (void *)xp;
14197 	return status;
14198 #endif
14199 }
14200 
14201 #endif
14202 int
ncx_putn_uint_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)14203 ncx_putn_uint_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
14204 {
14205 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14206 
14207  /* basic algorithm is:
14208   *   - ensure sane alignment of output data
14209   *   - copy (conversion happens automatically) input data
14210   *     to output
14211   *   - update tp to point at next unconverted input, and xpp to point
14212   *     at next location for converted output
14213   */
14214   long i, j, ni;
14215   uint tmp[LOOPCNT];        /* in case input is misaligned */
14216   uint *xp;
14217   int nrange = 0;         /* number of range errors */
14218   int realign = 0;        /* "do we need to fix input data alignment?" */
14219   long cxp = (long) *((char**)xpp);
14220 
14221   realign = (cxp & 7) % SIZEOF_UINT;
14222   /* sjl: manually stripmine so we can limit amount of
14223    * vector work space reserved to LOOPCNT elements. Also
14224    * makes vectorisation easy */
14225   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14226     ni=Min(nelems-j,LOOPCNT);
14227     if (realign) {
14228       xp = tmp;
14229     } else {
14230       xp = (uint *) *xpp;
14231     }
14232    /* copy the next block */
14233 #pragma cdir loopcnt=LOOPCNT
14234 #pragma cdir shortloop
14235     for (i=0; i<ni; i++) {
14236       /* the normal case: */
14237       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14238      /* test for range errors (not always needed but do it anyway) */
14239      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14240      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14241       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14242     }
14243    /* copy workspace back if necessary */
14244     if (realign) {
14245       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14246       xp = (uint *) *xpp;
14247     }
14248    /* update xpp and tp */
14249     xp += ni;
14250     tp += ni;
14251     *xpp = (void*)xp;
14252   }
14253   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14254 
14255 #else   /* not SX */
14256 
14257 	char *xp = (char *) *xpp;
14258 	int status = NC_NOERR;
14259 
14260 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14261 	{
14262 		int lstatus = ncx_put_uint_schar(xp, tp, fillp);
14263 		if (status == NC_NOERR) /* report the first encountered error */
14264 			status = lstatus;
14265 	}
14266 
14267 	*xpp = (void *)xp;
14268 	return status;
14269 #endif
14270 }
14271 
14272 int
ncx_putn_uint_short(void ** xpp,size_t nelems,const short * tp,void * fillp)14273 ncx_putn_uint_short(void **xpp, size_t nelems, const short *tp, void *fillp)
14274 {
14275 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14276 
14277  /* basic algorithm is:
14278   *   - ensure sane alignment of output data
14279   *   - copy (conversion happens automatically) input data
14280   *     to output
14281   *   - update tp to point at next unconverted input, and xpp to point
14282   *     at next location for converted output
14283   */
14284   long i, j, ni;
14285   uint tmp[LOOPCNT];        /* in case input is misaligned */
14286   uint *xp;
14287   int nrange = 0;         /* number of range errors */
14288   int realign = 0;        /* "do we need to fix input data alignment?" */
14289   long cxp = (long) *((char**)xpp);
14290 
14291   realign = (cxp & 7) % SIZEOF_UINT;
14292   /* sjl: manually stripmine so we can limit amount of
14293    * vector work space reserved to LOOPCNT elements. Also
14294    * makes vectorisation easy */
14295   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14296     ni=Min(nelems-j,LOOPCNT);
14297     if (realign) {
14298       xp = tmp;
14299     } else {
14300       xp = (uint *) *xpp;
14301     }
14302    /* copy the next block */
14303 #pragma cdir loopcnt=LOOPCNT
14304 #pragma cdir shortloop
14305     for (i=0; i<ni; i++) {
14306       /* the normal case: */
14307       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14308      /* test for range errors (not always needed but do it anyway) */
14309      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14310      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14311       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14312     }
14313    /* copy workspace back if necessary */
14314     if (realign) {
14315       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14316       xp = (uint *) *xpp;
14317     }
14318    /* update xpp and tp */
14319     xp += ni;
14320     tp += ni;
14321     *xpp = (void*)xp;
14322   }
14323   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14324 
14325 #else   /* not SX */
14326 
14327 	char *xp = (char *) *xpp;
14328 	int status = NC_NOERR;
14329 
14330 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14331 	{
14332 		int lstatus = ncx_put_uint_short(xp, tp, fillp);
14333 		if (status == NC_NOERR) /* report the first encountered error */
14334 			status = lstatus;
14335 	}
14336 
14337 	*xpp = (void *)xp;
14338 	return status;
14339 #endif
14340 }
14341 
14342 int
ncx_putn_uint_int(void ** xpp,size_t nelems,const int * tp,void * fillp)14343 ncx_putn_uint_int(void **xpp, size_t nelems, const int *tp, void *fillp)
14344 {
14345 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14346 
14347  /* basic algorithm is:
14348   *   - ensure sane alignment of output data
14349   *   - copy (conversion happens automatically) input data
14350   *     to output
14351   *   - update tp to point at next unconverted input, and xpp to point
14352   *     at next location for converted output
14353   */
14354   long i, j, ni;
14355   uint tmp[LOOPCNT];        /* in case input is misaligned */
14356   uint *xp;
14357   int nrange = 0;         /* number of range errors */
14358   int realign = 0;        /* "do we need to fix input data alignment?" */
14359   long cxp = (long) *((char**)xpp);
14360 
14361   realign = (cxp & 7) % SIZEOF_UINT;
14362   /* sjl: manually stripmine so we can limit amount of
14363    * vector work space reserved to LOOPCNT elements. Also
14364    * makes vectorisation easy */
14365   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14366     ni=Min(nelems-j,LOOPCNT);
14367     if (realign) {
14368       xp = tmp;
14369     } else {
14370       xp = (uint *) *xpp;
14371     }
14372    /* copy the next block */
14373 #pragma cdir loopcnt=LOOPCNT
14374 #pragma cdir shortloop
14375     for (i=0; i<ni; i++) {
14376       /* the normal case: */
14377       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14378      /* test for range errors (not always needed but do it anyway) */
14379      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14380      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14381       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14382     }
14383    /* copy workspace back if necessary */
14384     if (realign) {
14385       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14386       xp = (uint *) *xpp;
14387     }
14388    /* update xpp and tp */
14389     xp += ni;
14390     tp += ni;
14391     *xpp = (void*)xp;
14392   }
14393   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14394 
14395 #else   /* not SX */
14396 
14397 	char *xp = (char *) *xpp;
14398 	int status = NC_NOERR;
14399 
14400 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14401 	{
14402 		int lstatus = ncx_put_uint_int(xp, tp, fillp);
14403 		if (status == NC_NOERR) /* report the first encountered error */
14404 			status = lstatus;
14405 	}
14406 
14407 	*xpp = (void *)xp;
14408 	return status;
14409 #endif
14410 }
14411 
14412 int
ncx_putn_uint_long(void ** xpp,size_t nelems,const long * tp,void * fillp)14413 ncx_putn_uint_long(void **xpp, size_t nelems, const long *tp, void *fillp)
14414 {
14415 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14416 
14417  /* basic algorithm is:
14418   *   - ensure sane alignment of output data
14419   *   - copy (conversion happens automatically) input data
14420   *     to output
14421   *   - update tp to point at next unconverted input, and xpp to point
14422   *     at next location for converted output
14423   */
14424   long i, j, ni;
14425   uint tmp[LOOPCNT];        /* in case input is misaligned */
14426   uint *xp;
14427   int nrange = 0;         /* number of range errors */
14428   int realign = 0;        /* "do we need to fix input data alignment?" */
14429   long cxp = (long) *((char**)xpp);
14430 
14431   realign = (cxp & 7) % SIZEOF_UINT;
14432   /* sjl: manually stripmine so we can limit amount of
14433    * vector work space reserved to LOOPCNT elements. Also
14434    * makes vectorisation easy */
14435   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14436     ni=Min(nelems-j,LOOPCNT);
14437     if (realign) {
14438       xp = tmp;
14439     } else {
14440       xp = (uint *) *xpp;
14441     }
14442    /* copy the next block */
14443 #pragma cdir loopcnt=LOOPCNT
14444 #pragma cdir shortloop
14445     for (i=0; i<ni; i++) {
14446       /* the normal case: */
14447       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14448      /* test for range errors (not always needed but do it anyway) */
14449      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14450      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14451       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14452     }
14453    /* copy workspace back if necessary */
14454     if (realign) {
14455       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14456       xp = (uint *) *xpp;
14457     }
14458    /* update xpp and tp */
14459     xp += ni;
14460     tp += ni;
14461     *xpp = (void*)xp;
14462   }
14463   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14464 
14465 #else   /* not SX */
14466 
14467 	char *xp = (char *) *xpp;
14468 	int status = NC_NOERR;
14469 
14470 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14471 	{
14472 		int lstatus = ncx_put_uint_long(xp, tp, fillp);
14473 		if (status == NC_NOERR) /* report the first encountered error */
14474 			status = lstatus;
14475 	}
14476 
14477 	*xpp = (void *)xp;
14478 	return status;
14479 #endif
14480 }
14481 
14482 int
ncx_putn_uint_float(void ** xpp,size_t nelems,const float * tp,void * fillp)14483 ncx_putn_uint_float(void **xpp, size_t nelems, const float *tp, void *fillp)
14484 {
14485 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14486 
14487  /* basic algorithm is:
14488   *   - ensure sane alignment of output data
14489   *   - copy (conversion happens automatically) input data
14490   *     to output
14491   *   - update tp to point at next unconverted input, and xpp to point
14492   *     at next location for converted output
14493   */
14494   long i, j, ni;
14495   uint tmp[LOOPCNT];        /* in case input is misaligned */
14496   uint *xp;
14497   int nrange = 0;         /* number of range errors */
14498   int realign = 0;        /* "do we need to fix input data alignment?" */
14499   long cxp = (long) *((char**)xpp);
14500 
14501   realign = (cxp & 7) % SIZEOF_UINT;
14502   /* sjl: manually stripmine so we can limit amount of
14503    * vector work space reserved to LOOPCNT elements. Also
14504    * makes vectorisation easy */
14505   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14506     ni=Min(nelems-j,LOOPCNT);
14507     if (realign) {
14508       xp = tmp;
14509     } else {
14510       xp = (uint *) *xpp;
14511     }
14512    /* copy the next block */
14513 #pragma cdir loopcnt=LOOPCNT
14514 #pragma cdir shortloop
14515     for (i=0; i<ni; i++) {
14516       /* the normal case: */
14517       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14518      /* test for range errors (not always needed but do it anyway) */
14519      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14520      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14521       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14522     }
14523    /* copy workspace back if necessary */
14524     if (realign) {
14525       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14526       xp = (uint *) *xpp;
14527     }
14528    /* update xpp and tp */
14529     xp += ni;
14530     tp += ni;
14531     *xpp = (void*)xp;
14532   }
14533   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14534 
14535 #else   /* not SX */
14536 
14537 	char *xp = (char *) *xpp;
14538 	int status = NC_NOERR;
14539 
14540 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14541 	{
14542 		int lstatus = ncx_put_uint_float(xp, tp, fillp);
14543 		if (status == NC_NOERR) /* report the first encountered error */
14544 			status = lstatus;
14545 	}
14546 
14547 	*xpp = (void *)xp;
14548 	return status;
14549 #endif
14550 }
14551 
14552 int
ncx_putn_uint_double(void ** xpp,size_t nelems,const double * tp,void * fillp)14553 ncx_putn_uint_double(void **xpp, size_t nelems, const double *tp, void *fillp)
14554 {
14555 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14556 
14557  /* basic algorithm is:
14558   *   - ensure sane alignment of output data
14559   *   - copy (conversion happens automatically) input data
14560   *     to output
14561   *   - update tp to point at next unconverted input, and xpp to point
14562   *     at next location for converted output
14563   */
14564   long i, j, ni;
14565   uint tmp[LOOPCNT];        /* in case input is misaligned */
14566   uint *xp;
14567   int nrange = 0;         /* number of range errors */
14568   int realign = 0;        /* "do we need to fix input data alignment?" */
14569   long cxp = (long) *((char**)xpp);
14570 
14571   realign = (cxp & 7) % SIZEOF_UINT;
14572   /* sjl: manually stripmine so we can limit amount of
14573    * vector work space reserved to LOOPCNT elements. Also
14574    * makes vectorisation easy */
14575   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14576     ni=Min(nelems-j,LOOPCNT);
14577     if (realign) {
14578       xp = tmp;
14579     } else {
14580       xp = (uint *) *xpp;
14581     }
14582    /* copy the next block */
14583 #pragma cdir loopcnt=LOOPCNT
14584 #pragma cdir shortloop
14585     for (i=0; i<ni; i++) {
14586       /* the normal case: */
14587       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14588      /* test for range errors (not always needed but do it anyway) */
14589      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14590      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14591       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14592     }
14593    /* copy workspace back if necessary */
14594     if (realign) {
14595       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14596       xp = (uint *) *xpp;
14597     }
14598    /* update xpp and tp */
14599     xp += ni;
14600     tp += ni;
14601     *xpp = (void*)xp;
14602   }
14603   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14604 
14605 #else   /* not SX */
14606 
14607 	char *xp = (char *) *xpp;
14608 	int status = NC_NOERR;
14609 
14610 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14611 	{
14612 		int lstatus = ncx_put_uint_double(xp, tp, fillp);
14613 		if (status == NC_NOERR) /* report the first encountered error */
14614 			status = lstatus;
14615 	}
14616 
14617 	*xpp = (void *)xp;
14618 	return status;
14619 #endif
14620 }
14621 
14622 int
ncx_putn_uint_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)14623 ncx_putn_uint_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
14624 {
14625 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14626 
14627  /* basic algorithm is:
14628   *   - ensure sane alignment of output data
14629   *   - copy (conversion happens automatically) input data
14630   *     to output
14631   *   - update tp to point at next unconverted input, and xpp to point
14632   *     at next location for converted output
14633   */
14634   long i, j, ni;
14635   uint tmp[LOOPCNT];        /* in case input is misaligned */
14636   uint *xp;
14637   int nrange = 0;         /* number of range errors */
14638   int realign = 0;        /* "do we need to fix input data alignment?" */
14639   long cxp = (long) *((char**)xpp);
14640 
14641   realign = (cxp & 7) % SIZEOF_UINT;
14642   /* sjl: manually stripmine so we can limit amount of
14643    * vector work space reserved to LOOPCNT elements. Also
14644    * makes vectorisation easy */
14645   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14646     ni=Min(nelems-j,LOOPCNT);
14647     if (realign) {
14648       xp = tmp;
14649     } else {
14650       xp = (uint *) *xpp;
14651     }
14652    /* copy the next block */
14653 #pragma cdir loopcnt=LOOPCNT
14654 #pragma cdir shortloop
14655     for (i=0; i<ni; i++) {
14656       /* the normal case: */
14657       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14658      /* test for range errors (not always needed but do it anyway) */
14659      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14660      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14661       nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
14662     }
14663    /* copy workspace back if necessary */
14664     if (realign) {
14665       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14666       xp = (uint *) *xpp;
14667     }
14668    /* update xpp and tp */
14669     xp += ni;
14670     tp += ni;
14671     *xpp = (void*)xp;
14672   }
14673   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14674 
14675 #else   /* not SX */
14676 
14677 	char *xp = (char *) *xpp;
14678 	int status = NC_NOERR;
14679 
14680 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14681 	{
14682 		int lstatus = ncx_put_uint_longlong(xp, tp, fillp);
14683 		if (status == NC_NOERR) /* report the first encountered error */
14684 			status = lstatus;
14685 	}
14686 
14687 	*xpp = (void *)xp;
14688 	return status;
14689 #endif
14690 }
14691 
14692 int
ncx_putn_uint_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)14693 ncx_putn_uint_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
14694 {
14695 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14696 
14697  /* basic algorithm is:
14698   *   - ensure sane alignment of output data
14699   *   - copy (conversion happens automatically) input data
14700   *     to output
14701   *   - update tp to point at next unconverted input, and xpp to point
14702   *     at next location for converted output
14703   */
14704   long i, j, ni;
14705   uint tmp[LOOPCNT];        /* in case input is misaligned */
14706   uint *xp;
14707   int nrange = 0;         /* number of range errors */
14708   int realign = 0;        /* "do we need to fix input data alignment?" */
14709   long cxp = (long) *((char**)xpp);
14710 
14711   realign = (cxp & 7) % SIZEOF_UINT;
14712   /* sjl: manually stripmine so we can limit amount of
14713    * vector work space reserved to LOOPCNT elements. Also
14714    * makes vectorisation easy */
14715   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14716     ni=Min(nelems-j,LOOPCNT);
14717     if (realign) {
14718       xp = tmp;
14719     } else {
14720       xp = (uint *) *xpp;
14721     }
14722    /* copy the next block */
14723 #pragma cdir loopcnt=LOOPCNT
14724 #pragma cdir shortloop
14725     for (i=0; i<ni; i++) {
14726       /* the normal case: */
14727       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14728      /* test for range errors (not always needed but do it anyway) */
14729      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14730      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14731       nrange += tp[i] > X_UINT_MAX ;
14732     }
14733    /* copy workspace back if necessary */
14734     if (realign) {
14735       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14736       xp = (uint *) *xpp;
14737     }
14738    /* update xpp and tp */
14739     xp += ni;
14740     tp += ni;
14741     *xpp = (void*)xp;
14742   }
14743   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14744 
14745 #else   /* not SX */
14746 
14747 	char *xp = (char *) *xpp;
14748 	int status = NC_NOERR;
14749 
14750 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14751 	{
14752 		int lstatus = ncx_put_uint_uchar(xp, tp, fillp);
14753 		if (status == NC_NOERR) /* report the first encountered error */
14754 			status = lstatus;
14755 	}
14756 
14757 	*xpp = (void *)xp;
14758 	return status;
14759 #endif
14760 }
14761 
14762 int
ncx_putn_uint_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)14763 ncx_putn_uint_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
14764 {
14765 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14766 
14767  /* basic algorithm is:
14768   *   - ensure sane alignment of output data
14769   *   - copy (conversion happens automatically) input data
14770   *     to output
14771   *   - update tp to point at next unconverted input, and xpp to point
14772   *     at next location for converted output
14773   */
14774   long i, j, ni;
14775   uint tmp[LOOPCNT];        /* in case input is misaligned */
14776   uint *xp;
14777   int nrange = 0;         /* number of range errors */
14778   int realign = 0;        /* "do we need to fix input data alignment?" */
14779   long cxp = (long) *((char**)xpp);
14780 
14781   realign = (cxp & 7) % SIZEOF_UINT;
14782   /* sjl: manually stripmine so we can limit amount of
14783    * vector work space reserved to LOOPCNT elements. Also
14784    * makes vectorisation easy */
14785   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14786     ni=Min(nelems-j,LOOPCNT);
14787     if (realign) {
14788       xp = tmp;
14789     } else {
14790       xp = (uint *) *xpp;
14791     }
14792    /* copy the next block */
14793 #pragma cdir loopcnt=LOOPCNT
14794 #pragma cdir shortloop
14795     for (i=0; i<ni; i++) {
14796       /* the normal case: */
14797       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14798      /* test for range errors (not always needed but do it anyway) */
14799      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14800      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14801       nrange += tp[i] > X_UINT_MAX ;
14802     }
14803    /* copy workspace back if necessary */
14804     if (realign) {
14805       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14806       xp = (uint *) *xpp;
14807     }
14808    /* update xpp and tp */
14809     xp += ni;
14810     tp += ni;
14811     *xpp = (void*)xp;
14812   }
14813   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14814 
14815 #else   /* not SX */
14816 
14817 	char *xp = (char *) *xpp;
14818 	int status = NC_NOERR;
14819 
14820 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14821 	{
14822 		int lstatus = ncx_put_uint_ushort(xp, tp, fillp);
14823 		if (status == NC_NOERR) /* report the first encountered error */
14824 			status = lstatus;
14825 	}
14826 
14827 	*xpp = (void *)xp;
14828 	return status;
14829 #endif
14830 }
14831 
14832 int
ncx_putn_uint_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)14833 ncx_putn_uint_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
14834 {
14835 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT
14836 
14837  /* basic algorithm is:
14838   *   - ensure sane alignment of output data
14839   *   - copy (conversion happens automatically) input data
14840   *     to output
14841   *   - update tp to point at next unconverted input, and xpp to point
14842   *     at next location for converted output
14843   */
14844   long i, j, ni;
14845   uint tmp[LOOPCNT];        /* in case input is misaligned */
14846   uint *xp;
14847   int nrange = 0;         /* number of range errors */
14848   int realign = 0;        /* "do we need to fix input data alignment?" */
14849   long cxp = (long) *((char**)xpp);
14850 
14851   realign = (cxp & 7) % SIZEOF_UINT;
14852   /* sjl: manually stripmine so we can limit amount of
14853    * vector work space reserved to LOOPCNT elements. Also
14854    * makes vectorisation easy */
14855   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
14856     ni=Min(nelems-j,LOOPCNT);
14857     if (realign) {
14858       xp = tmp;
14859     } else {
14860       xp = (uint *) *xpp;
14861     }
14862    /* copy the next block */
14863 #pragma cdir loopcnt=LOOPCNT
14864 #pragma cdir shortloop
14865     for (i=0; i<ni; i++) {
14866       /* the normal case: */
14867       xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
14868      /* test for range errors (not always needed but do it anyway) */
14869      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
14870      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
14871       nrange += tp[i] > X_UINT_MAX ;
14872     }
14873    /* copy workspace back if necessary */
14874     if (realign) {
14875       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
14876       xp = (uint *) *xpp;
14877     }
14878    /* update xpp and tp */
14879     xp += ni;
14880     tp += ni;
14881     *xpp = (void*)xp;
14882   }
14883   return nrange == 0 ? NC_NOERR : NC_ERANGE;
14884 
14885 #else   /* not SX */
14886 
14887 	char *xp = (char *) *xpp;
14888 	int status = NC_NOERR;
14889 
14890 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
14891 	{
14892 		int lstatus = ncx_put_uint_ulonglong(xp, tp, fillp);
14893 		if (status == NC_NOERR) /* report the first encountered error */
14894 			status = lstatus;
14895 	}
14896 
14897 	*xpp = (void *)xp;
14898 	return status;
14899 #endif
14900 }
14901 
14902 
14903 
14904 /* float ---------------------------------------------------------------------*/
14905 
14906 #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
14907 /* optimized version */
14908 int
ncx_getn_float_float(const void ** xpp,size_t nelems,float * tp)14909 ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14910 {
14911 #ifdef WORDS_BIGENDIAN
14912 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
14913 # else
14914 	swapn4b(tp, *xpp, nelems);
14915 # endif
14916 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
14917 	return NC_NOERR;
14918 }
14919 #elif defined(vax) && vax != 0
14920 int
ncx_getn_float_float(const void ** xpp,size_t nfloats,float * ip)14921 ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
14922 {
14923 	float *const end = ip + nfloats;
14924 
14925 	while (ip < end)
14926 	{
14927 		struct vax_single *const vsp = (struct vax_single *) ip;
14928 		const struct ieee_single *const isp =
14929 			 (const struct ieee_single *) (*xpp);
14930 		unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
14931 
14932 		switch(exp) {
14933 		case 0 :
14934 			/* ieee subnormal */
14935 			if (isp->mant_hi == min.ieee.mant_hi
14936 				&& isp->mant_lo_hi == min.ieee.mant_lo_hi
14937 				&& isp->mant_lo_lo == min.ieee.mant_lo_lo)
14938 			{
14939 				*vsp = min.s;
14940 			}
14941 			else
14942 			{
14943 				unsigned mantissa = (isp->mant_hi << 16)
14944 					 | isp->mant_lo_hi << 8
14945 					 | isp->mant_lo_lo;
14946 				unsigned tmp = mantissa >> 20;
14947 				if (tmp >= 4) {
14948 					vsp->exp = 2;
14949 				} else if (tmp >= 2) {
14950 					vsp->exp = 1;
14951 				} else {
14952 					*vsp = min.s;
14953 					break;
14954 				} /* else */
14955 				tmp = mantissa - (1 << (20 + vsp->exp ));
14956 				tmp <<= 3 - vsp->exp;
14957 				vsp->mantissa2 = tmp;
14958 				vsp->mantissa1 = (tmp >> 16);
14959 			}
14960 			break;
14961 		case 0xfe :
14962 		case 0xff :
14963 			*vsp = max.s;
14964 			break;
14965 		default :
14966 			vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
14967 			vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
14968 			vsp->mantissa1 = isp->mant_hi;
14969 		}
14970 
14971 		vsp->sign = isp->sign;
14972 
14973 
14974 		ip++;
14975 		*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
14976 	}
14977 	return NC_NOERR;
14978 }
14979 #else
14980 int
ncx_getn_float_float(const void ** xpp,size_t nelems,float * tp)14981 ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
14982 {
14983 	const char *xp = *xpp;
14984 	int status = NC_NOERR;
14985 
14986 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
14987 	{
14988 		const int lstatus = ncx_get_float_float(xp, tp, fillp);
14989 		if (status == NC_NOERR) /* report the first encountered error */
14990 			status = lstatus;
14991 	}
14992 
14993 	*xpp = (const void *)xp;
14994 	return status;
14995 }
14996 
14997 #endif
14998 int
ncx_getn_float_schar(const void ** xpp,size_t nelems,schar * tp)14999 ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
15000 {
15001 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15002 
15003  /* basic algorithm is:
15004   *   - ensure sane alignment of input data
15005   *   - copy (conversion happens automatically) input data
15006   *     to output
15007   *   - update xpp to point at next unconverted input, and tp to point
15008   *     at next location for converted output
15009   */
15010   long i, j, ni;
15011   float tmp[LOOPCNT];        /* in case input is misaligned */
15012   float *xp;
15013   int nrange = 0;         /* number of range errors */
15014   int realign = 0;        /* "do we need to fix input data alignment?" */
15015   long cxp = (long) *((char**)xpp);
15016 
15017   realign = (cxp & 7) % SIZEOF_FLOAT;
15018   /* sjl: manually stripmine so we can limit amount of
15019    * vector work space reserved to LOOPCNT elements. Also
15020    * makes vectorisation easy */
15021   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15022     ni=Min(nelems-j,LOOPCNT);
15023     if (realign) {
15024       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15025       xp = tmp;
15026     } else {
15027       xp = (float *) *xpp;
15028     }
15029    /* copy the next block */
15030 #pragma cdir loopcnt=LOOPCNT
15031 #pragma cdir shortloop
15032     for (i=0; i<ni; i++) {
15033       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
15034      /* test for range errors (not always needed but do it anyway) */
15035      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15036      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15037       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
15038     }
15039    /* update xpp and tp */
15040     if (realign) xp = (float *) *xpp;
15041     xp += ni;
15042     tp += ni;
15043     *xpp = (void*)xp;
15044   }
15045   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15046 
15047 #else   /* not SX */
15048 	const char *xp = (const char *) *xpp;
15049 	int status = NC_NOERR;
15050 
15051 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15052 	{
15053 		const int lstatus = ncx_get_float_schar(xp, tp);
15054 		if (status == NC_NOERR) /* report the first encountered error */
15055 			status = lstatus;
15056 	}
15057 
15058 	*xpp = (const void *)xp;
15059 	return status;
15060 #endif
15061 }
15062 
15063 int
ncx_getn_float_short(const void ** xpp,size_t nelems,short * tp)15064 ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
15065 {
15066 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15067 
15068  /* basic algorithm is:
15069   *   - ensure sane alignment of input data
15070   *   - copy (conversion happens automatically) input data
15071   *     to output
15072   *   - update xpp to point at next unconverted input, and tp to point
15073   *     at next location for converted output
15074   */
15075   long i, j, ni;
15076   float tmp[LOOPCNT];        /* in case input is misaligned */
15077   float *xp;
15078   int nrange = 0;         /* number of range errors */
15079   int realign = 0;        /* "do we need to fix input data alignment?" */
15080   long cxp = (long) *((char**)xpp);
15081 
15082   realign = (cxp & 7) % SIZEOF_FLOAT;
15083   /* sjl: manually stripmine so we can limit amount of
15084    * vector work space reserved to LOOPCNT elements. Also
15085    * makes vectorisation easy */
15086   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15087     ni=Min(nelems-j,LOOPCNT);
15088     if (realign) {
15089       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15090       xp = tmp;
15091     } else {
15092       xp = (float *) *xpp;
15093     }
15094    /* copy the next block */
15095 #pragma cdir loopcnt=LOOPCNT
15096 #pragma cdir shortloop
15097     for (i=0; i<ni; i++) {
15098       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
15099      /* test for range errors (not always needed but do it anyway) */
15100      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15101      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15102       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
15103     }
15104    /* update xpp and tp */
15105     if (realign) xp = (float *) *xpp;
15106     xp += ni;
15107     tp += ni;
15108     *xpp = (void*)xp;
15109   }
15110   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15111 
15112 #else   /* not SX */
15113 	const char *xp = (const char *) *xpp;
15114 	int status = NC_NOERR;
15115 
15116 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15117 	{
15118 		const int lstatus = ncx_get_float_short(xp, tp);
15119 		if (status == NC_NOERR) /* report the first encountered error */
15120 			status = lstatus;
15121 	}
15122 
15123 	*xpp = (const void *)xp;
15124 	return status;
15125 #endif
15126 }
15127 
15128 int
ncx_getn_float_int(const void ** xpp,size_t nelems,int * tp)15129 ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
15130 {
15131 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15132 
15133  /* basic algorithm is:
15134   *   - ensure sane alignment of input data
15135   *   - copy (conversion happens automatically) input data
15136   *     to output
15137   *   - update xpp to point at next unconverted input, and tp to point
15138   *     at next location for converted output
15139   */
15140   long i, j, ni;
15141   float tmp[LOOPCNT];        /* in case input is misaligned */
15142   float *xp;
15143   int nrange = 0;         /* number of range errors */
15144   int realign = 0;        /* "do we need to fix input data alignment?" */
15145   long cxp = (long) *((char**)xpp);
15146 
15147   realign = (cxp & 7) % SIZEOF_FLOAT;
15148   /* sjl: manually stripmine so we can limit amount of
15149    * vector work space reserved to LOOPCNT elements. Also
15150    * makes vectorisation easy */
15151   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15152     ni=Min(nelems-j,LOOPCNT);
15153     if (realign) {
15154       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15155       xp = tmp;
15156     } else {
15157       xp = (float *) *xpp;
15158     }
15159    /* copy the next block */
15160 #pragma cdir loopcnt=LOOPCNT
15161 #pragma cdir shortloop
15162     for (i=0; i<ni; i++) {
15163       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
15164      /* test for range errors (not always needed but do it anyway) */
15165      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15166      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15167       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
15168     }
15169    /* update xpp and tp */
15170     if (realign) xp = (float *) *xpp;
15171     xp += ni;
15172     tp += ni;
15173     *xpp = (void*)xp;
15174   }
15175   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15176 
15177 #else   /* not SX */
15178 	const char *xp = (const char *) *xpp;
15179 	int status = NC_NOERR;
15180 
15181 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15182 	{
15183 		const int lstatus = ncx_get_float_int(xp, tp);
15184 		if (status == NC_NOERR) /* report the first encountered error */
15185 			status = lstatus;
15186 	}
15187 
15188 	*xpp = (const void *)xp;
15189 	return status;
15190 #endif
15191 }
15192 
15193 int
ncx_getn_float_long(const void ** xpp,size_t nelems,long * tp)15194 ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
15195 {
15196 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15197 
15198  /* basic algorithm is:
15199   *   - ensure sane alignment of input data
15200   *   - copy (conversion happens automatically) input data
15201   *     to output
15202   *   - update xpp to point at next unconverted input, and tp to point
15203   *     at next location for converted output
15204   */
15205   long i, j, ni;
15206   float tmp[LOOPCNT];        /* in case input is misaligned */
15207   float *xp;
15208   int nrange = 0;         /* number of range errors */
15209   int realign = 0;        /* "do we need to fix input data alignment?" */
15210   long cxp = (long) *((char**)xpp);
15211 
15212   realign = (cxp & 7) % SIZEOF_FLOAT;
15213   /* sjl: manually stripmine so we can limit amount of
15214    * vector work space reserved to LOOPCNT elements. Also
15215    * makes vectorisation easy */
15216   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15217     ni=Min(nelems-j,LOOPCNT);
15218     if (realign) {
15219       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15220       xp = tmp;
15221     } else {
15222       xp = (float *) *xpp;
15223     }
15224    /* copy the next block */
15225 #pragma cdir loopcnt=LOOPCNT
15226 #pragma cdir shortloop
15227     for (i=0; i<ni; i++) {
15228       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
15229      /* test for range errors (not always needed but do it anyway) */
15230      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15231      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15232       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
15233     }
15234    /* update xpp and tp */
15235     if (realign) xp = (float *) *xpp;
15236     xp += ni;
15237     tp += ni;
15238     *xpp = (void*)xp;
15239   }
15240   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15241 
15242 #else   /* not SX */
15243 	const char *xp = (const char *) *xpp;
15244 	int status = NC_NOERR;
15245 
15246 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15247 	{
15248 		const int lstatus = ncx_get_float_long(xp, tp);
15249 		if (status == NC_NOERR) /* report the first encountered error */
15250 			status = lstatus;
15251 	}
15252 
15253 	*xpp = (const void *)xp;
15254 	return status;
15255 #endif
15256 }
15257 
15258 int
ncx_getn_float_double(const void ** xpp,size_t nelems,double * tp)15259 ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
15260 {
15261 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15262 
15263  /* basic algorithm is:
15264   *   - ensure sane alignment of input data
15265   *   - copy (conversion happens automatically) input data
15266   *     to output
15267   *   - update xpp to point at next unconverted input, and tp to point
15268   *     at next location for converted output
15269   */
15270   long i, j, ni;
15271   float tmp[LOOPCNT];        /* in case input is misaligned */
15272   float *xp;
15273   int nrange = 0;         /* number of range errors */
15274   int realign = 0;        /* "do we need to fix input data alignment?" */
15275   long cxp = (long) *((char**)xpp);
15276 
15277   realign = (cxp & 7) % SIZEOF_FLOAT;
15278   /* sjl: manually stripmine so we can limit amount of
15279    * vector work space reserved to LOOPCNT elements. Also
15280    * makes vectorisation easy */
15281   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15282     ni=Min(nelems-j,LOOPCNT);
15283     if (realign) {
15284       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15285       xp = tmp;
15286     } else {
15287       xp = (float *) *xpp;
15288     }
15289    /* copy the next block */
15290 #pragma cdir loopcnt=LOOPCNT
15291 #pragma cdir shortloop
15292     for (i=0; i<ni; i++) {
15293       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
15294      /* test for range errors (not always needed but do it anyway) */
15295      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15296      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15297       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
15298     }
15299    /* update xpp and tp */
15300     if (realign) xp = (float *) *xpp;
15301     xp += ni;
15302     tp += ni;
15303     *xpp = (void*)xp;
15304   }
15305   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15306 
15307 #else   /* not SX */
15308 	const char *xp = (const char *) *xpp;
15309 	int status = NC_NOERR;
15310 
15311 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15312 	{
15313 		const int lstatus = ncx_get_float_double(xp, tp);
15314 		if (status == NC_NOERR) /* report the first encountered error */
15315 			status = lstatus;
15316 	}
15317 
15318 	*xpp = (const void *)xp;
15319 	return status;
15320 #endif
15321 }
15322 
15323 int
ncx_getn_float_longlong(const void ** xpp,size_t nelems,longlong * tp)15324 ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp)
15325 {
15326 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15327 
15328  /* basic algorithm is:
15329   *   - ensure sane alignment of input data
15330   *   - copy (conversion happens automatically) input data
15331   *     to output
15332   *   - update xpp to point at next unconverted input, and tp to point
15333   *     at next location for converted output
15334   */
15335   long i, j, ni;
15336   float tmp[LOOPCNT];        /* in case input is misaligned */
15337   float *xp;
15338   int nrange = 0;         /* number of range errors */
15339   int realign = 0;        /* "do we need to fix input data alignment?" */
15340   long cxp = (long) *((char**)xpp);
15341 
15342   realign = (cxp & 7) % SIZEOF_FLOAT;
15343   /* sjl: manually stripmine so we can limit amount of
15344    * vector work space reserved to LOOPCNT elements. Also
15345    * makes vectorisation easy */
15346   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15347     ni=Min(nelems-j,LOOPCNT);
15348     if (realign) {
15349       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15350       xp = tmp;
15351     } else {
15352       xp = (float *) *xpp;
15353     }
15354    /* copy the next block */
15355 #pragma cdir loopcnt=LOOPCNT
15356 #pragma cdir shortloop
15357     for (i=0; i<ni; i++) {
15358       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
15359      /* test for range errors (not always needed but do it anyway) */
15360      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15361      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15362       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
15363     }
15364    /* update xpp and tp */
15365     if (realign) xp = (float *) *xpp;
15366     xp += ni;
15367     tp += ni;
15368     *xpp = (void*)xp;
15369   }
15370   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15371 
15372 #else   /* not SX */
15373 	const char *xp = (const char *) *xpp;
15374 	int status = NC_NOERR;
15375 
15376 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15377 	{
15378 		const int lstatus = ncx_get_float_longlong(xp, tp);
15379 		if (status == NC_NOERR) /* report the first encountered error */
15380 			status = lstatus;
15381 	}
15382 
15383 	*xpp = (const void *)xp;
15384 	return status;
15385 #endif
15386 }
15387 
15388 int
ncx_getn_float_ushort(const void ** xpp,size_t nelems,ushort * tp)15389 ncx_getn_float_ushort(const void **xpp, size_t nelems, ushort *tp)
15390 {
15391 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15392 
15393  /* basic algorithm is:
15394   *   - ensure sane alignment of input data
15395   *   - copy (conversion happens automatically) input data
15396   *     to output
15397   *   - update xpp to point at next unconverted input, and tp to point
15398   *     at next location for converted output
15399   */
15400   long i, j, ni;
15401   float tmp[LOOPCNT];        /* in case input is misaligned */
15402   float *xp;
15403   int nrange = 0;         /* number of range errors */
15404   int realign = 0;        /* "do we need to fix input data alignment?" */
15405   long cxp = (long) *((char**)xpp);
15406 
15407   realign = (cxp & 7) % SIZEOF_FLOAT;
15408   /* sjl: manually stripmine so we can limit amount of
15409    * vector work space reserved to LOOPCNT elements. Also
15410    * makes vectorisation easy */
15411   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15412     ni=Min(nelems-j,LOOPCNT);
15413     if (realign) {
15414       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15415       xp = tmp;
15416     } else {
15417       xp = (float *) *xpp;
15418     }
15419    /* copy the next block */
15420 #pragma cdir loopcnt=LOOPCNT
15421 #pragma cdir shortloop
15422     for (i=0; i<ni; i++) {
15423       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
15424      /* test for range errors (not always needed but do it anyway) */
15425      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15426      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15427       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
15428     }
15429    /* update xpp and tp */
15430     if (realign) xp = (float *) *xpp;
15431     xp += ni;
15432     tp += ni;
15433     *xpp = (void*)xp;
15434   }
15435   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15436 
15437 #else   /* not SX */
15438 	const char *xp = (const char *) *xpp;
15439 	int status = NC_NOERR;
15440 
15441 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15442 	{
15443 		const int lstatus = ncx_get_float_ushort(xp, tp);
15444 		if (status == NC_NOERR) /* report the first encountered error */
15445 			status = lstatus;
15446 	}
15447 
15448 	*xpp = (const void *)xp;
15449 	return status;
15450 #endif
15451 }
15452 
15453 int
ncx_getn_float_uchar(const void ** xpp,size_t nelems,uchar * tp)15454 ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
15455 {
15456 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15457 
15458  /* basic algorithm is:
15459   *   - ensure sane alignment of input data
15460   *   - copy (conversion happens automatically) input data
15461   *     to output
15462   *   - update xpp to point at next unconverted input, and tp to point
15463   *     at next location for converted output
15464   */
15465   long i, j, ni;
15466   float tmp[LOOPCNT];        /* in case input is misaligned */
15467   float *xp;
15468   int nrange = 0;         /* number of range errors */
15469   int realign = 0;        /* "do we need to fix input data alignment?" */
15470   long cxp = (long) *((char**)xpp);
15471 
15472   realign = (cxp & 7) % SIZEOF_FLOAT;
15473   /* sjl: manually stripmine so we can limit amount of
15474    * vector work space reserved to LOOPCNT elements. Also
15475    * makes vectorisation easy */
15476   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15477     ni=Min(nelems-j,LOOPCNT);
15478     if (realign) {
15479       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15480       xp = tmp;
15481     } else {
15482       xp = (float *) *xpp;
15483     }
15484    /* copy the next block */
15485 #pragma cdir loopcnt=LOOPCNT
15486 #pragma cdir shortloop
15487     for (i=0; i<ni; i++) {
15488       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
15489      /* test for range errors (not always needed but do it anyway) */
15490      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15491      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15492       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
15493     }
15494    /* update xpp and tp */
15495     if (realign) xp = (float *) *xpp;
15496     xp += ni;
15497     tp += ni;
15498     *xpp = (void*)xp;
15499   }
15500   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15501 
15502 #else   /* not SX */
15503 	const char *xp = (const char *) *xpp;
15504 	int status = NC_NOERR;
15505 
15506 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15507 	{
15508 		const int lstatus = ncx_get_float_uchar(xp, tp);
15509 		if (status == NC_NOERR) /* report the first encountered error */
15510 			status = lstatus;
15511 	}
15512 
15513 	*xpp = (const void *)xp;
15514 	return status;
15515 #endif
15516 }
15517 
15518 int
ncx_getn_float_uint(const void ** xpp,size_t nelems,uint * tp)15519 ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp)
15520 {
15521 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15522 
15523  /* basic algorithm is:
15524   *   - ensure sane alignment of input data
15525   *   - copy (conversion happens automatically) input data
15526   *     to output
15527   *   - update xpp to point at next unconverted input, and tp to point
15528   *     at next location for converted output
15529   */
15530   long i, j, ni;
15531   float tmp[LOOPCNT];        /* in case input is misaligned */
15532   float *xp;
15533   int nrange = 0;         /* number of range errors */
15534   int realign = 0;        /* "do we need to fix input data alignment?" */
15535   long cxp = (long) *((char**)xpp);
15536 
15537   realign = (cxp & 7) % SIZEOF_FLOAT;
15538   /* sjl: manually stripmine so we can limit amount of
15539    * vector work space reserved to LOOPCNT elements. Also
15540    * makes vectorisation easy */
15541   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15542     ni=Min(nelems-j,LOOPCNT);
15543     if (realign) {
15544       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15545       xp = tmp;
15546     } else {
15547       xp = (float *) *xpp;
15548     }
15549    /* copy the next block */
15550 #pragma cdir loopcnt=LOOPCNT
15551 #pragma cdir shortloop
15552     for (i=0; i<ni; i++) {
15553       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
15554      /* test for range errors (not always needed but do it anyway) */
15555      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15556      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15557       nrange += xp[i] > UINT_MAX || xp[i] < 0;
15558     }
15559    /* update xpp and tp */
15560     if (realign) xp = (float *) *xpp;
15561     xp += ni;
15562     tp += ni;
15563     *xpp = (void*)xp;
15564   }
15565   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15566 
15567 #else   /* not SX */
15568 	const char *xp = (const char *) *xpp;
15569 	int status = NC_NOERR;
15570 
15571 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15572 	{
15573 		const int lstatus = ncx_get_float_uint(xp, tp);
15574 		if (status == NC_NOERR) /* report the first encountered error */
15575 			status = lstatus;
15576 	}
15577 
15578 	*xpp = (const void *)xp;
15579 	return status;
15580 #endif
15581 }
15582 
15583 int
ncx_getn_float_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)15584 ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
15585 {
15586 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15587 
15588  /* basic algorithm is:
15589   *   - ensure sane alignment of input data
15590   *   - copy (conversion happens automatically) input data
15591   *     to output
15592   *   - update xpp to point at next unconverted input, and tp to point
15593   *     at next location for converted output
15594   */
15595   long i, j, ni;
15596   float tmp[LOOPCNT];        /* in case input is misaligned */
15597   float *xp;
15598   int nrange = 0;         /* number of range errors */
15599   int realign = 0;        /* "do we need to fix input data alignment?" */
15600   long cxp = (long) *((char**)xpp);
15601 
15602   realign = (cxp & 7) % SIZEOF_FLOAT;
15603   /* sjl: manually stripmine so we can limit amount of
15604    * vector work space reserved to LOOPCNT elements. Also
15605    * makes vectorisation easy */
15606   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15607     ni=Min(nelems-j,LOOPCNT);
15608     if (realign) {
15609       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
15610       xp = tmp;
15611     } else {
15612       xp = (float *) *xpp;
15613     }
15614    /* copy the next block */
15615 #pragma cdir loopcnt=LOOPCNT
15616 #pragma cdir shortloop
15617     for (i=0; i<ni; i++) {
15618       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
15619      /* test for range errors (not always needed but do it anyway) */
15620      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
15621      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
15622       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
15623     }
15624    /* update xpp and tp */
15625     if (realign) xp = (float *) *xpp;
15626     xp += ni;
15627     tp += ni;
15628     *xpp = (void*)xp;
15629   }
15630   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15631 
15632 #else   /* not SX */
15633 	const char *xp = (const char *) *xpp;
15634 	int status = NC_NOERR;
15635 
15636 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15637 	{
15638 		const int lstatus = ncx_get_float_ulonglong(xp, tp);
15639 		if (status == NC_NOERR) /* report the first encountered error */
15640 			status = lstatus;
15641 	}
15642 
15643 	*xpp = (const void *)xp;
15644 	return status;
15645 #endif
15646 }
15647 
15648 
15649 int
ncx_putn_float_float(void ** xpp,size_t nelems,const float * tp,void * fillp)15650 ncx_putn_float_float(void **xpp, size_t nelems, const float *tp, void *fillp)
15651 #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
15652 /* optimized version */
15653 {
15654 #ifdef WORDS_BIGENDIAN
15655 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
15656 # else
15657 	swapn4b(*xpp, tp, nelems);
15658 # endif
15659 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
15660 	return NC_NOERR;
15661 }
15662 #elif defined(vax) && vax != 0
15663 {
15664 	const float *const end = tp + nelems;
15665 
15666 	while (tp < end) {
15667 				const struct vax_single *const vsp =
15668 			 (const struct vax_single *)ip;
15669 		struct ieee_single *const isp = (struct ieee_single *) (*xpp);
15670 
15671 		switch(vsp->exp){
15672 		case 0 :
15673 			/* all vax float with zero exponent map to zero */
15674 			*isp = min.ieee;
15675 			break;
15676 		case 2 :
15677 		case 1 :
15678 		{
15679 			/* These will map to subnormals */
15680 			unsigned mantissa = (vsp->mantissa1 << 16)
15681 					 | vsp->mantissa2;
15682 			mantissa >>= 3 - vsp->exp;
15683 			mantissa += (1 << (20 + vsp->exp));
15684 			isp->mant_lo_lo = mantissa;
15685 			isp->mant_lo_hi = mantissa >> 8;
15686 			isp->mant_hi = mantissa >> 16;
15687 			isp->exp_lo = 0;
15688 			isp->exp_hi = 0;
15689 		}
15690 			break;
15691 		case 0xff : /* max.s.exp */
15692 			if (vsp->mantissa2 == max.s.mantissa2 &&
15693 			    vsp->mantissa1 == max.s.mantissa1)
15694 			{
15695 				/* map largest vax float to ieee infinity */
15696 				*isp = max.ieee;
15697 				break;
15698 			} /* else, fall thru */
15699 		default :
15700 		{
15701 			unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
15702 			isp->exp_hi = exp >> 1;
15703 			isp->exp_lo = exp;
15704 			isp->mant_lo_lo = vsp->mantissa2;
15705 			isp->mant_lo_hi = vsp->mantissa2 >> 8;
15706 			isp->mant_hi = vsp->mantissa1;
15707 		}
15708 		}
15709 
15710 		isp->sign = vsp->sign;
15711 
15712 		tp++;
15713 		*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
15714 	}
15715 	return NC_NOERR;
15716 }
15717 #else
15718 {
15719 	char *xp = *xpp;
15720 	int status = NC_NOERR;
15721 
15722 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
15723 		int lstatus = ncx_put_float_float(xp, tp, fillp);
15724 		if (status == NC_NOERR) /* report the first encountered error */
15725 			status = lstatus;
15726 	}
15727 
15728 	*xpp = (void *)xp;
15729 	return status;
15730 }
15731 #endif
15732 int
ncx_putn_float_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)15733 ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
15734 {
15735 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15736 
15737  /* basic algorithm is:
15738   *   - ensure sane alignment of output data
15739   *   - copy (conversion happens automatically) input data
15740   *     to output
15741   *   - update tp to point at next unconverted input, and xpp to point
15742   *     at next location for converted output
15743   */
15744   long i, j, ni;
15745   float tmp[LOOPCNT];        /* in case input is misaligned */
15746   float *xp;
15747   int nrange = 0;         /* number of range errors */
15748   int realign = 0;        /* "do we need to fix input data alignment?" */
15749   long cxp = (long) *((char**)xpp);
15750 
15751   realign = (cxp & 7) % SIZEOF_FLOAT;
15752   /* sjl: manually stripmine so we can limit amount of
15753    * vector work space reserved to LOOPCNT elements. Also
15754    * makes vectorisation easy */
15755   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15756     ni=Min(nelems-j,LOOPCNT);
15757     if (realign) {
15758       xp = tmp;
15759     } else {
15760       xp = (float *) *xpp;
15761     }
15762    /* copy the next block */
15763 #pragma cdir loopcnt=LOOPCNT
15764 #pragma cdir shortloop
15765     for (i=0; i<ni; i++) {
15766       /* the normal case: */
15767       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15768      /* test for range errors (not always needed but do it anyway) */
15769      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15770      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15771       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15772     }
15773    /* copy workspace back if necessary */
15774     if (realign) {
15775       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15776       xp = (float *) *xpp;
15777     }
15778    /* update xpp and tp */
15779     xp += ni;
15780     tp += ni;
15781     *xpp = (void*)xp;
15782   }
15783   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15784 
15785 #else   /* not SX */
15786 
15787 	char *xp = (char *) *xpp;
15788 	int status = NC_NOERR;
15789 
15790 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15791 	{
15792 		int lstatus = ncx_put_float_schar(xp, tp, fillp);
15793 		if (status == NC_NOERR) /* report the first encountered error */
15794 			status = lstatus;
15795 	}
15796 
15797 	*xpp = (void *)xp;
15798 	return status;
15799 #endif
15800 }
15801 
15802 int
ncx_putn_float_short(void ** xpp,size_t nelems,const short * tp,void * fillp)15803 ncx_putn_float_short(void **xpp, size_t nelems, const short *tp, void *fillp)
15804 {
15805 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15806 
15807  /* basic algorithm is:
15808   *   - ensure sane alignment of output data
15809   *   - copy (conversion happens automatically) input data
15810   *     to output
15811   *   - update tp to point at next unconverted input, and xpp to point
15812   *     at next location for converted output
15813   */
15814   long i, j, ni;
15815   float tmp[LOOPCNT];        /* in case input is misaligned */
15816   float *xp;
15817   int nrange = 0;         /* number of range errors */
15818   int realign = 0;        /* "do we need to fix input data alignment?" */
15819   long cxp = (long) *((char**)xpp);
15820 
15821   realign = (cxp & 7) % SIZEOF_FLOAT;
15822   /* sjl: manually stripmine so we can limit amount of
15823    * vector work space reserved to LOOPCNT elements. Also
15824    * makes vectorisation easy */
15825   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15826     ni=Min(nelems-j,LOOPCNT);
15827     if (realign) {
15828       xp = tmp;
15829     } else {
15830       xp = (float *) *xpp;
15831     }
15832    /* copy the next block */
15833 #pragma cdir loopcnt=LOOPCNT
15834 #pragma cdir shortloop
15835     for (i=0; i<ni; i++) {
15836       /* the normal case: */
15837       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15838      /* test for range errors (not always needed but do it anyway) */
15839      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15840      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15841       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15842     }
15843    /* copy workspace back if necessary */
15844     if (realign) {
15845       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15846       xp = (float *) *xpp;
15847     }
15848    /* update xpp and tp */
15849     xp += ni;
15850     tp += ni;
15851     *xpp = (void*)xp;
15852   }
15853   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15854 
15855 #else   /* not SX */
15856 
15857 	char *xp = (char *) *xpp;
15858 	int status = NC_NOERR;
15859 
15860 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15861 	{
15862 		int lstatus = ncx_put_float_short(xp, tp, fillp);
15863 		if (status == NC_NOERR) /* report the first encountered error */
15864 			status = lstatus;
15865 	}
15866 
15867 	*xpp = (void *)xp;
15868 	return status;
15869 #endif
15870 }
15871 
15872 int
ncx_putn_float_int(void ** xpp,size_t nelems,const int * tp,void * fillp)15873 ncx_putn_float_int(void **xpp, size_t nelems, const int *tp, void *fillp)
15874 {
15875 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15876 
15877  /* basic algorithm is:
15878   *   - ensure sane alignment of output data
15879   *   - copy (conversion happens automatically) input data
15880   *     to output
15881   *   - update tp to point at next unconverted input, and xpp to point
15882   *     at next location for converted output
15883   */
15884   long i, j, ni;
15885   float tmp[LOOPCNT];        /* in case input is misaligned */
15886   float *xp;
15887   int nrange = 0;         /* number of range errors */
15888   int realign = 0;        /* "do we need to fix input data alignment?" */
15889   long cxp = (long) *((char**)xpp);
15890 
15891   realign = (cxp & 7) % SIZEOF_FLOAT;
15892   /* sjl: manually stripmine so we can limit amount of
15893    * vector work space reserved to LOOPCNT elements. Also
15894    * makes vectorisation easy */
15895   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15896     ni=Min(nelems-j,LOOPCNT);
15897     if (realign) {
15898       xp = tmp;
15899     } else {
15900       xp = (float *) *xpp;
15901     }
15902    /* copy the next block */
15903 #pragma cdir loopcnt=LOOPCNT
15904 #pragma cdir shortloop
15905     for (i=0; i<ni; i++) {
15906       /* the normal case: */
15907       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15908      /* test for range errors (not always needed but do it anyway) */
15909      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15910      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15911       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15912     }
15913    /* copy workspace back if necessary */
15914     if (realign) {
15915       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15916       xp = (float *) *xpp;
15917     }
15918    /* update xpp and tp */
15919     xp += ni;
15920     tp += ni;
15921     *xpp = (void*)xp;
15922   }
15923   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15924 
15925 #else   /* not SX */
15926 
15927 	char *xp = (char *) *xpp;
15928 	int status = NC_NOERR;
15929 
15930 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
15931 	{
15932 		int lstatus = ncx_put_float_int(xp, tp, fillp);
15933 		if (status == NC_NOERR) /* report the first encountered error */
15934 			status = lstatus;
15935 	}
15936 
15937 	*xpp = (void *)xp;
15938 	return status;
15939 #endif
15940 }
15941 
15942 int
ncx_putn_float_long(void ** xpp,size_t nelems,const long * tp,void * fillp)15943 ncx_putn_float_long(void **xpp, size_t nelems, const long *tp, void *fillp)
15944 {
15945 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
15946 
15947  /* basic algorithm is:
15948   *   - ensure sane alignment of output data
15949   *   - copy (conversion happens automatically) input data
15950   *     to output
15951   *   - update tp to point at next unconverted input, and xpp to point
15952   *     at next location for converted output
15953   */
15954   long i, j, ni;
15955   float tmp[LOOPCNT];        /* in case input is misaligned */
15956   float *xp;
15957   int nrange = 0;         /* number of range errors */
15958   int realign = 0;        /* "do we need to fix input data alignment?" */
15959   long cxp = (long) *((char**)xpp);
15960 
15961   realign = (cxp & 7) % SIZEOF_FLOAT;
15962   /* sjl: manually stripmine so we can limit amount of
15963    * vector work space reserved to LOOPCNT elements. Also
15964    * makes vectorisation easy */
15965   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
15966     ni=Min(nelems-j,LOOPCNT);
15967     if (realign) {
15968       xp = tmp;
15969     } else {
15970       xp = (float *) *xpp;
15971     }
15972    /* copy the next block */
15973 #pragma cdir loopcnt=LOOPCNT
15974 #pragma cdir shortloop
15975     for (i=0; i<ni; i++) {
15976       /* the normal case: */
15977       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
15978      /* test for range errors (not always needed but do it anyway) */
15979      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
15980      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
15981       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
15982     }
15983    /* copy workspace back if necessary */
15984     if (realign) {
15985       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
15986       xp = (float *) *xpp;
15987     }
15988    /* update xpp and tp */
15989     xp += ni;
15990     tp += ni;
15991     *xpp = (void*)xp;
15992   }
15993   return nrange == 0 ? NC_NOERR : NC_ERANGE;
15994 
15995 #else   /* not SX */
15996 
15997 	char *xp = (char *) *xpp;
15998 	int status = NC_NOERR;
15999 
16000 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16001 	{
16002 		int lstatus = ncx_put_float_long(xp, tp, fillp);
16003 		if (status == NC_NOERR) /* report the first encountered error */
16004 			status = lstatus;
16005 	}
16006 
16007 	*xpp = (void *)xp;
16008 	return status;
16009 #endif
16010 }
16011 
16012 int
ncx_putn_float_double(void ** xpp,size_t nelems,const double * tp,void * fillp)16013 ncx_putn_float_double(void **xpp, size_t nelems, const double *tp, void *fillp)
16014 {
16015 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16016 
16017  /* basic algorithm is:
16018   *   - ensure sane alignment of output data
16019   *   - copy (conversion happens automatically) input data
16020   *     to output
16021   *   - update tp to point at next unconverted input, and xpp to point
16022   *     at next location for converted output
16023   */
16024   long i, j, ni;
16025   float tmp[LOOPCNT];        /* in case input is misaligned */
16026   float *xp;
16027   int nrange = 0;         /* number of range errors */
16028   int realign = 0;        /* "do we need to fix input data alignment?" */
16029   long cxp = (long) *((char**)xpp);
16030 
16031   realign = (cxp & 7) % SIZEOF_FLOAT;
16032   /* sjl: manually stripmine so we can limit amount of
16033    * vector work space reserved to LOOPCNT elements. Also
16034    * makes vectorisation easy */
16035   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16036     ni=Min(nelems-j,LOOPCNT);
16037     if (realign) {
16038       xp = tmp;
16039     } else {
16040       xp = (float *) *xpp;
16041     }
16042    /* copy the next block */
16043 #pragma cdir loopcnt=LOOPCNT
16044 #pragma cdir shortloop
16045     for (i=0; i<ni; i++) {
16046       /* the normal case: */
16047       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16048      /* test for range errors (not always needed but do it anyway) */
16049      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16050      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16051       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
16052     }
16053    /* copy workspace back if necessary */
16054     if (realign) {
16055       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16056       xp = (float *) *xpp;
16057     }
16058    /* update xpp and tp */
16059     xp += ni;
16060     tp += ni;
16061     *xpp = (void*)xp;
16062   }
16063   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16064 
16065 #else   /* not SX */
16066 
16067 	char *xp = (char *) *xpp;
16068 	int status = NC_NOERR;
16069 
16070 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16071 	{
16072 		int lstatus = ncx_put_float_double(xp, tp, fillp);
16073 		if (status == NC_NOERR) /* report the first encountered error */
16074 			status = lstatus;
16075 	}
16076 
16077 	*xpp = (void *)xp;
16078 	return status;
16079 #endif
16080 }
16081 
16082 int
ncx_putn_float_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)16083 ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
16084 {
16085 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16086 
16087  /* basic algorithm is:
16088   *   - ensure sane alignment of output data
16089   *   - copy (conversion happens automatically) input data
16090   *     to output
16091   *   - update tp to point at next unconverted input, and xpp to point
16092   *     at next location for converted output
16093   */
16094   long i, j, ni;
16095   float tmp[LOOPCNT];        /* in case input is misaligned */
16096   float *xp;
16097   int nrange = 0;         /* number of range errors */
16098   int realign = 0;        /* "do we need to fix input data alignment?" */
16099   long cxp = (long) *((char**)xpp);
16100 
16101   realign = (cxp & 7) % SIZEOF_FLOAT;
16102   /* sjl: manually stripmine so we can limit amount of
16103    * vector work space reserved to LOOPCNT elements. Also
16104    * makes vectorisation easy */
16105   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16106     ni=Min(nelems-j,LOOPCNT);
16107     if (realign) {
16108       xp = tmp;
16109     } else {
16110       xp = (float *) *xpp;
16111     }
16112    /* copy the next block */
16113 #pragma cdir loopcnt=LOOPCNT
16114 #pragma cdir shortloop
16115     for (i=0; i<ni; i++) {
16116       /* the normal case: */
16117       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16118      /* test for range errors (not always needed but do it anyway) */
16119      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16120      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16121       nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
16122     }
16123    /* copy workspace back if necessary */
16124     if (realign) {
16125       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16126       xp = (float *) *xpp;
16127     }
16128    /* update xpp and tp */
16129     xp += ni;
16130     tp += ni;
16131     *xpp = (void*)xp;
16132   }
16133   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16134 
16135 #else   /* not SX */
16136 
16137 	char *xp = (char *) *xpp;
16138 	int status = NC_NOERR;
16139 
16140 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16141 	{
16142 		int lstatus = ncx_put_float_longlong(xp, tp, fillp);
16143 		if (status == NC_NOERR) /* report the first encountered error */
16144 			status = lstatus;
16145 	}
16146 
16147 	*xpp = (void *)xp;
16148 	return status;
16149 #endif
16150 }
16151 
16152 int
ncx_putn_float_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)16153 ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
16154 {
16155 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16156 
16157  /* basic algorithm is:
16158   *   - ensure sane alignment of output data
16159   *   - copy (conversion happens automatically) input data
16160   *     to output
16161   *   - update tp to point at next unconverted input, and xpp to point
16162   *     at next location for converted output
16163   */
16164   long i, j, ni;
16165   float tmp[LOOPCNT];        /* in case input is misaligned */
16166   float *xp;
16167   int nrange = 0;         /* number of range errors */
16168   int realign = 0;        /* "do we need to fix input data alignment?" */
16169   long cxp = (long) *((char**)xpp);
16170 
16171   realign = (cxp & 7) % SIZEOF_FLOAT;
16172   /* sjl: manually stripmine so we can limit amount of
16173    * vector work space reserved to LOOPCNT elements. Also
16174    * makes vectorisation easy */
16175   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16176     ni=Min(nelems-j,LOOPCNT);
16177     if (realign) {
16178       xp = tmp;
16179     } else {
16180       xp = (float *) *xpp;
16181     }
16182    /* copy the next block */
16183 #pragma cdir loopcnt=LOOPCNT
16184 #pragma cdir shortloop
16185     for (i=0; i<ni; i++) {
16186       /* the normal case: */
16187       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16188      /* test for range errors (not always needed but do it anyway) */
16189      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16190      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16191       nrange += tp[i] > X_FLOAT_MAX ;
16192     }
16193    /* copy workspace back if necessary */
16194     if (realign) {
16195       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16196       xp = (float *) *xpp;
16197     }
16198    /* update xpp and tp */
16199     xp += ni;
16200     tp += ni;
16201     *xpp = (void*)xp;
16202   }
16203   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16204 
16205 #else   /* not SX */
16206 
16207 	char *xp = (char *) *xpp;
16208 	int status = NC_NOERR;
16209 
16210 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16211 	{
16212 		int lstatus = ncx_put_float_uchar(xp, tp, fillp);
16213 		if (status == NC_NOERR) /* report the first encountered error */
16214 			status = lstatus;
16215 	}
16216 
16217 	*xpp = (void *)xp;
16218 	return status;
16219 #endif
16220 }
16221 
16222 int
ncx_putn_float_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)16223 ncx_putn_float_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
16224 {
16225 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16226 
16227  /* basic algorithm is:
16228   *   - ensure sane alignment of output data
16229   *   - copy (conversion happens automatically) input data
16230   *     to output
16231   *   - update tp to point at next unconverted input, and xpp to point
16232   *     at next location for converted output
16233   */
16234   long i, j, ni;
16235   float tmp[LOOPCNT];        /* in case input is misaligned */
16236   float *xp;
16237   int nrange = 0;         /* number of range errors */
16238   int realign = 0;        /* "do we need to fix input data alignment?" */
16239   long cxp = (long) *((char**)xpp);
16240 
16241   realign = (cxp & 7) % SIZEOF_FLOAT;
16242   /* sjl: manually stripmine so we can limit amount of
16243    * vector work space reserved to LOOPCNT elements. Also
16244    * makes vectorisation easy */
16245   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16246     ni=Min(nelems-j,LOOPCNT);
16247     if (realign) {
16248       xp = tmp;
16249     } else {
16250       xp = (float *) *xpp;
16251     }
16252    /* copy the next block */
16253 #pragma cdir loopcnt=LOOPCNT
16254 #pragma cdir shortloop
16255     for (i=0; i<ni; i++) {
16256       /* the normal case: */
16257       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16258      /* test for range errors (not always needed but do it anyway) */
16259      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16260      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16261       nrange += tp[i] > X_FLOAT_MAX ;
16262     }
16263    /* copy workspace back if necessary */
16264     if (realign) {
16265       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16266       xp = (float *) *xpp;
16267     }
16268    /* update xpp and tp */
16269     xp += ni;
16270     tp += ni;
16271     *xpp = (void*)xp;
16272   }
16273   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16274 
16275 #else   /* not SX */
16276 
16277 	char *xp = (char *) *xpp;
16278 	int status = NC_NOERR;
16279 
16280 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16281 	{
16282 		int lstatus = ncx_put_float_ushort(xp, tp, fillp);
16283 		if (status == NC_NOERR) /* report the first encountered error */
16284 			status = lstatus;
16285 	}
16286 
16287 	*xpp = (void *)xp;
16288 	return status;
16289 #endif
16290 }
16291 
16292 int
ncx_putn_float_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)16293 ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
16294 {
16295 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16296 
16297  /* basic algorithm is:
16298   *   - ensure sane alignment of output data
16299   *   - copy (conversion happens automatically) input data
16300   *     to output
16301   *   - update tp to point at next unconverted input, and xpp to point
16302   *     at next location for converted output
16303   */
16304   long i, j, ni;
16305   float tmp[LOOPCNT];        /* in case input is misaligned */
16306   float *xp;
16307   int nrange = 0;         /* number of range errors */
16308   int realign = 0;        /* "do we need to fix input data alignment?" */
16309   long cxp = (long) *((char**)xpp);
16310 
16311   realign = (cxp & 7) % SIZEOF_FLOAT;
16312   /* sjl: manually stripmine so we can limit amount of
16313    * vector work space reserved to LOOPCNT elements. Also
16314    * makes vectorisation easy */
16315   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16316     ni=Min(nelems-j,LOOPCNT);
16317     if (realign) {
16318       xp = tmp;
16319     } else {
16320       xp = (float *) *xpp;
16321     }
16322    /* copy the next block */
16323 #pragma cdir loopcnt=LOOPCNT
16324 #pragma cdir shortloop
16325     for (i=0; i<ni; i++) {
16326       /* the normal case: */
16327       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16328      /* test for range errors (not always needed but do it anyway) */
16329      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16330      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16331       nrange += tp[i] > X_FLOAT_MAX ;
16332     }
16333    /* copy workspace back if necessary */
16334     if (realign) {
16335       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16336       xp = (float *) *xpp;
16337     }
16338    /* update xpp and tp */
16339     xp += ni;
16340     tp += ni;
16341     *xpp = (void*)xp;
16342   }
16343   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16344 
16345 #else   /* not SX */
16346 
16347 	char *xp = (char *) *xpp;
16348 	int status = NC_NOERR;
16349 
16350 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16351 	{
16352 		int lstatus = ncx_put_float_uint(xp, tp, fillp);
16353 		if (status == NC_NOERR) /* report the first encountered error */
16354 			status = lstatus;
16355 	}
16356 
16357 	*xpp = (void *)xp;
16358 	return status;
16359 #endif
16360 }
16361 
16362 int
ncx_putn_float_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)16363 ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
16364 {
16365 #if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT
16366 
16367  /* basic algorithm is:
16368   *   - ensure sane alignment of output data
16369   *   - copy (conversion happens automatically) input data
16370   *     to output
16371   *   - update tp to point at next unconverted input, and xpp to point
16372   *     at next location for converted output
16373   */
16374   long i, j, ni;
16375   float tmp[LOOPCNT];        /* in case input is misaligned */
16376   float *xp;
16377   int nrange = 0;         /* number of range errors */
16378   int realign = 0;        /* "do we need to fix input data alignment?" */
16379   long cxp = (long) *((char**)xpp);
16380 
16381   realign = (cxp & 7) % SIZEOF_FLOAT;
16382   /* sjl: manually stripmine so we can limit amount of
16383    * vector work space reserved to LOOPCNT elements. Also
16384    * makes vectorisation easy */
16385   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16386     ni=Min(nelems-j,LOOPCNT);
16387     if (realign) {
16388       xp = tmp;
16389     } else {
16390       xp = (float *) *xpp;
16391     }
16392    /* copy the next block */
16393 #pragma cdir loopcnt=LOOPCNT
16394 #pragma cdir shortloop
16395     for (i=0; i<ni; i++) {
16396       /* the normal case: */
16397       xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
16398      /* test for range errors (not always needed but do it anyway) */
16399      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
16400      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
16401       nrange += tp[i] > X_FLOAT_MAX ;
16402     }
16403    /* copy workspace back if necessary */
16404     if (realign) {
16405       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
16406       xp = (float *) *xpp;
16407     }
16408    /* update xpp and tp */
16409     xp += ni;
16410     tp += ni;
16411     *xpp = (void*)xp;
16412   }
16413   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16414 
16415 #else   /* not SX */
16416 
16417 	char *xp = (char *) *xpp;
16418 	int status = NC_NOERR;
16419 
16420 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
16421 	{
16422 		int lstatus = ncx_put_float_ulonglong(xp, tp, fillp);
16423 		if (status == NC_NOERR) /* report the first encountered error */
16424 			status = lstatus;
16425 	}
16426 
16427 	*xpp = (void *)xp;
16428 	return status;
16429 #endif
16430 }
16431 
16432 
16433 /* double --------------------------------------------------------------------*/
16434 
16435 #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
16436 /* optimized version */
16437 int
ncx_getn_double_double(const void ** xpp,size_t nelems,double * tp)16438 ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16439 {
16440 #ifdef WORDS_BIGENDIAN
16441 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
16442 # else
16443 	swapn8b(tp, *xpp, nelems);
16444 # endif
16445 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
16446 	return NC_NOERR;
16447 }
16448 #elif defined(vax) && vax != 0
16449 int
ncx_getn_double_double(const void ** xpp,size_t ndoubles,double * ip)16450 ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
16451 {
16452 	double *const end = ip + ndoubles;
16453 
16454 	while (ip < end)
16455 	{
16456 	struct vax_double *const vdp =
16457 			 (struct vax_double *)ip;
16458 	const struct ieee_double *const idp =
16459 			 (const struct ieee_double *) (*xpp);
16460 	{
16461 		const struct dbl_limits *lim;
16462 		int ii;
16463 		for (ii = 0, lim = dbl_limits;
16464 			ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
16465 			ii++, lim++)
16466 		{
16467 			if ((idp->mant_lo == lim->ieee.mant_lo)
16468 				&& (idp->mant_4 == lim->ieee.mant_4)
16469 				&& (idp->mant_5 == lim->ieee.mant_5)
16470 				&& (idp->mant_6 == lim->ieee.mant_6)
16471 				&& (idp->exp_lo == lim->ieee.exp_lo)
16472 				&& (idp->exp_hi == lim->ieee.exp_hi)
16473 				)
16474 			{
16475 				*vdp = lim->d;
16476 				goto doneit;
16477 			}
16478 		}
16479 	}
16480 	{
16481 		unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
16482 		vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
16483 	}
16484 	{
16485 		unsigned mant_hi = ((idp->mant_6 << 16)
16486 				 | (idp->mant_5 << 8)
16487 				 | idp->mant_4);
16488 		unsigned mant_lo = SWAP4(idp->mant_lo);
16489 		vdp->mantissa1 = (mant_hi >> 13);
16490 		vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
16491 				| (mant_lo >> 29);
16492 		vdp->mantissa3 = (mant_lo >> 13);
16493 		vdp->mantissa4 = (mant_lo << 3);
16494 	}
16495 	doneit:
16496 		vdp->sign = idp->sign;
16497 
16498 		ip++;
16499 		*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
16500 	}
16501 	return NC_NOERR;
16502 }
16503 	/* vax */
16504 #else
16505 int
ncx_getn_double_double(const void ** xpp,size_t nelems,double * tp)16506 ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
16507 {
16508 	const char *xp = *xpp;
16509 	int status = NC_NOERR;
16510 
16511 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16512 	{
16513 		const int lstatus = ncx_get_double_double(xp, tp, fillp);
16514 		if (status == NC_NOERR) /* report the first encountered error */
16515 			status = lstatus;
16516 	}
16517 
16518 	*xpp = (const void *)xp;
16519 	return status;
16520 }
16521 #endif
16522 int
ncx_getn_double_schar(const void ** xpp,size_t nelems,schar * tp)16523 ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
16524 {
16525 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16526 
16527  /* basic algorithm is:
16528   *   - ensure sane alignment of input data
16529   *   - copy (conversion happens automatically) input data
16530   *     to output
16531   *   - update xpp to point at next unconverted input, and tp to point
16532   *     at next location for converted output
16533   */
16534   long i, j, ni;
16535   double tmp[LOOPCNT];        /* in case input is misaligned */
16536   double *xp;
16537   int nrange = 0;         /* number of range errors */
16538   int realign = 0;        /* "do we need to fix input data alignment?" */
16539   long cxp = (long) *((char**)xpp);
16540 
16541   realign = (cxp & 7) % SIZEOF_DOUBLE;
16542   /* sjl: manually stripmine so we can limit amount of
16543    * vector work space reserved to LOOPCNT elements. Also
16544    * makes vectorisation easy */
16545   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16546     ni=Min(nelems-j,LOOPCNT);
16547     if (realign) {
16548       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16549       xp = tmp;
16550     } else {
16551       xp = (double *) *xpp;
16552     }
16553    /* copy the next block */
16554 #pragma cdir loopcnt=LOOPCNT
16555 #pragma cdir shortloop
16556     for (i=0; i<ni; i++) {
16557       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
16558      /* test for range errors (not always needed but do it anyway) */
16559      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16560      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16561       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
16562     }
16563    /* update xpp and tp */
16564     if (realign) xp = (double *) *xpp;
16565     xp += ni;
16566     tp += ni;
16567     *xpp = (void*)xp;
16568   }
16569   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16570 
16571 #else   /* not SX */
16572 	const char *xp = (const char *) *xpp;
16573 	int status = NC_NOERR;
16574 
16575 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16576 	{
16577 		const int lstatus = ncx_get_double_schar(xp, tp);
16578 		if (status == NC_NOERR) /* report the first encountered error */
16579 			status = lstatus;
16580 	}
16581 
16582 	*xpp = (const void *)xp;
16583 	return status;
16584 #endif
16585 }
16586 
16587 int
ncx_getn_double_short(const void ** xpp,size_t nelems,short * tp)16588 ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
16589 {
16590 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16591 
16592  /* basic algorithm is:
16593   *   - ensure sane alignment of input data
16594   *   - copy (conversion happens automatically) input data
16595   *     to output
16596   *   - update xpp to point at next unconverted input, and tp to point
16597   *     at next location for converted output
16598   */
16599   long i, j, ni;
16600   double tmp[LOOPCNT];        /* in case input is misaligned */
16601   double *xp;
16602   int nrange = 0;         /* number of range errors */
16603   int realign = 0;        /* "do we need to fix input data alignment?" */
16604   long cxp = (long) *((char**)xpp);
16605 
16606   realign = (cxp & 7) % SIZEOF_DOUBLE;
16607   /* sjl: manually stripmine so we can limit amount of
16608    * vector work space reserved to LOOPCNT elements. Also
16609    * makes vectorisation easy */
16610   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16611     ni=Min(nelems-j,LOOPCNT);
16612     if (realign) {
16613       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16614       xp = tmp;
16615     } else {
16616       xp = (double *) *xpp;
16617     }
16618    /* copy the next block */
16619 #pragma cdir loopcnt=LOOPCNT
16620 #pragma cdir shortloop
16621     for (i=0; i<ni; i++) {
16622       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
16623      /* test for range errors (not always needed but do it anyway) */
16624      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16625      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16626       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
16627     }
16628    /* update xpp and tp */
16629     if (realign) xp = (double *) *xpp;
16630     xp += ni;
16631     tp += ni;
16632     *xpp = (void*)xp;
16633   }
16634   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16635 
16636 #else   /* not SX */
16637 	const char *xp = (const char *) *xpp;
16638 	int status = NC_NOERR;
16639 
16640 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16641 	{
16642 		const int lstatus = ncx_get_double_short(xp, tp);
16643 		if (status == NC_NOERR) /* report the first encountered error */
16644 			status = lstatus;
16645 	}
16646 
16647 	*xpp = (const void *)xp;
16648 	return status;
16649 #endif
16650 }
16651 
16652 int
ncx_getn_double_int(const void ** xpp,size_t nelems,int * tp)16653 ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
16654 {
16655 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16656 
16657  /* basic algorithm is:
16658   *   - ensure sane alignment of input data
16659   *   - copy (conversion happens automatically) input data
16660   *     to output
16661   *   - update xpp to point at next unconverted input, and tp to point
16662   *     at next location for converted output
16663   */
16664   long i, j, ni;
16665   double tmp[LOOPCNT];        /* in case input is misaligned */
16666   double *xp;
16667   int nrange = 0;         /* number of range errors */
16668   int realign = 0;        /* "do we need to fix input data alignment?" */
16669   long cxp = (long) *((char**)xpp);
16670 
16671   realign = (cxp & 7) % SIZEOF_DOUBLE;
16672   /* sjl: manually stripmine so we can limit amount of
16673    * vector work space reserved to LOOPCNT elements. Also
16674    * makes vectorisation easy */
16675   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16676     ni=Min(nelems-j,LOOPCNT);
16677     if (realign) {
16678       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16679       xp = tmp;
16680     } else {
16681       xp = (double *) *xpp;
16682     }
16683    /* copy the next block */
16684 #pragma cdir loopcnt=LOOPCNT
16685 #pragma cdir shortloop
16686     for (i=0; i<ni; i++) {
16687       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
16688      /* test for range errors (not always needed but do it anyway) */
16689      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16690      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16691       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
16692     }
16693    /* update xpp and tp */
16694     if (realign) xp = (double *) *xpp;
16695     xp += ni;
16696     tp += ni;
16697     *xpp = (void*)xp;
16698   }
16699   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16700 
16701 #else   /* not SX */
16702 	const char *xp = (const char *) *xpp;
16703 	int status = NC_NOERR;
16704 
16705 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16706 	{
16707 		const int lstatus = ncx_get_double_int(xp, tp);
16708 		if (status == NC_NOERR) /* report the first encountered error */
16709 			status = lstatus;
16710 	}
16711 
16712 	*xpp = (const void *)xp;
16713 	return status;
16714 #endif
16715 }
16716 
16717 int
ncx_getn_double_long(const void ** xpp,size_t nelems,long * tp)16718 ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
16719 {
16720 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16721 
16722  /* basic algorithm is:
16723   *   - ensure sane alignment of input data
16724   *   - copy (conversion happens automatically) input data
16725   *     to output
16726   *   - update xpp to point at next unconverted input, and tp to point
16727   *     at next location for converted output
16728   */
16729   long i, j, ni;
16730   double tmp[LOOPCNT];        /* in case input is misaligned */
16731   double *xp;
16732   int nrange = 0;         /* number of range errors */
16733   int realign = 0;        /* "do we need to fix input data alignment?" */
16734   long cxp = (long) *((char**)xpp);
16735 
16736   realign = (cxp & 7) % SIZEOF_DOUBLE;
16737   /* sjl: manually stripmine so we can limit amount of
16738    * vector work space reserved to LOOPCNT elements. Also
16739    * makes vectorisation easy */
16740   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16741     ni=Min(nelems-j,LOOPCNT);
16742     if (realign) {
16743       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16744       xp = tmp;
16745     } else {
16746       xp = (double *) *xpp;
16747     }
16748    /* copy the next block */
16749 #pragma cdir loopcnt=LOOPCNT
16750 #pragma cdir shortloop
16751     for (i=0; i<ni; i++) {
16752       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
16753      /* test for range errors (not always needed but do it anyway) */
16754      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16755      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16756       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
16757     }
16758    /* update xpp and tp */
16759     if (realign) xp = (double *) *xpp;
16760     xp += ni;
16761     tp += ni;
16762     *xpp = (void*)xp;
16763   }
16764   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16765 
16766 #else   /* not SX */
16767 	const char *xp = (const char *) *xpp;
16768 	int status = NC_NOERR;
16769 
16770 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16771 	{
16772 		const int lstatus = ncx_get_double_long(xp, tp);
16773 		if (status == NC_NOERR) /* report the first encountered error */
16774 			status = lstatus;
16775 	}
16776 
16777 	*xpp = (const void *)xp;
16778 	return status;
16779 #endif
16780 }
16781 
16782 int
ncx_getn_double_float(const void ** xpp,size_t nelems,float * tp)16783 ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
16784 {
16785 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16786 
16787  /* basic algorithm is:
16788   *   - ensure sane alignment of input data
16789   *   - copy (conversion happens automatically) input data
16790   *     to output
16791   *   - update xpp to point at next unconverted input, and tp to point
16792   *     at next location for converted output
16793   */
16794   long i, j, ni;
16795   double tmp[LOOPCNT];        /* in case input is misaligned */
16796   double *xp;
16797   int nrange = 0;         /* number of range errors */
16798   int realign = 0;        /* "do we need to fix input data alignment?" */
16799   long cxp = (long) *((char**)xpp);
16800 
16801   realign = (cxp & 7) % SIZEOF_DOUBLE;
16802   /* sjl: manually stripmine so we can limit amount of
16803    * vector work space reserved to LOOPCNT elements. Also
16804    * makes vectorisation easy */
16805   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16806     ni=Min(nelems-j,LOOPCNT);
16807     if (realign) {
16808       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16809       xp = tmp;
16810     } else {
16811       xp = (double *) *xpp;
16812     }
16813    /* copy the next block */
16814 #pragma cdir loopcnt=LOOPCNT
16815 #pragma cdir shortloop
16816     for (i=0; i<ni; i++) {
16817       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
16818      /* test for range errors (not always needed but do it anyway) */
16819      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16820      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16821       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
16822     }
16823    /* update xpp and tp */
16824     if (realign) xp = (double *) *xpp;
16825     xp += ni;
16826     tp += ni;
16827     *xpp = (void*)xp;
16828   }
16829   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16830 
16831 #else   /* not SX */
16832 	const char *xp = (const char *) *xpp;
16833 	int status = NC_NOERR;
16834 
16835 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16836 	{
16837 		const int lstatus = ncx_get_double_float(xp, tp);
16838 		if (status == NC_NOERR) /* report the first encountered error */
16839 			status = lstatus;
16840 	}
16841 
16842 	*xpp = (const void *)xp;
16843 	return status;
16844 #endif
16845 }
16846 
16847 int
ncx_getn_double_longlong(const void ** xpp,size_t nelems,longlong * tp)16848 ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp)
16849 {
16850 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16851 
16852  /* basic algorithm is:
16853   *   - ensure sane alignment of input data
16854   *   - copy (conversion happens automatically) input data
16855   *     to output
16856   *   - update xpp to point at next unconverted input, and tp to point
16857   *     at next location for converted output
16858   */
16859   long i, j, ni;
16860   double tmp[LOOPCNT];        /* in case input is misaligned */
16861   double *xp;
16862   int nrange = 0;         /* number of range errors */
16863   int realign = 0;        /* "do we need to fix input data alignment?" */
16864   long cxp = (long) *((char**)xpp);
16865 
16866   realign = (cxp & 7) % SIZEOF_DOUBLE;
16867   /* sjl: manually stripmine so we can limit amount of
16868    * vector work space reserved to LOOPCNT elements. Also
16869    * makes vectorisation easy */
16870   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16871     ni=Min(nelems-j,LOOPCNT);
16872     if (realign) {
16873       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16874       xp = tmp;
16875     } else {
16876       xp = (double *) *xpp;
16877     }
16878    /* copy the next block */
16879 #pragma cdir loopcnt=LOOPCNT
16880 #pragma cdir shortloop
16881     for (i=0; i<ni; i++) {
16882       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
16883      /* test for range errors (not always needed but do it anyway) */
16884      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16885      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16886       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
16887     }
16888    /* update xpp and tp */
16889     if (realign) xp = (double *) *xpp;
16890     xp += ni;
16891     tp += ni;
16892     *xpp = (void*)xp;
16893   }
16894   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16895 
16896 #else   /* not SX */
16897 	const char *xp = (const char *) *xpp;
16898 	int status = NC_NOERR;
16899 
16900 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16901 	{
16902 		const int lstatus = ncx_get_double_longlong(xp, tp);
16903 		if (status == NC_NOERR) /* report the first encountered error */
16904 			status = lstatus;
16905 	}
16906 
16907 	*xpp = (const void *)xp;
16908 	return status;
16909 #endif
16910 }
16911 
16912 int
ncx_getn_double_uchar(const void ** xpp,size_t nelems,uchar * tp)16913 ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
16914 {
16915 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16916 
16917  /* basic algorithm is:
16918   *   - ensure sane alignment of input data
16919   *   - copy (conversion happens automatically) input data
16920   *     to output
16921   *   - update xpp to point at next unconverted input, and tp to point
16922   *     at next location for converted output
16923   */
16924   long i, j, ni;
16925   double tmp[LOOPCNT];        /* in case input is misaligned */
16926   double *xp;
16927   int nrange = 0;         /* number of range errors */
16928   int realign = 0;        /* "do we need to fix input data alignment?" */
16929   long cxp = (long) *((char**)xpp);
16930 
16931   realign = (cxp & 7) % SIZEOF_DOUBLE;
16932   /* sjl: manually stripmine so we can limit amount of
16933    * vector work space reserved to LOOPCNT elements. Also
16934    * makes vectorisation easy */
16935   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
16936     ni=Min(nelems-j,LOOPCNT);
16937     if (realign) {
16938       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
16939       xp = tmp;
16940     } else {
16941       xp = (double *) *xpp;
16942     }
16943    /* copy the next block */
16944 #pragma cdir loopcnt=LOOPCNT
16945 #pragma cdir shortloop
16946     for (i=0; i<ni; i++) {
16947       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
16948      /* test for range errors (not always needed but do it anyway) */
16949      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
16950      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
16951       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
16952     }
16953    /* update xpp and tp */
16954     if (realign) xp = (double *) *xpp;
16955     xp += ni;
16956     tp += ni;
16957     *xpp = (void*)xp;
16958   }
16959   return nrange == 0 ? NC_NOERR : NC_ERANGE;
16960 
16961 #else   /* not SX */
16962 	const char *xp = (const char *) *xpp;
16963 	int status = NC_NOERR;
16964 
16965 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
16966 	{
16967 		const int lstatus = ncx_get_double_uchar(xp, tp);
16968 		if (status == NC_NOERR) /* report the first encountered error */
16969 			status = lstatus;
16970 	}
16971 
16972 	*xpp = (const void *)xp;
16973 	return status;
16974 #endif
16975 }
16976 
16977 int
ncx_getn_double_ushort(const void ** xpp,size_t nelems,ushort * tp)16978 ncx_getn_double_ushort(const void **xpp, size_t nelems, ushort *tp)
16979 {
16980 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
16981 
16982  /* basic algorithm is:
16983   *   - ensure sane alignment of input data
16984   *   - copy (conversion happens automatically) input data
16985   *     to output
16986   *   - update xpp to point at next unconverted input, and tp to point
16987   *     at next location for converted output
16988   */
16989   long i, j, ni;
16990   double tmp[LOOPCNT];        /* in case input is misaligned */
16991   double *xp;
16992   int nrange = 0;         /* number of range errors */
16993   int realign = 0;        /* "do we need to fix input data alignment?" */
16994   long cxp = (long) *((char**)xpp);
16995 
16996   realign = (cxp & 7) % SIZEOF_DOUBLE;
16997   /* sjl: manually stripmine so we can limit amount of
16998    * vector work space reserved to LOOPCNT elements. Also
16999    * makes vectorisation easy */
17000   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17001     ni=Min(nelems-j,LOOPCNT);
17002     if (realign) {
17003       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17004       xp = tmp;
17005     } else {
17006       xp = (double *) *xpp;
17007     }
17008    /* copy the next block */
17009 #pragma cdir loopcnt=LOOPCNT
17010 #pragma cdir shortloop
17011     for (i=0; i<ni; i++) {
17012       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
17013      /* test for range errors (not always needed but do it anyway) */
17014      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17015      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17016       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
17017     }
17018    /* update xpp and tp */
17019     if (realign) xp = (double *) *xpp;
17020     xp += ni;
17021     tp += ni;
17022     *xpp = (void*)xp;
17023   }
17024   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17025 
17026 #else   /* not SX */
17027 	const char *xp = (const char *) *xpp;
17028 	int status = NC_NOERR;
17029 
17030 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17031 	{
17032 		const int lstatus = ncx_get_double_ushort(xp, tp);
17033 		if (status == NC_NOERR) /* report the first encountered error */
17034 			status = lstatus;
17035 	}
17036 
17037 	*xpp = (const void *)xp;
17038 	return status;
17039 #endif
17040 }
17041 
17042 int
ncx_getn_double_uint(const void ** xpp,size_t nelems,uint * tp)17043 ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp)
17044 {
17045 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17046 
17047  /* basic algorithm is:
17048   *   - ensure sane alignment of input data
17049   *   - copy (conversion happens automatically) input data
17050   *     to output
17051   *   - update xpp to point at next unconverted input, and tp to point
17052   *     at next location for converted output
17053   */
17054   long i, j, ni;
17055   double tmp[LOOPCNT];        /* in case input is misaligned */
17056   double *xp;
17057   int nrange = 0;         /* number of range errors */
17058   int realign = 0;        /* "do we need to fix input data alignment?" */
17059   long cxp = (long) *((char**)xpp);
17060 
17061   realign = (cxp & 7) % SIZEOF_DOUBLE;
17062   /* sjl: manually stripmine so we can limit amount of
17063    * vector work space reserved to LOOPCNT elements. Also
17064    * makes vectorisation easy */
17065   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17066     ni=Min(nelems-j,LOOPCNT);
17067     if (realign) {
17068       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17069       xp = tmp;
17070     } else {
17071       xp = (double *) *xpp;
17072     }
17073    /* copy the next block */
17074 #pragma cdir loopcnt=LOOPCNT
17075 #pragma cdir shortloop
17076     for (i=0; i<ni; i++) {
17077       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
17078      /* test for range errors (not always needed but do it anyway) */
17079      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17080      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17081       nrange += xp[i] > UINT_MAX || xp[i] < 0;
17082     }
17083    /* update xpp and tp */
17084     if (realign) xp = (double *) *xpp;
17085     xp += ni;
17086     tp += ni;
17087     *xpp = (void*)xp;
17088   }
17089   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17090 
17091 #else   /* not SX */
17092 	const char *xp = (const char *) *xpp;
17093 	int status = NC_NOERR;
17094 
17095 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17096 	{
17097 		const int lstatus = ncx_get_double_uint(xp, tp);
17098 		if (status == NC_NOERR) /* report the first encountered error */
17099 			status = lstatus;
17100 	}
17101 
17102 	*xpp = (const void *)xp;
17103 	return status;
17104 #endif
17105 }
17106 
17107 int
ncx_getn_double_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)17108 ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
17109 {
17110 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17111 
17112  /* basic algorithm is:
17113   *   - ensure sane alignment of input data
17114   *   - copy (conversion happens automatically) input data
17115   *     to output
17116   *   - update xpp to point at next unconverted input, and tp to point
17117   *     at next location for converted output
17118   */
17119   long i, j, ni;
17120   double tmp[LOOPCNT];        /* in case input is misaligned */
17121   double *xp;
17122   int nrange = 0;         /* number of range errors */
17123   int realign = 0;        /* "do we need to fix input data alignment?" */
17124   long cxp = (long) *((char**)xpp);
17125 
17126   realign = (cxp & 7) % SIZEOF_DOUBLE;
17127   /* sjl: manually stripmine so we can limit amount of
17128    * vector work space reserved to LOOPCNT elements. Also
17129    * makes vectorisation easy */
17130   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17131     ni=Min(nelems-j,LOOPCNT);
17132     if (realign) {
17133       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
17134       xp = tmp;
17135     } else {
17136       xp = (double *) *xpp;
17137     }
17138    /* copy the next block */
17139 #pragma cdir loopcnt=LOOPCNT
17140 #pragma cdir shortloop
17141     for (i=0; i<ni; i++) {
17142       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
17143      /* test for range errors (not always needed but do it anyway) */
17144      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
17145      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
17146       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
17147     }
17148    /* update xpp and tp */
17149     if (realign) xp = (double *) *xpp;
17150     xp += ni;
17151     tp += ni;
17152     *xpp = (void*)xp;
17153   }
17154   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17155 
17156 #else   /* not SX */
17157 	const char *xp = (const char *) *xpp;
17158 	int status = NC_NOERR;
17159 
17160 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17161 	{
17162 		const int lstatus = ncx_get_double_ulonglong(xp, tp);
17163 		if (status == NC_NOERR) /* report the first encountered error */
17164 			status = lstatus;
17165 	}
17166 
17167 	*xpp = (const void *)xp;
17168 	return status;
17169 #endif
17170 }
17171 
17172 
17173 #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
17174 /* optimized version */
17175 int
ncx_putn_double_double(void ** xpp,size_t nelems,const double * tp,void * fillp)17176 ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17177 {
17178 #ifdef WORDS_BIGENDIAN
17179 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
17180 # else
17181 	swapn8b(*xpp, tp, nelems);
17182 # endif
17183 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
17184 	return NC_NOERR;
17185 }
17186 #elif defined(vax) && vax != 0
17187 int
ncx_putn_double_double(void ** xpp,size_t ndoubles,const double * ip,void * fillp)17188 ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip, void *fillp)
17189 {
17190 	const double *const end = ip + ndoubles;
17191 
17192 	while (ip < end)
17193 	{
17194 	const struct vax_double *const vdp =
17195 			(const struct vax_double *)ip;
17196 	struct ieee_double *const idp =
17197 			 (struct ieee_double *) (*xpp);
17198 
17199 	if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
17200 		(vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
17201 		(vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
17202 		(vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
17203 		(vdp->exp == dbl_limits[0].d.exp))
17204 	{
17205 		*idp = dbl_limits[0].ieee;
17206 		goto shipit;
17207 	}
17208 	if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
17209 		(vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
17210 		(vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
17211 		(vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
17212 		(vdp->exp == dbl_limits[1].d.exp))
17213 	{
17214 		*idp = dbl_limits[1].ieee;
17215 		goto shipit;
17216 	}
17217 
17218 	{
17219 		unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
17220 
17221 		unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
17222 			(vdp->mantissa3 << 13) |
17223 			((vdp->mantissa4 >> 3) & MASK(13));
17224 
17225 		unsigned mant_hi = (vdp->mantissa1 << 13)
17226 				 | (vdp->mantissa2 >> 3);
17227 
17228 		if ((vdp->mantissa4 & 7) > 4)
17229 		{
17230 			/* round up */
17231 			mant_lo++;
17232 			if (mant_lo == 0)
17233 			{
17234 				mant_hi++;
17235 				if (mant_hi > 0xffffff)
17236 				{
17237 					mant_hi = 0;
17238 					exp++;
17239 				}
17240 			}
17241 		}
17242 
17243 		idp->mant_lo = SWAP4(mant_lo);
17244 		idp->mant_6 = mant_hi >> 16;
17245 		idp->mant_5 = (mant_hi & 0xff00) >> 8;
17246 		idp->mant_4 = mant_hi;
17247 		idp->exp_hi = exp >> 4;
17248 		idp->exp_lo = exp;
17249 	}
17250 
17251 	shipit:
17252 		idp->sign = vdp->sign;
17253 
17254 		ip++;
17255 		*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
17256 	}
17257 	return NC_NOERR;
17258 }
17259 	/* vax */
17260 #else
17261 int
ncx_putn_double_double(void ** xpp,size_t nelems,const double * tp,void * fillp)17262 ncx_putn_double_double(void **xpp, size_t nelems, const double *tp, void *fillp)
17263 {
17264 	char *xp = *xpp;
17265 	int status = NC_NOERR;
17266 
17267 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17268 	{
17269 		int lstatus = ncx_put_double_double(xp, tp, fillp);
17270 		if (status == NC_NOERR) /* report the first encountered error */
17271 			status = lstatus;
17272 	}
17273 
17274 	*xpp = (void *)xp;
17275 	return status;
17276 }
17277 #endif
17278 int
ncx_putn_double_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)17279 ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
17280 {
17281 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17282 
17283  /* basic algorithm is:
17284   *   - ensure sane alignment of output data
17285   *   - copy (conversion happens automatically) input data
17286   *     to output
17287   *   - update tp to point at next unconverted input, and xpp to point
17288   *     at next location for converted output
17289   */
17290   long i, j, ni;
17291   double tmp[LOOPCNT];        /* in case input is misaligned */
17292   double *xp;
17293   int nrange = 0;         /* number of range errors */
17294   int realign = 0;        /* "do we need to fix input data alignment?" */
17295   long cxp = (long) *((char**)xpp);
17296 
17297   realign = (cxp & 7) % SIZEOF_DOUBLE;
17298   /* sjl: manually stripmine so we can limit amount of
17299    * vector work space reserved to LOOPCNT elements. Also
17300    * makes vectorisation easy */
17301   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17302     ni=Min(nelems-j,LOOPCNT);
17303     if (realign) {
17304       xp = tmp;
17305     } else {
17306       xp = (double *) *xpp;
17307     }
17308    /* copy the next block */
17309 #pragma cdir loopcnt=LOOPCNT
17310 #pragma cdir shortloop
17311     for (i=0; i<ni; i++) {
17312       /* the normal case: */
17313       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17314      /* test for range errors (not always needed but do it anyway) */
17315      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17316      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17317       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17318     }
17319    /* copy workspace back if necessary */
17320     if (realign) {
17321       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17322       xp = (double *) *xpp;
17323     }
17324    /* update xpp and tp */
17325     xp += ni;
17326     tp += ni;
17327     *xpp = (void*)xp;
17328   }
17329   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17330 
17331 #else   /* not SX */
17332 
17333 	char *xp = (char *) *xpp;
17334 	int status = NC_NOERR;
17335 
17336 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17337 	{
17338 		int lstatus = ncx_put_double_schar(xp, tp, fillp);
17339 		if (status == NC_NOERR) /* report the first encountered error */
17340 			status = lstatus;
17341 	}
17342 
17343 	*xpp = (void *)xp;
17344 	return status;
17345 #endif
17346 }
17347 
17348 int
ncx_putn_double_short(void ** xpp,size_t nelems,const short * tp,void * fillp)17349 ncx_putn_double_short(void **xpp, size_t nelems, const short *tp, void *fillp)
17350 {
17351 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17352 
17353  /* basic algorithm is:
17354   *   - ensure sane alignment of output data
17355   *   - copy (conversion happens automatically) input data
17356   *     to output
17357   *   - update tp to point at next unconverted input, and xpp to point
17358   *     at next location for converted output
17359   */
17360   long i, j, ni;
17361   double tmp[LOOPCNT];        /* in case input is misaligned */
17362   double *xp;
17363   int nrange = 0;         /* number of range errors */
17364   int realign = 0;        /* "do we need to fix input data alignment?" */
17365   long cxp = (long) *((char**)xpp);
17366 
17367   realign = (cxp & 7) % SIZEOF_DOUBLE;
17368   /* sjl: manually stripmine so we can limit amount of
17369    * vector work space reserved to LOOPCNT elements. Also
17370    * makes vectorisation easy */
17371   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17372     ni=Min(nelems-j,LOOPCNT);
17373     if (realign) {
17374       xp = tmp;
17375     } else {
17376       xp = (double *) *xpp;
17377     }
17378    /* copy the next block */
17379 #pragma cdir loopcnt=LOOPCNT
17380 #pragma cdir shortloop
17381     for (i=0; i<ni; i++) {
17382       /* the normal case: */
17383       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17384      /* test for range errors (not always needed but do it anyway) */
17385      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17386      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17387       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17388     }
17389    /* copy workspace back if necessary */
17390     if (realign) {
17391       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17392       xp = (double *) *xpp;
17393     }
17394    /* update xpp and tp */
17395     xp += ni;
17396     tp += ni;
17397     *xpp = (void*)xp;
17398   }
17399   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17400 
17401 #else   /* not SX */
17402 
17403 	char *xp = (char *) *xpp;
17404 	int status = NC_NOERR;
17405 
17406 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17407 	{
17408 		int lstatus = ncx_put_double_short(xp, tp, fillp);
17409 		if (status == NC_NOERR) /* report the first encountered error */
17410 			status = lstatus;
17411 	}
17412 
17413 	*xpp = (void *)xp;
17414 	return status;
17415 #endif
17416 }
17417 
17418 int
ncx_putn_double_int(void ** xpp,size_t nelems,const int * tp,void * fillp)17419 ncx_putn_double_int(void **xpp, size_t nelems, const int *tp, void *fillp)
17420 {
17421 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17422 
17423  /* basic algorithm is:
17424   *   - ensure sane alignment of output data
17425   *   - copy (conversion happens automatically) input data
17426   *     to output
17427   *   - update tp to point at next unconverted input, and xpp to point
17428   *     at next location for converted output
17429   */
17430   long i, j, ni;
17431   double tmp[LOOPCNT];        /* in case input is misaligned */
17432   double *xp;
17433   int nrange = 0;         /* number of range errors */
17434   int realign = 0;        /* "do we need to fix input data alignment?" */
17435   long cxp = (long) *((char**)xpp);
17436 
17437   realign = (cxp & 7) % SIZEOF_DOUBLE;
17438   /* sjl: manually stripmine so we can limit amount of
17439    * vector work space reserved to LOOPCNT elements. Also
17440    * makes vectorisation easy */
17441   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17442     ni=Min(nelems-j,LOOPCNT);
17443     if (realign) {
17444       xp = tmp;
17445     } else {
17446       xp = (double *) *xpp;
17447     }
17448    /* copy the next block */
17449 #pragma cdir loopcnt=LOOPCNT
17450 #pragma cdir shortloop
17451     for (i=0; i<ni; i++) {
17452       /* the normal case: */
17453       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17454      /* test for range errors (not always needed but do it anyway) */
17455      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17456      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17457       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17458     }
17459    /* copy workspace back if necessary */
17460     if (realign) {
17461       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17462       xp = (double *) *xpp;
17463     }
17464    /* update xpp and tp */
17465     xp += ni;
17466     tp += ni;
17467     *xpp = (void*)xp;
17468   }
17469   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17470 
17471 #else   /* not SX */
17472 
17473 	char *xp = (char *) *xpp;
17474 	int status = NC_NOERR;
17475 
17476 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17477 	{
17478 		int lstatus = ncx_put_double_int(xp, tp, fillp);
17479 		if (status == NC_NOERR) /* report the first encountered error */
17480 			status = lstatus;
17481 	}
17482 
17483 	*xpp = (void *)xp;
17484 	return status;
17485 #endif
17486 }
17487 
17488 int
ncx_putn_double_long(void ** xpp,size_t nelems,const long * tp,void * fillp)17489 ncx_putn_double_long(void **xpp, size_t nelems, const long *tp, void *fillp)
17490 {
17491 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17492 
17493  /* basic algorithm is:
17494   *   - ensure sane alignment of output data
17495   *   - copy (conversion happens automatically) input data
17496   *     to output
17497   *   - update tp to point at next unconverted input, and xpp to point
17498   *     at next location for converted output
17499   */
17500   long i, j, ni;
17501   double tmp[LOOPCNT];        /* in case input is misaligned */
17502   double *xp;
17503   int nrange = 0;         /* number of range errors */
17504   int realign = 0;        /* "do we need to fix input data alignment?" */
17505   long cxp = (long) *((char**)xpp);
17506 
17507   realign = (cxp & 7) % SIZEOF_DOUBLE;
17508   /* sjl: manually stripmine so we can limit amount of
17509    * vector work space reserved to LOOPCNT elements. Also
17510    * makes vectorisation easy */
17511   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17512     ni=Min(nelems-j,LOOPCNT);
17513     if (realign) {
17514       xp = tmp;
17515     } else {
17516       xp = (double *) *xpp;
17517     }
17518    /* copy the next block */
17519 #pragma cdir loopcnt=LOOPCNT
17520 #pragma cdir shortloop
17521     for (i=0; i<ni; i++) {
17522       /* the normal case: */
17523       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17524      /* test for range errors (not always needed but do it anyway) */
17525      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17526      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17527       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17528     }
17529    /* copy workspace back if necessary */
17530     if (realign) {
17531       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17532       xp = (double *) *xpp;
17533     }
17534    /* update xpp and tp */
17535     xp += ni;
17536     tp += ni;
17537     *xpp = (void*)xp;
17538   }
17539   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17540 
17541 #else   /* not SX */
17542 
17543 	char *xp = (char *) *xpp;
17544 	int status = NC_NOERR;
17545 
17546 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17547 	{
17548 		int lstatus = ncx_put_double_long(xp, tp, fillp);
17549 		if (status == NC_NOERR) /* report the first encountered error */
17550 			status = lstatus;
17551 	}
17552 
17553 	*xpp = (void *)xp;
17554 	return status;
17555 #endif
17556 }
17557 
17558 int
ncx_putn_double_float(void ** xpp,size_t nelems,const float * tp,void * fillp)17559 ncx_putn_double_float(void **xpp, size_t nelems, const float *tp, void *fillp)
17560 {
17561 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17562 
17563  /* basic algorithm is:
17564   *   - ensure sane alignment of output data
17565   *   - copy (conversion happens automatically) input data
17566   *     to output
17567   *   - update tp to point at next unconverted input, and xpp to point
17568   *     at next location for converted output
17569   */
17570   long i, j, ni;
17571   double tmp[LOOPCNT];        /* in case input is misaligned */
17572   double *xp;
17573   int nrange = 0;         /* number of range errors */
17574   int realign = 0;        /* "do we need to fix input data alignment?" */
17575   long cxp = (long) *((char**)xpp);
17576 
17577   realign = (cxp & 7) % SIZEOF_DOUBLE;
17578   /* sjl: manually stripmine so we can limit amount of
17579    * vector work space reserved to LOOPCNT elements. Also
17580    * makes vectorisation easy */
17581   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17582     ni=Min(nelems-j,LOOPCNT);
17583     if (realign) {
17584       xp = tmp;
17585     } else {
17586       xp = (double *) *xpp;
17587     }
17588    /* copy the next block */
17589 #pragma cdir loopcnt=LOOPCNT
17590 #pragma cdir shortloop
17591     for (i=0; i<ni; i++) {
17592       /* the normal case: */
17593       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17594      /* test for range errors (not always needed but do it anyway) */
17595      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17596      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17597       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17598     }
17599    /* copy workspace back if necessary */
17600     if (realign) {
17601       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17602       xp = (double *) *xpp;
17603     }
17604    /* update xpp and tp */
17605     xp += ni;
17606     tp += ni;
17607     *xpp = (void*)xp;
17608   }
17609   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17610 
17611 #else   /* not SX */
17612 
17613 	char *xp = (char *) *xpp;
17614 	int status = NC_NOERR;
17615 
17616 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17617 	{
17618 		int lstatus = ncx_put_double_float(xp, tp, fillp);
17619 		if (status == NC_NOERR) /* report the first encountered error */
17620 			status = lstatus;
17621 	}
17622 
17623 	*xpp = (void *)xp;
17624 	return status;
17625 #endif
17626 }
17627 
17628 int
ncx_putn_double_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)17629 ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
17630 {
17631 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17632 
17633  /* basic algorithm is:
17634   *   - ensure sane alignment of output data
17635   *   - copy (conversion happens automatically) input data
17636   *     to output
17637   *   - update tp to point at next unconverted input, and xpp to point
17638   *     at next location for converted output
17639   */
17640   long i, j, ni;
17641   double tmp[LOOPCNT];        /* in case input is misaligned */
17642   double *xp;
17643   int nrange = 0;         /* number of range errors */
17644   int realign = 0;        /* "do we need to fix input data alignment?" */
17645   long cxp = (long) *((char**)xpp);
17646 
17647   realign = (cxp & 7) % SIZEOF_DOUBLE;
17648   /* sjl: manually stripmine so we can limit amount of
17649    * vector work space reserved to LOOPCNT elements. Also
17650    * makes vectorisation easy */
17651   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17652     ni=Min(nelems-j,LOOPCNT);
17653     if (realign) {
17654       xp = tmp;
17655     } else {
17656       xp = (double *) *xpp;
17657     }
17658    /* copy the next block */
17659 #pragma cdir loopcnt=LOOPCNT
17660 #pragma cdir shortloop
17661     for (i=0; i<ni; i++) {
17662       /* the normal case: */
17663       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17664      /* test for range errors (not always needed but do it anyway) */
17665      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17666      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17667       nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
17668     }
17669    /* copy workspace back if necessary */
17670     if (realign) {
17671       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17672       xp = (double *) *xpp;
17673     }
17674    /* update xpp and tp */
17675     xp += ni;
17676     tp += ni;
17677     *xpp = (void*)xp;
17678   }
17679   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17680 
17681 #else   /* not SX */
17682 
17683 	char *xp = (char *) *xpp;
17684 	int status = NC_NOERR;
17685 
17686 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17687 	{
17688 		int lstatus = ncx_put_double_longlong(xp, tp, fillp);
17689 		if (status == NC_NOERR) /* report the first encountered error */
17690 			status = lstatus;
17691 	}
17692 
17693 	*xpp = (void *)xp;
17694 	return status;
17695 #endif
17696 }
17697 
17698 int
ncx_putn_double_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)17699 ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
17700 {
17701 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17702 
17703  /* basic algorithm is:
17704   *   - ensure sane alignment of output data
17705   *   - copy (conversion happens automatically) input data
17706   *     to output
17707   *   - update tp to point at next unconverted input, and xpp to point
17708   *     at next location for converted output
17709   */
17710   long i, j, ni;
17711   double tmp[LOOPCNT];        /* in case input is misaligned */
17712   double *xp;
17713   int nrange = 0;         /* number of range errors */
17714   int realign = 0;        /* "do we need to fix input data alignment?" */
17715   long cxp = (long) *((char**)xpp);
17716 
17717   realign = (cxp & 7) % SIZEOF_DOUBLE;
17718   /* sjl: manually stripmine so we can limit amount of
17719    * vector work space reserved to LOOPCNT elements. Also
17720    * makes vectorisation easy */
17721   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17722     ni=Min(nelems-j,LOOPCNT);
17723     if (realign) {
17724       xp = tmp;
17725     } else {
17726       xp = (double *) *xpp;
17727     }
17728    /* copy the next block */
17729 #pragma cdir loopcnt=LOOPCNT
17730 #pragma cdir shortloop
17731     for (i=0; i<ni; i++) {
17732       /* the normal case: */
17733       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17734      /* test for range errors (not always needed but do it anyway) */
17735      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17736      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17737       nrange += tp[i] > X_DOUBLE_MAX ;
17738     }
17739    /* copy workspace back if necessary */
17740     if (realign) {
17741       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17742       xp = (double *) *xpp;
17743     }
17744    /* update xpp and tp */
17745     xp += ni;
17746     tp += ni;
17747     *xpp = (void*)xp;
17748   }
17749   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17750 
17751 #else   /* not SX */
17752 
17753 	char *xp = (char *) *xpp;
17754 	int status = NC_NOERR;
17755 
17756 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17757 	{
17758 		int lstatus = ncx_put_double_uchar(xp, tp, fillp);
17759 		if (status == NC_NOERR) /* report the first encountered error */
17760 			status = lstatus;
17761 	}
17762 
17763 	*xpp = (void *)xp;
17764 	return status;
17765 #endif
17766 }
17767 
17768 int
ncx_putn_double_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)17769 ncx_putn_double_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
17770 {
17771 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17772 
17773  /* basic algorithm is:
17774   *   - ensure sane alignment of output data
17775   *   - copy (conversion happens automatically) input data
17776   *     to output
17777   *   - update tp to point at next unconverted input, and xpp to point
17778   *     at next location for converted output
17779   */
17780   long i, j, ni;
17781   double tmp[LOOPCNT];        /* in case input is misaligned */
17782   double *xp;
17783   int nrange = 0;         /* number of range errors */
17784   int realign = 0;        /* "do we need to fix input data alignment?" */
17785   long cxp = (long) *((char**)xpp);
17786 
17787   realign = (cxp & 7) % SIZEOF_DOUBLE;
17788   /* sjl: manually stripmine so we can limit amount of
17789    * vector work space reserved to LOOPCNT elements. Also
17790    * makes vectorisation easy */
17791   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17792     ni=Min(nelems-j,LOOPCNT);
17793     if (realign) {
17794       xp = tmp;
17795     } else {
17796       xp = (double *) *xpp;
17797     }
17798    /* copy the next block */
17799 #pragma cdir loopcnt=LOOPCNT
17800 #pragma cdir shortloop
17801     for (i=0; i<ni; i++) {
17802       /* the normal case: */
17803       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17804      /* test for range errors (not always needed but do it anyway) */
17805      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17806      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17807       nrange += tp[i] > X_DOUBLE_MAX ;
17808     }
17809    /* copy workspace back if necessary */
17810     if (realign) {
17811       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17812       xp = (double *) *xpp;
17813     }
17814    /* update xpp and tp */
17815     xp += ni;
17816     tp += ni;
17817     *xpp = (void*)xp;
17818   }
17819   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17820 
17821 #else   /* not SX */
17822 
17823 	char *xp = (char *) *xpp;
17824 	int status = NC_NOERR;
17825 
17826 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17827 	{
17828 		int lstatus = ncx_put_double_ushort(xp, tp, fillp);
17829 		if (status == NC_NOERR) /* report the first encountered error */
17830 			status = lstatus;
17831 	}
17832 
17833 	*xpp = (void *)xp;
17834 	return status;
17835 #endif
17836 }
17837 
17838 int
ncx_putn_double_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)17839 ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
17840 {
17841 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17842 
17843  /* basic algorithm is:
17844   *   - ensure sane alignment of output data
17845   *   - copy (conversion happens automatically) input data
17846   *     to output
17847   *   - update tp to point at next unconverted input, and xpp to point
17848   *     at next location for converted output
17849   */
17850   long i, j, ni;
17851   double tmp[LOOPCNT];        /* in case input is misaligned */
17852   double *xp;
17853   int nrange = 0;         /* number of range errors */
17854   int realign = 0;        /* "do we need to fix input data alignment?" */
17855   long cxp = (long) *((char**)xpp);
17856 
17857   realign = (cxp & 7) % SIZEOF_DOUBLE;
17858   /* sjl: manually stripmine so we can limit amount of
17859    * vector work space reserved to LOOPCNT elements. Also
17860    * makes vectorisation easy */
17861   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17862     ni=Min(nelems-j,LOOPCNT);
17863     if (realign) {
17864       xp = tmp;
17865     } else {
17866       xp = (double *) *xpp;
17867     }
17868    /* copy the next block */
17869 #pragma cdir loopcnt=LOOPCNT
17870 #pragma cdir shortloop
17871     for (i=0; i<ni; i++) {
17872       /* the normal case: */
17873       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17874      /* test for range errors (not always needed but do it anyway) */
17875      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17876      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17877       nrange += tp[i] > X_DOUBLE_MAX ;
17878     }
17879    /* copy workspace back if necessary */
17880     if (realign) {
17881       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17882       xp = (double *) *xpp;
17883     }
17884    /* update xpp and tp */
17885     xp += ni;
17886     tp += ni;
17887     *xpp = (void*)xp;
17888   }
17889   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17890 
17891 #else   /* not SX */
17892 
17893 	char *xp = (char *) *xpp;
17894 	int status = NC_NOERR;
17895 
17896 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17897 	{
17898 		int lstatus = ncx_put_double_uint(xp, tp, fillp);
17899 		if (status == NC_NOERR) /* report the first encountered error */
17900 			status = lstatus;
17901 	}
17902 
17903 	*xpp = (void *)xp;
17904 	return status;
17905 #endif
17906 }
17907 
17908 int
ncx_putn_double_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)17909 ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
17910 {
17911 #if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE
17912 
17913  /* basic algorithm is:
17914   *   - ensure sane alignment of output data
17915   *   - copy (conversion happens automatically) input data
17916   *     to output
17917   *   - update tp to point at next unconverted input, and xpp to point
17918   *     at next location for converted output
17919   */
17920   long i, j, ni;
17921   double tmp[LOOPCNT];        /* in case input is misaligned */
17922   double *xp;
17923   int nrange = 0;         /* number of range errors */
17924   int realign = 0;        /* "do we need to fix input data alignment?" */
17925   long cxp = (long) *((char**)xpp);
17926 
17927   realign = (cxp & 7) % SIZEOF_DOUBLE;
17928   /* sjl: manually stripmine so we can limit amount of
17929    * vector work space reserved to LOOPCNT elements. Also
17930    * makes vectorisation easy */
17931   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
17932     ni=Min(nelems-j,LOOPCNT);
17933     if (realign) {
17934       xp = tmp;
17935     } else {
17936       xp = (double *) *xpp;
17937     }
17938    /* copy the next block */
17939 #pragma cdir loopcnt=LOOPCNT
17940 #pragma cdir shortloop
17941     for (i=0; i<ni; i++) {
17942       /* the normal case: */
17943       xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
17944      /* test for range errors (not always needed but do it anyway) */
17945      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
17946      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
17947       nrange += tp[i] > X_DOUBLE_MAX ;
17948     }
17949    /* copy workspace back if necessary */
17950     if (realign) {
17951       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
17952       xp = (double *) *xpp;
17953     }
17954    /* update xpp and tp */
17955     xp += ni;
17956     tp += ni;
17957     *xpp = (void*)xp;
17958   }
17959   return nrange == 0 ? NC_NOERR : NC_ERANGE;
17960 
17961 #else   /* not SX */
17962 
17963 	char *xp = (char *) *xpp;
17964 	int status = NC_NOERR;
17965 
17966 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
17967 	{
17968 		int lstatus = ncx_put_double_ulonglong(xp, tp, fillp);
17969 		if (status == NC_NOERR) /* report the first encountered error */
17970 			status = lstatus;
17971 	}
17972 
17973 	*xpp = (void *)xp;
17974 	return status;
17975 #endif
17976 }
17977 
17978 
17979 
17980 /* longlong ------------------------------------------------------------------*/
17981 
17982 #if X_SIZEOF_INT64 == SIZEOF_LONGLONG
17983 /* optimized version */
17984 int
ncx_getn_longlong_longlong(const void ** xpp,size_t nelems,long long * tp)17985 ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
17986 {
17987 #ifdef WORDS_BIGENDIAN
17988 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
17989 # else
17990 	swapn8b(tp, *xpp, nelems);
17991 # endif
17992 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
17993 	return NC_NOERR;
17994 }
17995 #else
17996 int
ncx_getn_longlong_longlong(const void ** xpp,size_t nelems,longlong * tp)17997 ncx_getn_longlong_longlong(const void **xpp, size_t nelems, longlong *tp)
17998 {
17999 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18000 
18001  /* basic algorithm is:
18002   *   - ensure sane alignment of input data
18003   *   - copy (conversion happens automatically) input data
18004   *     to output
18005   *   - update xpp to point at next unconverted input, and tp to point
18006   *     at next location for converted output
18007   */
18008   long i, j, ni;
18009   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18010   int64 *xp;
18011   int nrange = 0;         /* number of range errors */
18012   int realign = 0;        /* "do we need to fix input data alignment?" */
18013   long cxp = (long) *((char**)xpp);
18014 
18015   realign = (cxp & 7) % SIZEOF_INT64;
18016   /* sjl: manually stripmine so we can limit amount of
18017    * vector work space reserved to LOOPCNT elements. Also
18018    * makes vectorisation easy */
18019   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18020     ni=Min(nelems-j,LOOPCNT);
18021     if (realign) {
18022       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18023       xp = tmp;
18024     } else {
18025       xp = (int64 *) *xpp;
18026     }
18027    /* copy the next block */
18028 #pragma cdir loopcnt=LOOPCNT
18029 #pragma cdir shortloop
18030     for (i=0; i<ni; i++) {
18031       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
18032      /* test for range errors (not always needed but do it anyway) */
18033      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18034      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18035       nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
18036     }
18037    /* update xpp and tp */
18038     if (realign) xp = (int64 *) *xpp;
18039     xp += ni;
18040     tp += ni;
18041     *xpp = (void*)xp;
18042   }
18043   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18044 
18045 #else   /* not SX */
18046 	const char *xp = (const char *) *xpp;
18047 	int status = NC_NOERR;
18048 
18049 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18050 	{
18051 		const int lstatus = ncx_get_longlong_longlong(xp, tp);
18052 		if (status == NC_NOERR) /* report the first encountered error */
18053 			status = lstatus;
18054 	}
18055 
18056 	*xpp = (const void *)xp;
18057 	return status;
18058 #endif
18059 }
18060 
18061 #endif
18062 int
ncx_getn_longlong_schar(const void ** xpp,size_t nelems,schar * tp)18063 ncx_getn_longlong_schar(const void **xpp, size_t nelems, schar *tp)
18064 {
18065 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18066 
18067  /* basic algorithm is:
18068   *   - ensure sane alignment of input data
18069   *   - copy (conversion happens automatically) input data
18070   *     to output
18071   *   - update xpp to point at next unconverted input, and tp to point
18072   *     at next location for converted output
18073   */
18074   long i, j, ni;
18075   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18076   int64 *xp;
18077   int nrange = 0;         /* number of range errors */
18078   int realign = 0;        /* "do we need to fix input data alignment?" */
18079   long cxp = (long) *((char**)xpp);
18080 
18081   realign = (cxp & 7) % SIZEOF_INT64;
18082   /* sjl: manually stripmine so we can limit amount of
18083    * vector work space reserved to LOOPCNT elements. Also
18084    * makes vectorisation easy */
18085   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18086     ni=Min(nelems-j,LOOPCNT);
18087     if (realign) {
18088       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18089       xp = tmp;
18090     } else {
18091       xp = (int64 *) *xpp;
18092     }
18093    /* copy the next block */
18094 #pragma cdir loopcnt=LOOPCNT
18095 #pragma cdir shortloop
18096     for (i=0; i<ni; i++) {
18097       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
18098      /* test for range errors (not always needed but do it anyway) */
18099      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18100      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18101       nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
18102     }
18103    /* update xpp and tp */
18104     if (realign) xp = (int64 *) *xpp;
18105     xp += ni;
18106     tp += ni;
18107     *xpp = (void*)xp;
18108   }
18109   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18110 
18111 #else   /* not SX */
18112 	const char *xp = (const char *) *xpp;
18113 	int status = NC_NOERR;
18114 
18115 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18116 	{
18117 		const int lstatus = ncx_get_longlong_schar(xp, tp);
18118 		if (status == NC_NOERR) /* report the first encountered error */
18119 			status = lstatus;
18120 	}
18121 
18122 	*xpp = (const void *)xp;
18123 	return status;
18124 #endif
18125 }
18126 
18127 int
ncx_getn_longlong_short(const void ** xpp,size_t nelems,short * tp)18128 ncx_getn_longlong_short(const void **xpp, size_t nelems, short *tp)
18129 {
18130 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18131 
18132  /* basic algorithm is:
18133   *   - ensure sane alignment of input data
18134   *   - copy (conversion happens automatically) input data
18135   *     to output
18136   *   - update xpp to point at next unconverted input, and tp to point
18137   *     at next location for converted output
18138   */
18139   long i, j, ni;
18140   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18141   int64 *xp;
18142   int nrange = 0;         /* number of range errors */
18143   int realign = 0;        /* "do we need to fix input data alignment?" */
18144   long cxp = (long) *((char**)xpp);
18145 
18146   realign = (cxp & 7) % SIZEOF_INT64;
18147   /* sjl: manually stripmine so we can limit amount of
18148    * vector work space reserved to LOOPCNT elements. Also
18149    * makes vectorisation easy */
18150   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18151     ni=Min(nelems-j,LOOPCNT);
18152     if (realign) {
18153       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18154       xp = tmp;
18155     } else {
18156       xp = (int64 *) *xpp;
18157     }
18158    /* copy the next block */
18159 #pragma cdir loopcnt=LOOPCNT
18160 #pragma cdir shortloop
18161     for (i=0; i<ni; i++) {
18162       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
18163      /* test for range errors (not always needed but do it anyway) */
18164      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18165      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18166       nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
18167     }
18168    /* update xpp and tp */
18169     if (realign) xp = (int64 *) *xpp;
18170     xp += ni;
18171     tp += ni;
18172     *xpp = (void*)xp;
18173   }
18174   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18175 
18176 #else   /* not SX */
18177 	const char *xp = (const char *) *xpp;
18178 	int status = NC_NOERR;
18179 
18180 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18181 	{
18182 		const int lstatus = ncx_get_longlong_short(xp, tp);
18183 		if (status == NC_NOERR) /* report the first encountered error */
18184 			status = lstatus;
18185 	}
18186 
18187 	*xpp = (const void *)xp;
18188 	return status;
18189 #endif
18190 }
18191 
18192 int
ncx_getn_longlong_int(const void ** xpp,size_t nelems,int * tp)18193 ncx_getn_longlong_int(const void **xpp, size_t nelems, int *tp)
18194 {
18195 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18196 
18197  /* basic algorithm is:
18198   *   - ensure sane alignment of input data
18199   *   - copy (conversion happens automatically) input data
18200   *     to output
18201   *   - update xpp to point at next unconverted input, and tp to point
18202   *     at next location for converted output
18203   */
18204   long i, j, ni;
18205   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18206   int64 *xp;
18207   int nrange = 0;         /* number of range errors */
18208   int realign = 0;        /* "do we need to fix input data alignment?" */
18209   long cxp = (long) *((char**)xpp);
18210 
18211   realign = (cxp & 7) % SIZEOF_INT64;
18212   /* sjl: manually stripmine so we can limit amount of
18213    * vector work space reserved to LOOPCNT elements. Also
18214    * makes vectorisation easy */
18215   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18216     ni=Min(nelems-j,LOOPCNT);
18217     if (realign) {
18218       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18219       xp = tmp;
18220     } else {
18221       xp = (int64 *) *xpp;
18222     }
18223    /* copy the next block */
18224 #pragma cdir loopcnt=LOOPCNT
18225 #pragma cdir shortloop
18226     for (i=0; i<ni; i++) {
18227       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
18228      /* test for range errors (not always needed but do it anyway) */
18229      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18230      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18231       nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
18232     }
18233    /* update xpp and tp */
18234     if (realign) xp = (int64 *) *xpp;
18235     xp += ni;
18236     tp += ni;
18237     *xpp = (void*)xp;
18238   }
18239   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18240 
18241 #else   /* not SX */
18242 	const char *xp = (const char *) *xpp;
18243 	int status = NC_NOERR;
18244 
18245 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18246 	{
18247 		const int lstatus = ncx_get_longlong_int(xp, tp);
18248 		if (status == NC_NOERR) /* report the first encountered error */
18249 			status = lstatus;
18250 	}
18251 
18252 	*xpp = (const void *)xp;
18253 	return status;
18254 #endif
18255 }
18256 
18257 int
ncx_getn_longlong_long(const void ** xpp,size_t nelems,long * tp)18258 ncx_getn_longlong_long(const void **xpp, size_t nelems, long *tp)
18259 {
18260 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18261 
18262  /* basic algorithm is:
18263   *   - ensure sane alignment of input data
18264   *   - copy (conversion happens automatically) input data
18265   *     to output
18266   *   - update xpp to point at next unconverted input, and tp to point
18267   *     at next location for converted output
18268   */
18269   long i, j, ni;
18270   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18271   int64 *xp;
18272   int nrange = 0;         /* number of range errors */
18273   int realign = 0;        /* "do we need to fix input data alignment?" */
18274   long cxp = (long) *((char**)xpp);
18275 
18276   realign = (cxp & 7) % SIZEOF_INT64;
18277   /* sjl: manually stripmine so we can limit amount of
18278    * vector work space reserved to LOOPCNT elements. Also
18279    * makes vectorisation easy */
18280   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18281     ni=Min(nelems-j,LOOPCNT);
18282     if (realign) {
18283       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18284       xp = tmp;
18285     } else {
18286       xp = (int64 *) *xpp;
18287     }
18288    /* copy the next block */
18289 #pragma cdir loopcnt=LOOPCNT
18290 #pragma cdir shortloop
18291     for (i=0; i<ni; i++) {
18292       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
18293      /* test for range errors (not always needed but do it anyway) */
18294      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18295      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18296       nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
18297     }
18298    /* update xpp and tp */
18299     if (realign) xp = (int64 *) *xpp;
18300     xp += ni;
18301     tp += ni;
18302     *xpp = (void*)xp;
18303   }
18304   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18305 
18306 #else   /* not SX */
18307 	const char *xp = (const char *) *xpp;
18308 	int status = NC_NOERR;
18309 
18310 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18311 	{
18312 		const int lstatus = ncx_get_longlong_long(xp, tp);
18313 		if (status == NC_NOERR) /* report the first encountered error */
18314 			status = lstatus;
18315 	}
18316 
18317 	*xpp = (const void *)xp;
18318 	return status;
18319 #endif
18320 }
18321 
18322 int
ncx_getn_longlong_float(const void ** xpp,size_t nelems,float * tp)18323 ncx_getn_longlong_float(const void **xpp, size_t nelems, float *tp)
18324 {
18325 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18326 
18327  /* basic algorithm is:
18328   *   - ensure sane alignment of input data
18329   *   - copy (conversion happens automatically) input data
18330   *     to output
18331   *   - update xpp to point at next unconverted input, and tp to point
18332   *     at next location for converted output
18333   */
18334   long i, j, ni;
18335   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18336   int64 *xp;
18337   int nrange = 0;         /* number of range errors */
18338   int realign = 0;        /* "do we need to fix input data alignment?" */
18339   long cxp = (long) *((char**)xpp);
18340 
18341   realign = (cxp & 7) % SIZEOF_INT64;
18342   /* sjl: manually stripmine so we can limit amount of
18343    * vector work space reserved to LOOPCNT elements. Also
18344    * makes vectorisation easy */
18345   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18346     ni=Min(nelems-j,LOOPCNT);
18347     if (realign) {
18348       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18349       xp = tmp;
18350     } else {
18351       xp = (int64 *) *xpp;
18352     }
18353    /* copy the next block */
18354 #pragma cdir loopcnt=LOOPCNT
18355 #pragma cdir shortloop
18356     for (i=0; i<ni; i++) {
18357       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
18358      /* test for range errors (not always needed but do it anyway) */
18359      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18360      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18361       nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
18362     }
18363    /* update xpp and tp */
18364     if (realign) xp = (int64 *) *xpp;
18365     xp += ni;
18366     tp += ni;
18367     *xpp = (void*)xp;
18368   }
18369   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18370 
18371 #else   /* not SX */
18372 	const char *xp = (const char *) *xpp;
18373 	int status = NC_NOERR;
18374 
18375 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18376 	{
18377 		const int lstatus = ncx_get_longlong_float(xp, tp);
18378 		if (status == NC_NOERR) /* report the first encountered error */
18379 			status = lstatus;
18380 	}
18381 
18382 	*xpp = (const void *)xp;
18383 	return status;
18384 #endif
18385 }
18386 
18387 int
ncx_getn_longlong_double(const void ** xpp,size_t nelems,double * tp)18388 ncx_getn_longlong_double(const void **xpp, size_t nelems, double *tp)
18389 {
18390 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18391 
18392  /* basic algorithm is:
18393   *   - ensure sane alignment of input data
18394   *   - copy (conversion happens automatically) input data
18395   *     to output
18396   *   - update xpp to point at next unconverted input, and tp to point
18397   *     at next location for converted output
18398   */
18399   long i, j, ni;
18400   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18401   int64 *xp;
18402   int nrange = 0;         /* number of range errors */
18403   int realign = 0;        /* "do we need to fix input data alignment?" */
18404   long cxp = (long) *((char**)xpp);
18405 
18406   realign = (cxp & 7) % SIZEOF_INT64;
18407   /* sjl: manually stripmine so we can limit amount of
18408    * vector work space reserved to LOOPCNT elements. Also
18409    * makes vectorisation easy */
18410   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18411     ni=Min(nelems-j,LOOPCNT);
18412     if (realign) {
18413       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18414       xp = tmp;
18415     } else {
18416       xp = (int64 *) *xpp;
18417     }
18418    /* copy the next block */
18419 #pragma cdir loopcnt=LOOPCNT
18420 #pragma cdir shortloop
18421     for (i=0; i<ni; i++) {
18422       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
18423      /* test for range errors (not always needed but do it anyway) */
18424      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18425      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18426       nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
18427     }
18428    /* update xpp and tp */
18429     if (realign) xp = (int64 *) *xpp;
18430     xp += ni;
18431     tp += ni;
18432     *xpp = (void*)xp;
18433   }
18434   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18435 
18436 #else   /* not SX */
18437 	const char *xp = (const char *) *xpp;
18438 	int status = NC_NOERR;
18439 
18440 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18441 	{
18442 		const int lstatus = ncx_get_longlong_double(xp, tp);
18443 		if (status == NC_NOERR) /* report the first encountered error */
18444 			status = lstatus;
18445 	}
18446 
18447 	*xpp = (const void *)xp;
18448 	return status;
18449 #endif
18450 }
18451 
18452 int
ncx_getn_longlong_uchar(const void ** xpp,size_t nelems,uchar * tp)18453 ncx_getn_longlong_uchar(const void **xpp, size_t nelems, uchar *tp)
18454 {
18455 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18456 
18457  /* basic algorithm is:
18458   *   - ensure sane alignment of input data
18459   *   - copy (conversion happens automatically) input data
18460   *     to output
18461   *   - update xpp to point at next unconverted input, and tp to point
18462   *     at next location for converted output
18463   */
18464   long i, j, ni;
18465   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18466   int64 *xp;
18467   int nrange = 0;         /* number of range errors */
18468   int realign = 0;        /* "do we need to fix input data alignment?" */
18469   long cxp = (long) *((char**)xpp);
18470 
18471   realign = (cxp & 7) % SIZEOF_INT64;
18472   /* sjl: manually stripmine so we can limit amount of
18473    * vector work space reserved to LOOPCNT elements. Also
18474    * makes vectorisation easy */
18475   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18476     ni=Min(nelems-j,LOOPCNT);
18477     if (realign) {
18478       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18479       xp = tmp;
18480     } else {
18481       xp = (int64 *) *xpp;
18482     }
18483    /* copy the next block */
18484 #pragma cdir loopcnt=LOOPCNT
18485 #pragma cdir shortloop
18486     for (i=0; i<ni; i++) {
18487       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
18488      /* test for range errors (not always needed but do it anyway) */
18489      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18490      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18491       nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
18492     }
18493    /* update xpp and tp */
18494     if (realign) xp = (int64 *) *xpp;
18495     xp += ni;
18496     tp += ni;
18497     *xpp = (void*)xp;
18498   }
18499   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18500 
18501 #else   /* not SX */
18502 	const char *xp = (const char *) *xpp;
18503 	int status = NC_NOERR;
18504 
18505 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18506 	{
18507 		const int lstatus = ncx_get_longlong_uchar(xp, tp);
18508 		if (status == NC_NOERR) /* report the first encountered error */
18509 			status = lstatus;
18510 	}
18511 
18512 	*xpp = (const void *)xp;
18513 	return status;
18514 #endif
18515 }
18516 
18517 int
ncx_getn_longlong_ushort(const void ** xpp,size_t nelems,ushort * tp)18518 ncx_getn_longlong_ushort(const void **xpp, size_t nelems, ushort *tp)
18519 {
18520 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18521 
18522  /* basic algorithm is:
18523   *   - ensure sane alignment of input data
18524   *   - copy (conversion happens automatically) input data
18525   *     to output
18526   *   - update xpp to point at next unconverted input, and tp to point
18527   *     at next location for converted output
18528   */
18529   long i, j, ni;
18530   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18531   int64 *xp;
18532   int nrange = 0;         /* number of range errors */
18533   int realign = 0;        /* "do we need to fix input data alignment?" */
18534   long cxp = (long) *((char**)xpp);
18535 
18536   realign = (cxp & 7) % SIZEOF_INT64;
18537   /* sjl: manually stripmine so we can limit amount of
18538    * vector work space reserved to LOOPCNT elements. Also
18539    * makes vectorisation easy */
18540   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18541     ni=Min(nelems-j,LOOPCNT);
18542     if (realign) {
18543       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18544       xp = tmp;
18545     } else {
18546       xp = (int64 *) *xpp;
18547     }
18548    /* copy the next block */
18549 #pragma cdir loopcnt=LOOPCNT
18550 #pragma cdir shortloop
18551     for (i=0; i<ni; i++) {
18552       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
18553      /* test for range errors (not always needed but do it anyway) */
18554      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18555      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18556       nrange += xp[i] > USHORT_MAX || xp[i] < 0;
18557     }
18558    /* update xpp and tp */
18559     if (realign) xp = (int64 *) *xpp;
18560     xp += ni;
18561     tp += ni;
18562     *xpp = (void*)xp;
18563   }
18564   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18565 
18566 #else   /* not SX */
18567 	const char *xp = (const char *) *xpp;
18568 	int status = NC_NOERR;
18569 
18570 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18571 	{
18572 		const int lstatus = ncx_get_longlong_ushort(xp, tp);
18573 		if (status == NC_NOERR) /* report the first encountered error */
18574 			status = lstatus;
18575 	}
18576 
18577 	*xpp = (const void *)xp;
18578 	return status;
18579 #endif
18580 }
18581 
18582 int
ncx_getn_longlong_uint(const void ** xpp,size_t nelems,uint * tp)18583 ncx_getn_longlong_uint(const void **xpp, size_t nelems, uint *tp)
18584 {
18585 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18586 
18587  /* basic algorithm is:
18588   *   - ensure sane alignment of input data
18589   *   - copy (conversion happens automatically) input data
18590   *     to output
18591   *   - update xpp to point at next unconverted input, and tp to point
18592   *     at next location for converted output
18593   */
18594   long i, j, ni;
18595   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18596   int64 *xp;
18597   int nrange = 0;         /* number of range errors */
18598   int realign = 0;        /* "do we need to fix input data alignment?" */
18599   long cxp = (long) *((char**)xpp);
18600 
18601   realign = (cxp & 7) % SIZEOF_INT64;
18602   /* sjl: manually stripmine so we can limit amount of
18603    * vector work space reserved to LOOPCNT elements. Also
18604    * makes vectorisation easy */
18605   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18606     ni=Min(nelems-j,LOOPCNT);
18607     if (realign) {
18608       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18609       xp = tmp;
18610     } else {
18611       xp = (int64 *) *xpp;
18612     }
18613    /* copy the next block */
18614 #pragma cdir loopcnt=LOOPCNT
18615 #pragma cdir shortloop
18616     for (i=0; i<ni; i++) {
18617       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
18618      /* test for range errors (not always needed but do it anyway) */
18619      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18620      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18621       nrange += xp[i] > UINT_MAX || xp[i] < 0;
18622     }
18623    /* update xpp and tp */
18624     if (realign) xp = (int64 *) *xpp;
18625     xp += ni;
18626     tp += ni;
18627     *xpp = (void*)xp;
18628   }
18629   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18630 
18631 #else   /* not SX */
18632 	const char *xp = (const char *) *xpp;
18633 	int status = NC_NOERR;
18634 
18635 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18636 	{
18637 		const int lstatus = ncx_get_longlong_uint(xp, tp);
18638 		if (status == NC_NOERR) /* report the first encountered error */
18639 			status = lstatus;
18640 	}
18641 
18642 	*xpp = (const void *)xp;
18643 	return status;
18644 #endif
18645 }
18646 
18647 int
ncx_getn_longlong_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)18648 ncx_getn_longlong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
18649 {
18650 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18651 
18652  /* basic algorithm is:
18653   *   - ensure sane alignment of input data
18654   *   - copy (conversion happens automatically) input data
18655   *     to output
18656   *   - update xpp to point at next unconverted input, and tp to point
18657   *     at next location for converted output
18658   */
18659   long i, j, ni;
18660   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18661   int64 *xp;
18662   int nrange = 0;         /* number of range errors */
18663   int realign = 0;        /* "do we need to fix input data alignment?" */
18664   long cxp = (long) *((char**)xpp);
18665 
18666   realign = (cxp & 7) % SIZEOF_INT64;
18667   /* sjl: manually stripmine so we can limit amount of
18668    * vector work space reserved to LOOPCNT elements. Also
18669    * makes vectorisation easy */
18670   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18671     ni=Min(nelems-j,LOOPCNT);
18672     if (realign) {
18673       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
18674       xp = tmp;
18675     } else {
18676       xp = (int64 *) *xpp;
18677     }
18678    /* copy the next block */
18679 #pragma cdir loopcnt=LOOPCNT
18680 #pragma cdir shortloop
18681     for (i=0; i<ni; i++) {
18682       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
18683      /* test for range errors (not always needed but do it anyway) */
18684      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
18685      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
18686       nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
18687     }
18688    /* update xpp and tp */
18689     if (realign) xp = (int64 *) *xpp;
18690     xp += ni;
18691     tp += ni;
18692     *xpp = (void*)xp;
18693   }
18694   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18695 
18696 #else   /* not SX */
18697 	const char *xp = (const char *) *xpp;
18698 	int status = NC_NOERR;
18699 
18700 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18701 	{
18702 		const int lstatus = ncx_get_longlong_ulonglong(xp, tp);
18703 		if (status == NC_NOERR) /* report the first encountered error */
18704 			status = lstatus;
18705 	}
18706 
18707 	*xpp = (const void *)xp;
18708 	return status;
18709 #endif
18710 }
18711 
18712 
18713 #if X_SIZEOF_INT64 == SIZEOF_LONGLONG
18714 /* optimized version */
18715 int
ncx_putn_longlong_longlong(void ** xpp,size_t nelems,const long long * tp,void * fillp)18716 ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp, void *fillp)
18717 {
18718 #ifdef WORDS_BIGENDIAN
18719 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
18720 # else
18721 	swapn8b(*xpp, tp, nelems);
18722 # endif
18723 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
18724 	return NC_NOERR;
18725 }
18726 #else
18727 int
ncx_putn_longlong_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)18728 ncx_putn_longlong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
18729 {
18730 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18731 
18732  /* basic algorithm is:
18733   *   - ensure sane alignment of output data
18734   *   - copy (conversion happens automatically) input data
18735   *     to output
18736   *   - update tp to point at next unconverted input, and xpp to point
18737   *     at next location for converted output
18738   */
18739   long i, j, ni;
18740   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18741   int64 *xp;
18742   int nrange = 0;         /* number of range errors */
18743   int realign = 0;        /* "do we need to fix input data alignment?" */
18744   long cxp = (long) *((char**)xpp);
18745 
18746   realign = (cxp & 7) % SIZEOF_INT64;
18747   /* sjl: manually stripmine so we can limit amount of
18748    * vector work space reserved to LOOPCNT elements. Also
18749    * makes vectorisation easy */
18750   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18751     ni=Min(nelems-j,LOOPCNT);
18752     if (realign) {
18753       xp = tmp;
18754     } else {
18755       xp = (int64 *) *xpp;
18756     }
18757    /* copy the next block */
18758 #pragma cdir loopcnt=LOOPCNT
18759 #pragma cdir shortloop
18760     for (i=0; i<ni; i++) {
18761       /* the normal case: */
18762       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18763      /* test for range errors (not always needed but do it anyway) */
18764      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18765      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18766       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18767     }
18768    /* copy workspace back if necessary */
18769     if (realign) {
18770       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18771       xp = (int64 *) *xpp;
18772     }
18773    /* update xpp and tp */
18774     xp += ni;
18775     tp += ni;
18776     *xpp = (void*)xp;
18777   }
18778   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18779 
18780 #else   /* not SX */
18781 
18782 	char *xp = (char *) *xpp;
18783 	int status = NC_NOERR;
18784 
18785 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18786 	{
18787 		int lstatus = ncx_put_longlong_longlong(xp, tp, fillp);
18788 		if (status == NC_NOERR) /* report the first encountered error */
18789 			status = lstatus;
18790 	}
18791 
18792 	*xpp = (void *)xp;
18793 	return status;
18794 #endif
18795 }
18796 
18797 #endif
18798 int
ncx_putn_longlong_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)18799 ncx_putn_longlong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
18800 {
18801 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18802 
18803  /* basic algorithm is:
18804   *   - ensure sane alignment of output data
18805   *   - copy (conversion happens automatically) input data
18806   *     to output
18807   *   - update tp to point at next unconverted input, and xpp to point
18808   *     at next location for converted output
18809   */
18810   long i, j, ni;
18811   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18812   int64 *xp;
18813   int nrange = 0;         /* number of range errors */
18814   int realign = 0;        /* "do we need to fix input data alignment?" */
18815   long cxp = (long) *((char**)xpp);
18816 
18817   realign = (cxp & 7) % SIZEOF_INT64;
18818   /* sjl: manually stripmine so we can limit amount of
18819    * vector work space reserved to LOOPCNT elements. Also
18820    * makes vectorisation easy */
18821   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18822     ni=Min(nelems-j,LOOPCNT);
18823     if (realign) {
18824       xp = tmp;
18825     } else {
18826       xp = (int64 *) *xpp;
18827     }
18828    /* copy the next block */
18829 #pragma cdir loopcnt=LOOPCNT
18830 #pragma cdir shortloop
18831     for (i=0; i<ni; i++) {
18832       /* the normal case: */
18833       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18834      /* test for range errors (not always needed but do it anyway) */
18835      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18836      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18837       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18838     }
18839    /* copy workspace back if necessary */
18840     if (realign) {
18841       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18842       xp = (int64 *) *xpp;
18843     }
18844    /* update xpp and tp */
18845     xp += ni;
18846     tp += ni;
18847     *xpp = (void*)xp;
18848   }
18849   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18850 
18851 #else   /* not SX */
18852 
18853 	char *xp = (char *) *xpp;
18854 	int status = NC_NOERR;
18855 
18856 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18857 	{
18858 		int lstatus = ncx_put_longlong_schar(xp, tp, fillp);
18859 		if (status == NC_NOERR) /* report the first encountered error */
18860 			status = lstatus;
18861 	}
18862 
18863 	*xpp = (void *)xp;
18864 	return status;
18865 #endif
18866 }
18867 
18868 int
ncx_putn_longlong_short(void ** xpp,size_t nelems,const short * tp,void * fillp)18869 ncx_putn_longlong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
18870 {
18871 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18872 
18873  /* basic algorithm is:
18874   *   - ensure sane alignment of output data
18875   *   - copy (conversion happens automatically) input data
18876   *     to output
18877   *   - update tp to point at next unconverted input, and xpp to point
18878   *     at next location for converted output
18879   */
18880   long i, j, ni;
18881   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18882   int64 *xp;
18883   int nrange = 0;         /* number of range errors */
18884   int realign = 0;        /* "do we need to fix input data alignment?" */
18885   long cxp = (long) *((char**)xpp);
18886 
18887   realign = (cxp & 7) % SIZEOF_INT64;
18888   /* sjl: manually stripmine so we can limit amount of
18889    * vector work space reserved to LOOPCNT elements. Also
18890    * makes vectorisation easy */
18891   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18892     ni=Min(nelems-j,LOOPCNT);
18893     if (realign) {
18894       xp = tmp;
18895     } else {
18896       xp = (int64 *) *xpp;
18897     }
18898    /* copy the next block */
18899 #pragma cdir loopcnt=LOOPCNT
18900 #pragma cdir shortloop
18901     for (i=0; i<ni; i++) {
18902       /* the normal case: */
18903       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18904      /* test for range errors (not always needed but do it anyway) */
18905      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18906      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18907       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18908     }
18909    /* copy workspace back if necessary */
18910     if (realign) {
18911       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18912       xp = (int64 *) *xpp;
18913     }
18914    /* update xpp and tp */
18915     xp += ni;
18916     tp += ni;
18917     *xpp = (void*)xp;
18918   }
18919   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18920 
18921 #else   /* not SX */
18922 
18923 	char *xp = (char *) *xpp;
18924 	int status = NC_NOERR;
18925 
18926 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18927 	{
18928 		int lstatus = ncx_put_longlong_short(xp, tp, fillp);
18929 		if (status == NC_NOERR) /* report the first encountered error */
18930 			status = lstatus;
18931 	}
18932 
18933 	*xpp = (void *)xp;
18934 	return status;
18935 #endif
18936 }
18937 
18938 int
ncx_putn_longlong_int(void ** xpp,size_t nelems,const int * tp,void * fillp)18939 ncx_putn_longlong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
18940 {
18941 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
18942 
18943  /* basic algorithm is:
18944   *   - ensure sane alignment of output data
18945   *   - copy (conversion happens automatically) input data
18946   *     to output
18947   *   - update tp to point at next unconverted input, and xpp to point
18948   *     at next location for converted output
18949   */
18950   long i, j, ni;
18951   int64 tmp[LOOPCNT];        /* in case input is misaligned */
18952   int64 *xp;
18953   int nrange = 0;         /* number of range errors */
18954   int realign = 0;        /* "do we need to fix input data alignment?" */
18955   long cxp = (long) *((char**)xpp);
18956 
18957   realign = (cxp & 7) % SIZEOF_INT64;
18958   /* sjl: manually stripmine so we can limit amount of
18959    * vector work space reserved to LOOPCNT elements. Also
18960    * makes vectorisation easy */
18961   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
18962     ni=Min(nelems-j,LOOPCNT);
18963     if (realign) {
18964       xp = tmp;
18965     } else {
18966       xp = (int64 *) *xpp;
18967     }
18968    /* copy the next block */
18969 #pragma cdir loopcnt=LOOPCNT
18970 #pragma cdir shortloop
18971     for (i=0; i<ni; i++) {
18972       /* the normal case: */
18973       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
18974      /* test for range errors (not always needed but do it anyway) */
18975      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
18976      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
18977       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
18978     }
18979    /* copy workspace back if necessary */
18980     if (realign) {
18981       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
18982       xp = (int64 *) *xpp;
18983     }
18984    /* update xpp and tp */
18985     xp += ni;
18986     tp += ni;
18987     *xpp = (void*)xp;
18988   }
18989   return nrange == 0 ? NC_NOERR : NC_ERANGE;
18990 
18991 #else   /* not SX */
18992 
18993 	char *xp = (char *) *xpp;
18994 	int status = NC_NOERR;
18995 
18996 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
18997 	{
18998 		int lstatus = ncx_put_longlong_int(xp, tp, fillp);
18999 		if (status == NC_NOERR) /* report the first encountered error */
19000 			status = lstatus;
19001 	}
19002 
19003 	*xpp = (void *)xp;
19004 	return status;
19005 #endif
19006 }
19007 
19008 int
ncx_putn_longlong_long(void ** xpp,size_t nelems,const long * tp,void * fillp)19009 ncx_putn_longlong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
19010 {
19011 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19012 
19013  /* basic algorithm is:
19014   *   - ensure sane alignment of output data
19015   *   - copy (conversion happens automatically) input data
19016   *     to output
19017   *   - update tp to point at next unconverted input, and xpp to point
19018   *     at next location for converted output
19019   */
19020   long i, j, ni;
19021   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19022   int64 *xp;
19023   int nrange = 0;         /* number of range errors */
19024   int realign = 0;        /* "do we need to fix input data alignment?" */
19025   long cxp = (long) *((char**)xpp);
19026 
19027   realign = (cxp & 7) % SIZEOF_INT64;
19028   /* sjl: manually stripmine so we can limit amount of
19029    * vector work space reserved to LOOPCNT elements. Also
19030    * makes vectorisation easy */
19031   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19032     ni=Min(nelems-j,LOOPCNT);
19033     if (realign) {
19034       xp = tmp;
19035     } else {
19036       xp = (int64 *) *xpp;
19037     }
19038    /* copy the next block */
19039 #pragma cdir loopcnt=LOOPCNT
19040 #pragma cdir shortloop
19041     for (i=0; i<ni; i++) {
19042       /* the normal case: */
19043       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19044      /* test for range errors (not always needed but do it anyway) */
19045      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19046      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19047       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19048     }
19049    /* copy workspace back if necessary */
19050     if (realign) {
19051       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19052       xp = (int64 *) *xpp;
19053     }
19054    /* update xpp and tp */
19055     xp += ni;
19056     tp += ni;
19057     *xpp = (void*)xp;
19058   }
19059   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19060 
19061 #else   /* not SX */
19062 
19063 	char *xp = (char *) *xpp;
19064 	int status = NC_NOERR;
19065 
19066 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19067 	{
19068 		int lstatus = ncx_put_longlong_long(xp, tp, fillp);
19069 		if (status == NC_NOERR) /* report the first encountered error */
19070 			status = lstatus;
19071 	}
19072 
19073 	*xpp = (void *)xp;
19074 	return status;
19075 #endif
19076 }
19077 
19078 int
ncx_putn_longlong_float(void ** xpp,size_t nelems,const float * tp,void * fillp)19079 ncx_putn_longlong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
19080 {
19081 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19082 
19083  /* basic algorithm is:
19084   *   - ensure sane alignment of output data
19085   *   - copy (conversion happens automatically) input data
19086   *     to output
19087   *   - update tp to point at next unconverted input, and xpp to point
19088   *     at next location for converted output
19089   */
19090   long i, j, ni;
19091   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19092   int64 *xp;
19093   int nrange = 0;         /* number of range errors */
19094   int realign = 0;        /* "do we need to fix input data alignment?" */
19095   long cxp = (long) *((char**)xpp);
19096 
19097   realign = (cxp & 7) % SIZEOF_INT64;
19098   /* sjl: manually stripmine so we can limit amount of
19099    * vector work space reserved to LOOPCNT elements. Also
19100    * makes vectorisation easy */
19101   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19102     ni=Min(nelems-j,LOOPCNT);
19103     if (realign) {
19104       xp = tmp;
19105     } else {
19106       xp = (int64 *) *xpp;
19107     }
19108    /* copy the next block */
19109 #pragma cdir loopcnt=LOOPCNT
19110 #pragma cdir shortloop
19111     for (i=0; i<ni; i++) {
19112       /* the normal case: */
19113       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19114      /* test for range errors (not always needed but do it anyway) */
19115      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19116      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19117       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19118     }
19119    /* copy workspace back if necessary */
19120     if (realign) {
19121       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19122       xp = (int64 *) *xpp;
19123     }
19124    /* update xpp and tp */
19125     xp += ni;
19126     tp += ni;
19127     *xpp = (void*)xp;
19128   }
19129   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19130 
19131 #else   /* not SX */
19132 
19133 	char *xp = (char *) *xpp;
19134 	int status = NC_NOERR;
19135 
19136 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19137 	{
19138 		int lstatus = ncx_put_longlong_float(xp, tp, fillp);
19139 		if (status == NC_NOERR) /* report the first encountered error */
19140 			status = lstatus;
19141 	}
19142 
19143 	*xpp = (void *)xp;
19144 	return status;
19145 #endif
19146 }
19147 
19148 int
ncx_putn_longlong_double(void ** xpp,size_t nelems,const double * tp,void * fillp)19149 ncx_putn_longlong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
19150 {
19151 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19152 
19153  /* basic algorithm is:
19154   *   - ensure sane alignment of output data
19155   *   - copy (conversion happens automatically) input data
19156   *     to output
19157   *   - update tp to point at next unconverted input, and xpp to point
19158   *     at next location for converted output
19159   */
19160   long i, j, ni;
19161   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19162   int64 *xp;
19163   int nrange = 0;         /* number of range errors */
19164   int realign = 0;        /* "do we need to fix input data alignment?" */
19165   long cxp = (long) *((char**)xpp);
19166 
19167   realign = (cxp & 7) % SIZEOF_INT64;
19168   /* sjl: manually stripmine so we can limit amount of
19169    * vector work space reserved to LOOPCNT elements. Also
19170    * makes vectorisation easy */
19171   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19172     ni=Min(nelems-j,LOOPCNT);
19173     if (realign) {
19174       xp = tmp;
19175     } else {
19176       xp = (int64 *) *xpp;
19177     }
19178    /* copy the next block */
19179 #pragma cdir loopcnt=LOOPCNT
19180 #pragma cdir shortloop
19181     for (i=0; i<ni; i++) {
19182       /* the normal case: */
19183       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19184      /* test for range errors (not always needed but do it anyway) */
19185      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19186      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19187       nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
19188     }
19189    /* copy workspace back if necessary */
19190     if (realign) {
19191       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19192       xp = (int64 *) *xpp;
19193     }
19194    /* update xpp and tp */
19195     xp += ni;
19196     tp += ni;
19197     *xpp = (void*)xp;
19198   }
19199   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19200 
19201 #else   /* not SX */
19202 
19203 	char *xp = (char *) *xpp;
19204 	int status = NC_NOERR;
19205 
19206 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19207 	{
19208 		int lstatus = ncx_put_longlong_double(xp, tp, fillp);
19209 		if (status == NC_NOERR) /* report the first encountered error */
19210 			status = lstatus;
19211 	}
19212 
19213 	*xpp = (void *)xp;
19214 	return status;
19215 #endif
19216 }
19217 
19218 int
ncx_putn_longlong_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)19219 ncx_putn_longlong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
19220 {
19221 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19222 
19223  /* basic algorithm is:
19224   *   - ensure sane alignment of output data
19225   *   - copy (conversion happens automatically) input data
19226   *     to output
19227   *   - update tp to point at next unconverted input, and xpp to point
19228   *     at next location for converted output
19229   */
19230   long i, j, ni;
19231   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19232   int64 *xp;
19233   int nrange = 0;         /* number of range errors */
19234   int realign = 0;        /* "do we need to fix input data alignment?" */
19235   long cxp = (long) *((char**)xpp);
19236 
19237   realign = (cxp & 7) % SIZEOF_INT64;
19238   /* sjl: manually stripmine so we can limit amount of
19239    * vector work space reserved to LOOPCNT elements. Also
19240    * makes vectorisation easy */
19241   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19242     ni=Min(nelems-j,LOOPCNT);
19243     if (realign) {
19244       xp = tmp;
19245     } else {
19246       xp = (int64 *) *xpp;
19247     }
19248    /* copy the next block */
19249 #pragma cdir loopcnt=LOOPCNT
19250 #pragma cdir shortloop
19251     for (i=0; i<ni; i++) {
19252       /* the normal case: */
19253       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19254      /* test for range errors (not always needed but do it anyway) */
19255      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19256      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19257       nrange += tp[i] > X_INT64_MAX ;
19258     }
19259    /* copy workspace back if necessary */
19260     if (realign) {
19261       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19262       xp = (int64 *) *xpp;
19263     }
19264    /* update xpp and tp */
19265     xp += ni;
19266     tp += ni;
19267     *xpp = (void*)xp;
19268   }
19269   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19270 
19271 #else   /* not SX */
19272 
19273 	char *xp = (char *) *xpp;
19274 	int status = NC_NOERR;
19275 
19276 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19277 	{
19278 		int lstatus = ncx_put_longlong_uchar(xp, tp, fillp);
19279 		if (status == NC_NOERR) /* report the first encountered error */
19280 			status = lstatus;
19281 	}
19282 
19283 	*xpp = (void *)xp;
19284 	return status;
19285 #endif
19286 }
19287 
19288 int
ncx_putn_longlong_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)19289 ncx_putn_longlong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
19290 {
19291 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19292 
19293  /* basic algorithm is:
19294   *   - ensure sane alignment of output data
19295   *   - copy (conversion happens automatically) input data
19296   *     to output
19297   *   - update tp to point at next unconverted input, and xpp to point
19298   *     at next location for converted output
19299   */
19300   long i, j, ni;
19301   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19302   int64 *xp;
19303   int nrange = 0;         /* number of range errors */
19304   int realign = 0;        /* "do we need to fix input data alignment?" */
19305   long cxp = (long) *((char**)xpp);
19306 
19307   realign = (cxp & 7) % SIZEOF_INT64;
19308   /* sjl: manually stripmine so we can limit amount of
19309    * vector work space reserved to LOOPCNT elements. Also
19310    * makes vectorisation easy */
19311   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19312     ni=Min(nelems-j,LOOPCNT);
19313     if (realign) {
19314       xp = tmp;
19315     } else {
19316       xp = (int64 *) *xpp;
19317     }
19318    /* copy the next block */
19319 #pragma cdir loopcnt=LOOPCNT
19320 #pragma cdir shortloop
19321     for (i=0; i<ni; i++) {
19322       /* the normal case: */
19323       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19324      /* test for range errors (not always needed but do it anyway) */
19325      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19326      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19327       nrange += tp[i] > X_INT64_MAX ;
19328     }
19329    /* copy workspace back if necessary */
19330     if (realign) {
19331       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19332       xp = (int64 *) *xpp;
19333     }
19334    /* update xpp and tp */
19335     xp += ni;
19336     tp += ni;
19337     *xpp = (void*)xp;
19338   }
19339   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19340 
19341 #else   /* not SX */
19342 
19343 	char *xp = (char *) *xpp;
19344 	int status = NC_NOERR;
19345 
19346 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19347 	{
19348 		int lstatus = ncx_put_longlong_ushort(xp, tp, fillp);
19349 		if (status == NC_NOERR) /* report the first encountered error */
19350 			status = lstatus;
19351 	}
19352 
19353 	*xpp = (void *)xp;
19354 	return status;
19355 #endif
19356 }
19357 
19358 int
ncx_putn_longlong_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)19359 ncx_putn_longlong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
19360 {
19361 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19362 
19363  /* basic algorithm is:
19364   *   - ensure sane alignment of output data
19365   *   - copy (conversion happens automatically) input data
19366   *     to output
19367   *   - update tp to point at next unconverted input, and xpp to point
19368   *     at next location for converted output
19369   */
19370   long i, j, ni;
19371   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19372   int64 *xp;
19373   int nrange = 0;         /* number of range errors */
19374   int realign = 0;        /* "do we need to fix input data alignment?" */
19375   long cxp = (long) *((char**)xpp);
19376 
19377   realign = (cxp & 7) % SIZEOF_INT64;
19378   /* sjl: manually stripmine so we can limit amount of
19379    * vector work space reserved to LOOPCNT elements. Also
19380    * makes vectorisation easy */
19381   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19382     ni=Min(nelems-j,LOOPCNT);
19383     if (realign) {
19384       xp = tmp;
19385     } else {
19386       xp = (int64 *) *xpp;
19387     }
19388    /* copy the next block */
19389 #pragma cdir loopcnt=LOOPCNT
19390 #pragma cdir shortloop
19391     for (i=0; i<ni; i++) {
19392       /* the normal case: */
19393       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19394      /* test for range errors (not always needed but do it anyway) */
19395      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19396      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19397       nrange += tp[i] > X_INT64_MAX ;
19398     }
19399    /* copy workspace back if necessary */
19400     if (realign) {
19401       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19402       xp = (int64 *) *xpp;
19403     }
19404    /* update xpp and tp */
19405     xp += ni;
19406     tp += ni;
19407     *xpp = (void*)xp;
19408   }
19409   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19410 
19411 #else   /* not SX */
19412 
19413 	char *xp = (char *) *xpp;
19414 	int status = NC_NOERR;
19415 
19416 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19417 	{
19418 		int lstatus = ncx_put_longlong_uint(xp, tp, fillp);
19419 		if (status == NC_NOERR) /* report the first encountered error */
19420 			status = lstatus;
19421 	}
19422 
19423 	*xpp = (void *)xp;
19424 	return status;
19425 #endif
19426 }
19427 
19428 int
ncx_putn_longlong_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)19429 ncx_putn_longlong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
19430 {
19431 #if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64
19432 
19433  /* basic algorithm is:
19434   *   - ensure sane alignment of output data
19435   *   - copy (conversion happens automatically) input data
19436   *     to output
19437   *   - update tp to point at next unconverted input, and xpp to point
19438   *     at next location for converted output
19439   */
19440   long i, j, ni;
19441   int64 tmp[LOOPCNT];        /* in case input is misaligned */
19442   int64 *xp;
19443   int nrange = 0;         /* number of range errors */
19444   int realign = 0;        /* "do we need to fix input data alignment?" */
19445   long cxp = (long) *((char**)xpp);
19446 
19447   realign = (cxp & 7) % SIZEOF_INT64;
19448   /* sjl: manually stripmine so we can limit amount of
19449    * vector work space reserved to LOOPCNT elements. Also
19450    * makes vectorisation easy */
19451   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19452     ni=Min(nelems-j,LOOPCNT);
19453     if (realign) {
19454       xp = tmp;
19455     } else {
19456       xp = (int64 *) *xpp;
19457     }
19458    /* copy the next block */
19459 #pragma cdir loopcnt=LOOPCNT
19460 #pragma cdir shortloop
19461     for (i=0; i<ni; i++) {
19462       /* the normal case: */
19463       xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
19464      /* test for range errors (not always needed but do it anyway) */
19465      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
19466      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
19467       nrange += tp[i] > X_INT64_MAX ;
19468     }
19469    /* copy workspace back if necessary */
19470     if (realign) {
19471       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
19472       xp = (int64 *) *xpp;
19473     }
19474    /* update xpp and tp */
19475     xp += ni;
19476     tp += ni;
19477     *xpp = (void*)xp;
19478   }
19479   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19480 
19481 #else   /* not SX */
19482 
19483 	char *xp = (char *) *xpp;
19484 	int status = NC_NOERR;
19485 
19486 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
19487 	{
19488 		int lstatus = ncx_put_longlong_ulonglong(xp, tp, fillp);
19489 		if (status == NC_NOERR) /* report the first encountered error */
19490 			status = lstatus;
19491 	}
19492 
19493 	*xpp = (void *)xp;
19494 	return status;
19495 #endif
19496 }
19497 
19498 
19499 /* uint64 --------------------------------------------------------------------*/
19500 
19501 #if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
19502 /* optimized version */
19503 int
ncx_getn_ulonglong_ulonglong(const void ** xpp,size_t nelems,unsigned long long * tp)19504 ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp)
19505 {
19506 #ifdef WORDS_BIGENDIAN
19507 	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
19508 # else
19509 	swapn8b(tp, *xpp, nelems);
19510 # endif
19511 	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
19512 	return NC_NOERR;
19513 }
19514 #else
19515 int
ncx_getn_ulonglong_ulonglong(const void ** xpp,size_t nelems,ulonglong * tp)19516 ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, ulonglong *tp)
19517 {
19518 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19519 
19520  /* basic algorithm is:
19521   *   - ensure sane alignment of input data
19522   *   - copy (conversion happens automatically) input data
19523   *     to output
19524   *   - update xpp to point at next unconverted input, and tp to point
19525   *     at next location for converted output
19526   */
19527   long i, j, ni;
19528   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19529   uint64 *xp;
19530   int nrange = 0;         /* number of range errors */
19531   int realign = 0;        /* "do we need to fix input data alignment?" */
19532   long cxp = (long) *((char**)xpp);
19533 
19534   realign = (cxp & 7) % SIZEOF_UINT64;
19535   /* sjl: manually stripmine so we can limit amount of
19536    * vector work space reserved to LOOPCNT elements. Also
19537    * makes vectorisation easy */
19538   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19539     ni=Min(nelems-j,LOOPCNT);
19540     if (realign) {
19541       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19542       xp = tmp;
19543     } else {
19544       xp = (uint64 *) *xpp;
19545     }
19546    /* copy the next block */
19547 #pragma cdir loopcnt=LOOPCNT
19548 #pragma cdir shortloop
19549     for (i=0; i<ni; i++) {
19550       tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
19551      /* test for range errors (not always needed but do it anyway) */
19552      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19553      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19554       nrange += xp[i] > ULONGLONG_MAX ;
19555     }
19556    /* update xpp and tp */
19557     if (realign) xp = (uint64 *) *xpp;
19558     xp += ni;
19559     tp += ni;
19560     *xpp = (void*)xp;
19561   }
19562   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19563 
19564 #else   /* not SX */
19565 	const char *xp = (const char *) *xpp;
19566 	int status = NC_NOERR;
19567 
19568 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19569 	{
19570 		const int lstatus = ncx_get_ulonglong_ulonglong(xp, tp);
19571 		if (status == NC_NOERR) /* report the first encountered error */
19572 			status = lstatus;
19573 	}
19574 
19575 	*xpp = (const void *)xp;
19576 	return status;
19577 #endif
19578 }
19579 
19580 #endif
19581 int
ncx_getn_ulonglong_schar(const void ** xpp,size_t nelems,schar * tp)19582 ncx_getn_ulonglong_schar(const void **xpp, size_t nelems, schar *tp)
19583 {
19584 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19585 
19586  /* basic algorithm is:
19587   *   - ensure sane alignment of input data
19588   *   - copy (conversion happens automatically) input data
19589   *     to output
19590   *   - update xpp to point at next unconverted input, and tp to point
19591   *     at next location for converted output
19592   */
19593   long i, j, ni;
19594   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19595   uint64 *xp;
19596   int nrange = 0;         /* number of range errors */
19597   int realign = 0;        /* "do we need to fix input data alignment?" */
19598   long cxp = (long) *((char**)xpp);
19599 
19600   realign = (cxp & 7) % SIZEOF_UINT64;
19601   /* sjl: manually stripmine so we can limit amount of
19602    * vector work space reserved to LOOPCNT elements. Also
19603    * makes vectorisation easy */
19604   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19605     ni=Min(nelems-j,LOOPCNT);
19606     if (realign) {
19607       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19608       xp = tmp;
19609     } else {
19610       xp = (uint64 *) *xpp;
19611     }
19612    /* copy the next block */
19613 #pragma cdir loopcnt=LOOPCNT
19614 #pragma cdir shortloop
19615     for (i=0; i<ni; i++) {
19616       tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
19617      /* test for range errors (not always needed but do it anyway) */
19618      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19619      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19620       nrange += xp[i] > SCHAR_MAX ;
19621     }
19622    /* update xpp and tp */
19623     if (realign) xp = (uint64 *) *xpp;
19624     xp += ni;
19625     tp += ni;
19626     *xpp = (void*)xp;
19627   }
19628   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19629 
19630 #else   /* not SX */
19631 	const char *xp = (const char *) *xpp;
19632 	int status = NC_NOERR;
19633 
19634 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19635 	{
19636 		const int lstatus = ncx_get_ulonglong_schar(xp, tp);
19637 		if (status == NC_NOERR) /* report the first encountered error */
19638 			status = lstatus;
19639 	}
19640 
19641 	*xpp = (const void *)xp;
19642 	return status;
19643 #endif
19644 }
19645 
19646 int
ncx_getn_ulonglong_short(const void ** xpp,size_t nelems,short * tp)19647 ncx_getn_ulonglong_short(const void **xpp, size_t nelems, short *tp)
19648 {
19649 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19650 
19651  /* basic algorithm is:
19652   *   - ensure sane alignment of input data
19653   *   - copy (conversion happens automatically) input data
19654   *     to output
19655   *   - update xpp to point at next unconverted input, and tp to point
19656   *     at next location for converted output
19657   */
19658   long i, j, ni;
19659   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19660   uint64 *xp;
19661   int nrange = 0;         /* number of range errors */
19662   int realign = 0;        /* "do we need to fix input data alignment?" */
19663   long cxp = (long) *((char**)xpp);
19664 
19665   realign = (cxp & 7) % SIZEOF_UINT64;
19666   /* sjl: manually stripmine so we can limit amount of
19667    * vector work space reserved to LOOPCNT elements. Also
19668    * makes vectorisation easy */
19669   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19670     ni=Min(nelems-j,LOOPCNT);
19671     if (realign) {
19672       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19673       xp = tmp;
19674     } else {
19675       xp = (uint64 *) *xpp;
19676     }
19677    /* copy the next block */
19678 #pragma cdir loopcnt=LOOPCNT
19679 #pragma cdir shortloop
19680     for (i=0; i<ni; i++) {
19681       tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
19682      /* test for range errors (not always needed but do it anyway) */
19683      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19684      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19685       nrange += xp[i] > SHORT_MAX ;
19686     }
19687    /* update xpp and tp */
19688     if (realign) xp = (uint64 *) *xpp;
19689     xp += ni;
19690     tp += ni;
19691     *xpp = (void*)xp;
19692   }
19693   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19694 
19695 #else   /* not SX */
19696 	const char *xp = (const char *) *xpp;
19697 	int status = NC_NOERR;
19698 
19699 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19700 	{
19701 		const int lstatus = ncx_get_ulonglong_short(xp, tp);
19702 		if (status == NC_NOERR) /* report the first encountered error */
19703 			status = lstatus;
19704 	}
19705 
19706 	*xpp = (const void *)xp;
19707 	return status;
19708 #endif
19709 }
19710 
19711 int
ncx_getn_ulonglong_int(const void ** xpp,size_t nelems,int * tp)19712 ncx_getn_ulonglong_int(const void **xpp, size_t nelems, int *tp)
19713 {
19714 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19715 
19716  /* basic algorithm is:
19717   *   - ensure sane alignment of input data
19718   *   - copy (conversion happens automatically) input data
19719   *     to output
19720   *   - update xpp to point at next unconverted input, and tp to point
19721   *     at next location for converted output
19722   */
19723   long i, j, ni;
19724   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19725   uint64 *xp;
19726   int nrange = 0;         /* number of range errors */
19727   int realign = 0;        /* "do we need to fix input data alignment?" */
19728   long cxp = (long) *((char**)xpp);
19729 
19730   realign = (cxp & 7) % SIZEOF_UINT64;
19731   /* sjl: manually stripmine so we can limit amount of
19732    * vector work space reserved to LOOPCNT elements. Also
19733    * makes vectorisation easy */
19734   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19735     ni=Min(nelems-j,LOOPCNT);
19736     if (realign) {
19737       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19738       xp = tmp;
19739     } else {
19740       xp = (uint64 *) *xpp;
19741     }
19742    /* copy the next block */
19743 #pragma cdir loopcnt=LOOPCNT
19744 #pragma cdir shortloop
19745     for (i=0; i<ni; i++) {
19746       tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
19747      /* test for range errors (not always needed but do it anyway) */
19748      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19749      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19750       nrange += xp[i] > INT_MAX ;
19751     }
19752    /* update xpp and tp */
19753     if (realign) xp = (uint64 *) *xpp;
19754     xp += ni;
19755     tp += ni;
19756     *xpp = (void*)xp;
19757   }
19758   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19759 
19760 #else   /* not SX */
19761 	const char *xp = (const char *) *xpp;
19762 	int status = NC_NOERR;
19763 
19764 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19765 	{
19766 		const int lstatus = ncx_get_ulonglong_int(xp, tp);
19767 		if (status == NC_NOERR) /* report the first encountered error */
19768 			status = lstatus;
19769 	}
19770 
19771 	*xpp = (const void *)xp;
19772 	return status;
19773 #endif
19774 }
19775 
19776 int
ncx_getn_ulonglong_long(const void ** xpp,size_t nelems,long * tp)19777 ncx_getn_ulonglong_long(const void **xpp, size_t nelems, long *tp)
19778 {
19779 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19780 
19781  /* basic algorithm is:
19782   *   - ensure sane alignment of input data
19783   *   - copy (conversion happens automatically) input data
19784   *     to output
19785   *   - update xpp to point at next unconverted input, and tp to point
19786   *     at next location for converted output
19787   */
19788   long i, j, ni;
19789   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19790   uint64 *xp;
19791   int nrange = 0;         /* number of range errors */
19792   int realign = 0;        /* "do we need to fix input data alignment?" */
19793   long cxp = (long) *((char**)xpp);
19794 
19795   realign = (cxp & 7) % SIZEOF_UINT64;
19796   /* sjl: manually stripmine so we can limit amount of
19797    * vector work space reserved to LOOPCNT elements. Also
19798    * makes vectorisation easy */
19799   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19800     ni=Min(nelems-j,LOOPCNT);
19801     if (realign) {
19802       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19803       xp = tmp;
19804     } else {
19805       xp = (uint64 *) *xpp;
19806     }
19807    /* copy the next block */
19808 #pragma cdir loopcnt=LOOPCNT
19809 #pragma cdir shortloop
19810     for (i=0; i<ni; i++) {
19811       tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
19812      /* test for range errors (not always needed but do it anyway) */
19813      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19814      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19815       nrange += xp[i] > LONG_MAX ;
19816     }
19817    /* update xpp and tp */
19818     if (realign) xp = (uint64 *) *xpp;
19819     xp += ni;
19820     tp += ni;
19821     *xpp = (void*)xp;
19822   }
19823   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19824 
19825 #else   /* not SX */
19826 	const char *xp = (const char *) *xpp;
19827 	int status = NC_NOERR;
19828 
19829 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19830 	{
19831 		const int lstatus = ncx_get_ulonglong_long(xp, tp);
19832 		if (status == NC_NOERR) /* report the first encountered error */
19833 			status = lstatus;
19834 	}
19835 
19836 	*xpp = (const void *)xp;
19837 	return status;
19838 #endif
19839 }
19840 
19841 int
ncx_getn_ulonglong_float(const void ** xpp,size_t nelems,float * tp)19842 ncx_getn_ulonglong_float(const void **xpp, size_t nelems, float *tp)
19843 {
19844 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19845 
19846  /* basic algorithm is:
19847   *   - ensure sane alignment of input data
19848   *   - copy (conversion happens automatically) input data
19849   *     to output
19850   *   - update xpp to point at next unconverted input, and tp to point
19851   *     at next location for converted output
19852   */
19853   long i, j, ni;
19854   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19855   uint64 *xp;
19856   int nrange = 0;         /* number of range errors */
19857   int realign = 0;        /* "do we need to fix input data alignment?" */
19858   long cxp = (long) *((char**)xpp);
19859 
19860   realign = (cxp & 7) % SIZEOF_UINT64;
19861   /* sjl: manually stripmine so we can limit amount of
19862    * vector work space reserved to LOOPCNT elements. Also
19863    * makes vectorisation easy */
19864   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19865     ni=Min(nelems-j,LOOPCNT);
19866     if (realign) {
19867       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19868       xp = tmp;
19869     } else {
19870       xp = (uint64 *) *xpp;
19871     }
19872    /* copy the next block */
19873 #pragma cdir loopcnt=LOOPCNT
19874 #pragma cdir shortloop
19875     for (i=0; i<ni; i++) {
19876       tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
19877      /* test for range errors (not always needed but do it anyway) */
19878      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19879      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19880       nrange += xp[i] > FLOAT_MAX ;
19881     }
19882    /* update xpp and tp */
19883     if (realign) xp = (uint64 *) *xpp;
19884     xp += ni;
19885     tp += ni;
19886     *xpp = (void*)xp;
19887   }
19888   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19889 
19890 #else   /* not SX */
19891 	const char *xp = (const char *) *xpp;
19892 	int status = NC_NOERR;
19893 
19894 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19895 	{
19896 		const int lstatus = ncx_get_ulonglong_float(xp, tp);
19897 		if (status == NC_NOERR) /* report the first encountered error */
19898 			status = lstatus;
19899 	}
19900 
19901 	*xpp = (const void *)xp;
19902 	return status;
19903 #endif
19904 }
19905 
19906 int
ncx_getn_ulonglong_double(const void ** xpp,size_t nelems,double * tp)19907 ncx_getn_ulonglong_double(const void **xpp, size_t nelems, double *tp)
19908 {
19909 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19910 
19911  /* basic algorithm is:
19912   *   - ensure sane alignment of input data
19913   *   - copy (conversion happens automatically) input data
19914   *     to output
19915   *   - update xpp to point at next unconverted input, and tp to point
19916   *     at next location for converted output
19917   */
19918   long i, j, ni;
19919   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19920   uint64 *xp;
19921   int nrange = 0;         /* number of range errors */
19922   int realign = 0;        /* "do we need to fix input data alignment?" */
19923   long cxp = (long) *((char**)xpp);
19924 
19925   realign = (cxp & 7) % SIZEOF_UINT64;
19926   /* sjl: manually stripmine so we can limit amount of
19927    * vector work space reserved to LOOPCNT elements. Also
19928    * makes vectorisation easy */
19929   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19930     ni=Min(nelems-j,LOOPCNT);
19931     if (realign) {
19932       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19933       xp = tmp;
19934     } else {
19935       xp = (uint64 *) *xpp;
19936     }
19937    /* copy the next block */
19938 #pragma cdir loopcnt=LOOPCNT
19939 #pragma cdir shortloop
19940     for (i=0; i<ni; i++) {
19941       tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
19942      /* test for range errors (not always needed but do it anyway) */
19943      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
19944      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
19945       nrange += xp[i] > DOUBLE_MAX ;
19946     }
19947    /* update xpp and tp */
19948     if (realign) xp = (uint64 *) *xpp;
19949     xp += ni;
19950     tp += ni;
19951     *xpp = (void*)xp;
19952   }
19953   return nrange == 0 ? NC_NOERR : NC_ERANGE;
19954 
19955 #else   /* not SX */
19956 	const char *xp = (const char *) *xpp;
19957 	int status = NC_NOERR;
19958 
19959 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
19960 	{
19961 		const int lstatus = ncx_get_ulonglong_double(xp, tp);
19962 		if (status == NC_NOERR) /* report the first encountered error */
19963 			status = lstatus;
19964 	}
19965 
19966 	*xpp = (const void *)xp;
19967 	return status;
19968 #endif
19969 }
19970 
19971 int
ncx_getn_ulonglong_longlong(const void ** xpp,size_t nelems,longlong * tp)19972 ncx_getn_ulonglong_longlong(const void **xpp, size_t nelems, longlong *tp)
19973 {
19974 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
19975 
19976  /* basic algorithm is:
19977   *   - ensure sane alignment of input data
19978   *   - copy (conversion happens automatically) input data
19979   *     to output
19980   *   - update xpp to point at next unconverted input, and tp to point
19981   *     at next location for converted output
19982   */
19983   long i, j, ni;
19984   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
19985   uint64 *xp;
19986   int nrange = 0;         /* number of range errors */
19987   int realign = 0;        /* "do we need to fix input data alignment?" */
19988   long cxp = (long) *((char**)xpp);
19989 
19990   realign = (cxp & 7) % SIZEOF_UINT64;
19991   /* sjl: manually stripmine so we can limit amount of
19992    * vector work space reserved to LOOPCNT elements. Also
19993    * makes vectorisation easy */
19994   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
19995     ni=Min(nelems-j,LOOPCNT);
19996     if (realign) {
19997       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
19998       xp = tmp;
19999     } else {
20000       xp = (uint64 *) *xpp;
20001     }
20002    /* copy the next block */
20003 #pragma cdir loopcnt=LOOPCNT
20004 #pragma cdir shortloop
20005     for (i=0; i<ni; i++) {
20006       tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
20007      /* test for range errors (not always needed but do it anyway) */
20008      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20009      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20010       nrange += xp[i] > LONGLONG_MAX ;
20011     }
20012    /* update xpp and tp */
20013     if (realign) xp = (uint64 *) *xpp;
20014     xp += ni;
20015     tp += ni;
20016     *xpp = (void*)xp;
20017   }
20018   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20019 
20020 #else   /* not SX */
20021 	const char *xp = (const char *) *xpp;
20022 	int status = NC_NOERR;
20023 
20024 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20025 	{
20026 		const int lstatus = ncx_get_ulonglong_longlong(xp, tp);
20027 		if (status == NC_NOERR) /* report the first encountered error */
20028 			status = lstatus;
20029 	}
20030 
20031 	*xpp = (const void *)xp;
20032 	return status;
20033 #endif
20034 }
20035 
20036 int
ncx_getn_ulonglong_uchar(const void ** xpp,size_t nelems,uchar * tp)20037 ncx_getn_ulonglong_uchar(const void **xpp, size_t nelems, uchar *tp)
20038 {
20039 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20040 
20041  /* basic algorithm is:
20042   *   - ensure sane alignment of input data
20043   *   - copy (conversion happens automatically) input data
20044   *     to output
20045   *   - update xpp to point at next unconverted input, and tp to point
20046   *     at next location for converted output
20047   */
20048   long i, j, ni;
20049   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20050   uint64 *xp;
20051   int nrange = 0;         /* number of range errors */
20052   int realign = 0;        /* "do we need to fix input data alignment?" */
20053   long cxp = (long) *((char**)xpp);
20054 
20055   realign = (cxp & 7) % SIZEOF_UINT64;
20056   /* sjl: manually stripmine so we can limit amount of
20057    * vector work space reserved to LOOPCNT elements. Also
20058    * makes vectorisation easy */
20059   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20060     ni=Min(nelems-j,LOOPCNT);
20061     if (realign) {
20062       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20063       xp = tmp;
20064     } else {
20065       xp = (uint64 *) *xpp;
20066     }
20067    /* copy the next block */
20068 #pragma cdir loopcnt=LOOPCNT
20069 #pragma cdir shortloop
20070     for (i=0; i<ni; i++) {
20071       tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
20072      /* test for range errors (not always needed but do it anyway) */
20073      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20074      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20075       nrange += xp[i] > UCHAR_MAX ;
20076     }
20077    /* update xpp and tp */
20078     if (realign) xp = (uint64 *) *xpp;
20079     xp += ni;
20080     tp += ni;
20081     *xpp = (void*)xp;
20082   }
20083   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20084 
20085 #else   /* not SX */
20086 	const char *xp = (const char *) *xpp;
20087 	int status = NC_NOERR;
20088 
20089 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20090 	{
20091 		const int lstatus = ncx_get_ulonglong_uchar(xp, tp);
20092 		if (status == NC_NOERR) /* report the first encountered error */
20093 			status = lstatus;
20094 	}
20095 
20096 	*xpp = (const void *)xp;
20097 	return status;
20098 #endif
20099 }
20100 
20101 int
ncx_getn_ulonglong_ushort(const void ** xpp,size_t nelems,ushort * tp)20102 ncx_getn_ulonglong_ushort(const void **xpp, size_t nelems, ushort *tp)
20103 {
20104 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20105 
20106  /* basic algorithm is:
20107   *   - ensure sane alignment of input data
20108   *   - copy (conversion happens automatically) input data
20109   *     to output
20110   *   - update xpp to point at next unconverted input, and tp to point
20111   *     at next location for converted output
20112   */
20113   long i, j, ni;
20114   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20115   uint64 *xp;
20116   int nrange = 0;         /* number of range errors */
20117   int realign = 0;        /* "do we need to fix input data alignment?" */
20118   long cxp = (long) *((char**)xpp);
20119 
20120   realign = (cxp & 7) % SIZEOF_UINT64;
20121   /* sjl: manually stripmine so we can limit amount of
20122    * vector work space reserved to LOOPCNT elements. Also
20123    * makes vectorisation easy */
20124   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20125     ni=Min(nelems-j,LOOPCNT);
20126     if (realign) {
20127       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20128       xp = tmp;
20129     } else {
20130       xp = (uint64 *) *xpp;
20131     }
20132    /* copy the next block */
20133 #pragma cdir loopcnt=LOOPCNT
20134 #pragma cdir shortloop
20135     for (i=0; i<ni; i++) {
20136       tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
20137      /* test for range errors (not always needed but do it anyway) */
20138      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20139      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20140       nrange += xp[i] > USHORT_MAX ;
20141     }
20142    /* update xpp and tp */
20143     if (realign) xp = (uint64 *) *xpp;
20144     xp += ni;
20145     tp += ni;
20146     *xpp = (void*)xp;
20147   }
20148   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20149 
20150 #else   /* not SX */
20151 	const char *xp = (const char *) *xpp;
20152 	int status = NC_NOERR;
20153 
20154 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20155 	{
20156 		const int lstatus = ncx_get_ulonglong_ushort(xp, tp);
20157 		if (status == NC_NOERR) /* report the first encountered error */
20158 			status = lstatus;
20159 	}
20160 
20161 	*xpp = (const void *)xp;
20162 	return status;
20163 #endif
20164 }
20165 
20166 int
ncx_getn_ulonglong_uint(const void ** xpp,size_t nelems,uint * tp)20167 ncx_getn_ulonglong_uint(const void **xpp, size_t nelems, uint *tp)
20168 {
20169 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20170 
20171  /* basic algorithm is:
20172   *   - ensure sane alignment of input data
20173   *   - copy (conversion happens automatically) input data
20174   *     to output
20175   *   - update xpp to point at next unconverted input, and tp to point
20176   *     at next location for converted output
20177   */
20178   long i, j, ni;
20179   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20180   uint64 *xp;
20181   int nrange = 0;         /* number of range errors */
20182   int realign = 0;        /* "do we need to fix input data alignment?" */
20183   long cxp = (long) *((char**)xpp);
20184 
20185   realign = (cxp & 7) % SIZEOF_UINT64;
20186   /* sjl: manually stripmine so we can limit amount of
20187    * vector work space reserved to LOOPCNT elements. Also
20188    * makes vectorisation easy */
20189   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20190     ni=Min(nelems-j,LOOPCNT);
20191     if (realign) {
20192       memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
20193       xp = tmp;
20194     } else {
20195       xp = (uint64 *) *xpp;
20196     }
20197    /* copy the next block */
20198 #pragma cdir loopcnt=LOOPCNT
20199 #pragma cdir shortloop
20200     for (i=0; i<ni; i++) {
20201       tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
20202      /* test for range errors (not always needed but do it anyway) */
20203      /* if xpp is unsigned, we need not check if xp[i] < _MIN */
20204      /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
20205       nrange += xp[i] > UINT_MAX ;
20206     }
20207    /* update xpp and tp */
20208     if (realign) xp = (uint64 *) *xpp;
20209     xp += ni;
20210     tp += ni;
20211     *xpp = (void*)xp;
20212   }
20213   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20214 
20215 #else   /* not SX */
20216 	const char *xp = (const char *) *xpp;
20217 	int status = NC_NOERR;
20218 
20219 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20220 	{
20221 		const int lstatus = ncx_get_ulonglong_uint(xp, tp);
20222 		if (status == NC_NOERR) /* report the first encountered error */
20223 			status = lstatus;
20224 	}
20225 
20226 	*xpp = (const void *)xp;
20227 	return status;
20228 #endif
20229 }
20230 
20231 
20232 #if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
20233 /* optimized version */
20234 int
ncx_putn_ulonglong_ulonglong(void ** xpp,size_t nelems,const unsigned long long * tp,void * fillp)20235 ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp, void *fillp)
20236 {
20237 #ifdef WORDS_BIGENDIAN
20238 	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
20239 # else
20240 	swapn8b(*xpp, tp, nelems);
20241 # endif
20242 	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
20243 	return NC_NOERR;
20244 }
20245 #else
20246 int
ncx_putn_ulonglong_ulonglong(void ** xpp,size_t nelems,const ulonglong * tp,void * fillp)20247 ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const ulonglong *tp, void *fillp)
20248 {
20249 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20250 
20251  /* basic algorithm is:
20252   *   - ensure sane alignment of output data
20253   *   - copy (conversion happens automatically) input data
20254   *     to output
20255   *   - update tp to point at next unconverted input, and xpp to point
20256   *     at next location for converted output
20257   */
20258   long i, j, ni;
20259   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20260   uint64 *xp;
20261   int nrange = 0;         /* number of range errors */
20262   int realign = 0;        /* "do we need to fix input data alignment?" */
20263   long cxp = (long) *((char**)xpp);
20264 
20265   realign = (cxp & 7) % SIZEOF_UINT64;
20266   /* sjl: manually stripmine so we can limit amount of
20267    * vector work space reserved to LOOPCNT elements. Also
20268    * makes vectorisation easy */
20269   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20270     ni=Min(nelems-j,LOOPCNT);
20271     if (realign) {
20272       xp = tmp;
20273     } else {
20274       xp = (uint64 *) *xpp;
20275     }
20276    /* copy the next block */
20277 #pragma cdir loopcnt=LOOPCNT
20278 #pragma cdir shortloop
20279     for (i=0; i<ni; i++) {
20280       /* the normal case: */
20281       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20282      /* test for range errors (not always needed but do it anyway) */
20283      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20284      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20285       nrange += tp[i] > X_UINT64_MAX ;
20286     }
20287    /* copy workspace back if necessary */
20288     if (realign) {
20289       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20290       xp = (uint64 *) *xpp;
20291     }
20292    /* update xpp and tp */
20293     xp += ni;
20294     tp += ni;
20295     *xpp = (void*)xp;
20296   }
20297   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20298 
20299 #else   /* not SX */
20300 
20301 	char *xp = (char *) *xpp;
20302 	int status = NC_NOERR;
20303 
20304 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20305 	{
20306 		int lstatus = ncx_put_ulonglong_ulonglong(xp, tp, fillp);
20307 		if (status == NC_NOERR) /* report the first encountered error */
20308 			status = lstatus;
20309 	}
20310 
20311 	*xpp = (void *)xp;
20312 	return status;
20313 #endif
20314 }
20315 
20316 #endif
20317 int
ncx_putn_ulonglong_schar(void ** xpp,size_t nelems,const schar * tp,void * fillp)20318 ncx_putn_ulonglong_schar(void **xpp, size_t nelems, const schar *tp, void *fillp)
20319 {
20320 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20321 
20322  /* basic algorithm is:
20323   *   - ensure sane alignment of output data
20324   *   - copy (conversion happens automatically) input data
20325   *     to output
20326   *   - update tp to point at next unconverted input, and xpp to point
20327   *     at next location for converted output
20328   */
20329   long i, j, ni;
20330   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20331   uint64 *xp;
20332   int nrange = 0;         /* number of range errors */
20333   int realign = 0;        /* "do we need to fix input data alignment?" */
20334   long cxp = (long) *((char**)xpp);
20335 
20336   realign = (cxp & 7) % SIZEOF_UINT64;
20337   /* sjl: manually stripmine so we can limit amount of
20338    * vector work space reserved to LOOPCNT elements. Also
20339    * makes vectorisation easy */
20340   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20341     ni=Min(nelems-j,LOOPCNT);
20342     if (realign) {
20343       xp = tmp;
20344     } else {
20345       xp = (uint64 *) *xpp;
20346     }
20347    /* copy the next block */
20348 #pragma cdir loopcnt=LOOPCNT
20349 #pragma cdir shortloop
20350     for (i=0; i<ni; i++) {
20351       /* the normal case: */
20352       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20353      /* test for range errors (not always needed but do it anyway) */
20354      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20355      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20356       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20357     }
20358    /* copy workspace back if necessary */
20359     if (realign) {
20360       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20361       xp = (uint64 *) *xpp;
20362     }
20363    /* update xpp and tp */
20364     xp += ni;
20365     tp += ni;
20366     *xpp = (void*)xp;
20367   }
20368   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20369 
20370 #else   /* not SX */
20371 
20372 	char *xp = (char *) *xpp;
20373 	int status = NC_NOERR;
20374 
20375 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20376 	{
20377 		int lstatus = ncx_put_ulonglong_schar(xp, tp, fillp);
20378 		if (status == NC_NOERR) /* report the first encountered error */
20379 			status = lstatus;
20380 	}
20381 
20382 	*xpp = (void *)xp;
20383 	return status;
20384 #endif
20385 }
20386 
20387 int
ncx_putn_ulonglong_short(void ** xpp,size_t nelems,const short * tp,void * fillp)20388 ncx_putn_ulonglong_short(void **xpp, size_t nelems, const short *tp, void *fillp)
20389 {
20390 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20391 
20392  /* basic algorithm is:
20393   *   - ensure sane alignment of output data
20394   *   - copy (conversion happens automatically) input data
20395   *     to output
20396   *   - update tp to point at next unconverted input, and xpp to point
20397   *     at next location for converted output
20398   */
20399   long i, j, ni;
20400   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20401   uint64 *xp;
20402   int nrange = 0;         /* number of range errors */
20403   int realign = 0;        /* "do we need to fix input data alignment?" */
20404   long cxp = (long) *((char**)xpp);
20405 
20406   realign = (cxp & 7) % SIZEOF_UINT64;
20407   /* sjl: manually stripmine so we can limit amount of
20408    * vector work space reserved to LOOPCNT elements. Also
20409    * makes vectorisation easy */
20410   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20411     ni=Min(nelems-j,LOOPCNT);
20412     if (realign) {
20413       xp = tmp;
20414     } else {
20415       xp = (uint64 *) *xpp;
20416     }
20417    /* copy the next block */
20418 #pragma cdir loopcnt=LOOPCNT
20419 #pragma cdir shortloop
20420     for (i=0; i<ni; i++) {
20421       /* the normal case: */
20422       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20423      /* test for range errors (not always needed but do it anyway) */
20424      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20425      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20426       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20427     }
20428    /* copy workspace back if necessary */
20429     if (realign) {
20430       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20431       xp = (uint64 *) *xpp;
20432     }
20433    /* update xpp and tp */
20434     xp += ni;
20435     tp += ni;
20436     *xpp = (void*)xp;
20437   }
20438   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20439 
20440 #else   /* not SX */
20441 
20442 	char *xp = (char *) *xpp;
20443 	int status = NC_NOERR;
20444 
20445 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20446 	{
20447 		int lstatus = ncx_put_ulonglong_short(xp, tp, fillp);
20448 		if (status == NC_NOERR) /* report the first encountered error */
20449 			status = lstatus;
20450 	}
20451 
20452 	*xpp = (void *)xp;
20453 	return status;
20454 #endif
20455 }
20456 
20457 int
ncx_putn_ulonglong_int(void ** xpp,size_t nelems,const int * tp,void * fillp)20458 ncx_putn_ulonglong_int(void **xpp, size_t nelems, const int *tp, void *fillp)
20459 {
20460 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20461 
20462  /* basic algorithm is:
20463   *   - ensure sane alignment of output data
20464   *   - copy (conversion happens automatically) input data
20465   *     to output
20466   *   - update tp to point at next unconverted input, and xpp to point
20467   *     at next location for converted output
20468   */
20469   long i, j, ni;
20470   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20471   uint64 *xp;
20472   int nrange = 0;         /* number of range errors */
20473   int realign = 0;        /* "do we need to fix input data alignment?" */
20474   long cxp = (long) *((char**)xpp);
20475 
20476   realign = (cxp & 7) % SIZEOF_UINT64;
20477   /* sjl: manually stripmine so we can limit amount of
20478    * vector work space reserved to LOOPCNT elements. Also
20479    * makes vectorisation easy */
20480   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20481     ni=Min(nelems-j,LOOPCNT);
20482     if (realign) {
20483       xp = tmp;
20484     } else {
20485       xp = (uint64 *) *xpp;
20486     }
20487    /* copy the next block */
20488 #pragma cdir loopcnt=LOOPCNT
20489 #pragma cdir shortloop
20490     for (i=0; i<ni; i++) {
20491       /* the normal case: */
20492       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20493      /* test for range errors (not always needed but do it anyway) */
20494      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20495      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20496       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20497     }
20498    /* copy workspace back if necessary */
20499     if (realign) {
20500       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20501       xp = (uint64 *) *xpp;
20502     }
20503    /* update xpp and tp */
20504     xp += ni;
20505     tp += ni;
20506     *xpp = (void*)xp;
20507   }
20508   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20509 
20510 #else   /* not SX */
20511 
20512 	char *xp = (char *) *xpp;
20513 	int status = NC_NOERR;
20514 
20515 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20516 	{
20517 		int lstatus = ncx_put_ulonglong_int(xp, tp, fillp);
20518 		if (status == NC_NOERR) /* report the first encountered error */
20519 			status = lstatus;
20520 	}
20521 
20522 	*xpp = (void *)xp;
20523 	return status;
20524 #endif
20525 }
20526 
20527 int
ncx_putn_ulonglong_long(void ** xpp,size_t nelems,const long * tp,void * fillp)20528 ncx_putn_ulonglong_long(void **xpp, size_t nelems, const long *tp, void *fillp)
20529 {
20530 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20531 
20532  /* basic algorithm is:
20533   *   - ensure sane alignment of output data
20534   *   - copy (conversion happens automatically) input data
20535   *     to output
20536   *   - update tp to point at next unconverted input, and xpp to point
20537   *     at next location for converted output
20538   */
20539   long i, j, ni;
20540   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20541   uint64 *xp;
20542   int nrange = 0;         /* number of range errors */
20543   int realign = 0;        /* "do we need to fix input data alignment?" */
20544   long cxp = (long) *((char**)xpp);
20545 
20546   realign = (cxp & 7) % SIZEOF_UINT64;
20547   /* sjl: manually stripmine so we can limit amount of
20548    * vector work space reserved to LOOPCNT elements. Also
20549    * makes vectorisation easy */
20550   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20551     ni=Min(nelems-j,LOOPCNT);
20552     if (realign) {
20553       xp = tmp;
20554     } else {
20555       xp = (uint64 *) *xpp;
20556     }
20557    /* copy the next block */
20558 #pragma cdir loopcnt=LOOPCNT
20559 #pragma cdir shortloop
20560     for (i=0; i<ni; i++) {
20561       /* the normal case: */
20562       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20563      /* test for range errors (not always needed but do it anyway) */
20564      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20565      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20566       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20567     }
20568    /* copy workspace back if necessary */
20569     if (realign) {
20570       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20571       xp = (uint64 *) *xpp;
20572     }
20573    /* update xpp and tp */
20574     xp += ni;
20575     tp += ni;
20576     *xpp = (void*)xp;
20577   }
20578   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20579 
20580 #else   /* not SX */
20581 
20582 	char *xp = (char *) *xpp;
20583 	int status = NC_NOERR;
20584 
20585 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20586 	{
20587 		int lstatus = ncx_put_ulonglong_long(xp, tp, fillp);
20588 		if (status == NC_NOERR) /* report the first encountered error */
20589 			status = lstatus;
20590 	}
20591 
20592 	*xpp = (void *)xp;
20593 	return status;
20594 #endif
20595 }
20596 
20597 int
ncx_putn_ulonglong_float(void ** xpp,size_t nelems,const float * tp,void * fillp)20598 ncx_putn_ulonglong_float(void **xpp, size_t nelems, const float *tp, void *fillp)
20599 {
20600 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20601 
20602  /* basic algorithm is:
20603   *   - ensure sane alignment of output data
20604   *   - copy (conversion happens automatically) input data
20605   *     to output
20606   *   - update tp to point at next unconverted input, and xpp to point
20607   *     at next location for converted output
20608   */
20609   long i, j, ni;
20610   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20611   uint64 *xp;
20612   int nrange = 0;         /* number of range errors */
20613   int realign = 0;        /* "do we need to fix input data alignment?" */
20614   long cxp = (long) *((char**)xpp);
20615 
20616   realign = (cxp & 7) % SIZEOF_UINT64;
20617   /* sjl: manually stripmine so we can limit amount of
20618    * vector work space reserved to LOOPCNT elements. Also
20619    * makes vectorisation easy */
20620   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20621     ni=Min(nelems-j,LOOPCNT);
20622     if (realign) {
20623       xp = tmp;
20624     } else {
20625       xp = (uint64 *) *xpp;
20626     }
20627    /* copy the next block */
20628 #pragma cdir loopcnt=LOOPCNT
20629 #pragma cdir shortloop
20630     for (i=0; i<ni; i++) {
20631       /* the normal case: */
20632       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20633      /* test for range errors (not always needed but do it anyway) */
20634      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20635      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20636       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20637     }
20638    /* copy workspace back if necessary */
20639     if (realign) {
20640       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20641       xp = (uint64 *) *xpp;
20642     }
20643    /* update xpp and tp */
20644     xp += ni;
20645     tp += ni;
20646     *xpp = (void*)xp;
20647   }
20648   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20649 
20650 #else   /* not SX */
20651 
20652 	char *xp = (char *) *xpp;
20653 	int status = NC_NOERR;
20654 
20655 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20656 	{
20657 		int lstatus = ncx_put_ulonglong_float(xp, tp, fillp);
20658 		if (status == NC_NOERR) /* report the first encountered error */
20659 			status = lstatus;
20660 	}
20661 
20662 	*xpp = (void *)xp;
20663 	return status;
20664 #endif
20665 }
20666 
20667 int
ncx_putn_ulonglong_double(void ** xpp,size_t nelems,const double * tp,void * fillp)20668 ncx_putn_ulonglong_double(void **xpp, size_t nelems, const double *tp, void *fillp)
20669 {
20670 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20671 
20672  /* basic algorithm is:
20673   *   - ensure sane alignment of output data
20674   *   - copy (conversion happens automatically) input data
20675   *     to output
20676   *   - update tp to point at next unconverted input, and xpp to point
20677   *     at next location for converted output
20678   */
20679   long i, j, ni;
20680   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20681   uint64 *xp;
20682   int nrange = 0;         /* number of range errors */
20683   int realign = 0;        /* "do we need to fix input data alignment?" */
20684   long cxp = (long) *((char**)xpp);
20685 
20686   realign = (cxp & 7) % SIZEOF_UINT64;
20687   /* sjl: manually stripmine so we can limit amount of
20688    * vector work space reserved to LOOPCNT elements. Also
20689    * makes vectorisation easy */
20690   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20691     ni=Min(nelems-j,LOOPCNT);
20692     if (realign) {
20693       xp = tmp;
20694     } else {
20695       xp = (uint64 *) *xpp;
20696     }
20697    /* copy the next block */
20698 #pragma cdir loopcnt=LOOPCNT
20699 #pragma cdir shortloop
20700     for (i=0; i<ni; i++) {
20701       /* the normal case: */
20702       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20703      /* test for range errors (not always needed but do it anyway) */
20704      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20705      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20706       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20707     }
20708    /* copy workspace back if necessary */
20709     if (realign) {
20710       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20711       xp = (uint64 *) *xpp;
20712     }
20713    /* update xpp and tp */
20714     xp += ni;
20715     tp += ni;
20716     *xpp = (void*)xp;
20717   }
20718   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20719 
20720 #else   /* not SX */
20721 
20722 	char *xp = (char *) *xpp;
20723 	int status = NC_NOERR;
20724 
20725 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20726 	{
20727 		int lstatus = ncx_put_ulonglong_double(xp, tp, fillp);
20728 		if (status == NC_NOERR) /* report the first encountered error */
20729 			status = lstatus;
20730 	}
20731 
20732 	*xpp = (void *)xp;
20733 	return status;
20734 #endif
20735 }
20736 
20737 int
ncx_putn_ulonglong_longlong(void ** xpp,size_t nelems,const longlong * tp,void * fillp)20738 ncx_putn_ulonglong_longlong(void **xpp, size_t nelems, const longlong *tp, void *fillp)
20739 {
20740 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20741 
20742  /* basic algorithm is:
20743   *   - ensure sane alignment of output data
20744   *   - copy (conversion happens automatically) input data
20745   *     to output
20746   *   - update tp to point at next unconverted input, and xpp to point
20747   *     at next location for converted output
20748   */
20749   long i, j, ni;
20750   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20751   uint64 *xp;
20752   int nrange = 0;         /* number of range errors */
20753   int realign = 0;        /* "do we need to fix input data alignment?" */
20754   long cxp = (long) *((char**)xpp);
20755 
20756   realign = (cxp & 7) % SIZEOF_UINT64;
20757   /* sjl: manually stripmine so we can limit amount of
20758    * vector work space reserved to LOOPCNT elements. Also
20759    * makes vectorisation easy */
20760   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20761     ni=Min(nelems-j,LOOPCNT);
20762     if (realign) {
20763       xp = tmp;
20764     } else {
20765       xp = (uint64 *) *xpp;
20766     }
20767    /* copy the next block */
20768 #pragma cdir loopcnt=LOOPCNT
20769 #pragma cdir shortloop
20770     for (i=0; i<ni; i++) {
20771       /* the normal case: */
20772       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20773      /* test for range errors (not always needed but do it anyway) */
20774      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20775      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20776       nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
20777     }
20778    /* copy workspace back if necessary */
20779     if (realign) {
20780       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20781       xp = (uint64 *) *xpp;
20782     }
20783    /* update xpp and tp */
20784     xp += ni;
20785     tp += ni;
20786     *xpp = (void*)xp;
20787   }
20788   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20789 
20790 #else   /* not SX */
20791 
20792 	char *xp = (char *) *xpp;
20793 	int status = NC_NOERR;
20794 
20795 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20796 	{
20797 		int lstatus = ncx_put_ulonglong_longlong(xp, tp, fillp);
20798 		if (status == NC_NOERR) /* report the first encountered error */
20799 			status = lstatus;
20800 	}
20801 
20802 	*xpp = (void *)xp;
20803 	return status;
20804 #endif
20805 }
20806 
20807 int
ncx_putn_ulonglong_uchar(void ** xpp,size_t nelems,const uchar * tp,void * fillp)20808 ncx_putn_ulonglong_uchar(void **xpp, size_t nelems, const uchar *tp, void *fillp)
20809 {
20810 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20811 
20812  /* basic algorithm is:
20813   *   - ensure sane alignment of output data
20814   *   - copy (conversion happens automatically) input data
20815   *     to output
20816   *   - update tp to point at next unconverted input, and xpp to point
20817   *     at next location for converted output
20818   */
20819   long i, j, ni;
20820   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20821   uint64 *xp;
20822   int nrange = 0;         /* number of range errors */
20823   int realign = 0;        /* "do we need to fix input data alignment?" */
20824   long cxp = (long) *((char**)xpp);
20825 
20826   realign = (cxp & 7) % SIZEOF_UINT64;
20827   /* sjl: manually stripmine so we can limit amount of
20828    * vector work space reserved to LOOPCNT elements. Also
20829    * makes vectorisation easy */
20830   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20831     ni=Min(nelems-j,LOOPCNT);
20832     if (realign) {
20833       xp = tmp;
20834     } else {
20835       xp = (uint64 *) *xpp;
20836     }
20837    /* copy the next block */
20838 #pragma cdir loopcnt=LOOPCNT
20839 #pragma cdir shortloop
20840     for (i=0; i<ni; i++) {
20841       /* the normal case: */
20842       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20843      /* test for range errors (not always needed but do it anyway) */
20844      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20845      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20846       nrange += tp[i] > X_UINT64_MAX ;
20847     }
20848    /* copy workspace back if necessary */
20849     if (realign) {
20850       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20851       xp = (uint64 *) *xpp;
20852     }
20853    /* update xpp and tp */
20854     xp += ni;
20855     tp += ni;
20856     *xpp = (void*)xp;
20857   }
20858   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20859 
20860 #else   /* not SX */
20861 
20862 	char *xp = (char *) *xpp;
20863 	int status = NC_NOERR;
20864 
20865 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20866 	{
20867 		int lstatus = ncx_put_ulonglong_uchar(xp, tp, fillp);
20868 		if (status == NC_NOERR) /* report the first encountered error */
20869 			status = lstatus;
20870 	}
20871 
20872 	*xpp = (void *)xp;
20873 	return status;
20874 #endif
20875 }
20876 
20877 int
ncx_putn_ulonglong_ushort(void ** xpp,size_t nelems,const ushort * tp,void * fillp)20878 ncx_putn_ulonglong_ushort(void **xpp, size_t nelems, const ushort *tp, void *fillp)
20879 {
20880 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20881 
20882  /* basic algorithm is:
20883   *   - ensure sane alignment of output data
20884   *   - copy (conversion happens automatically) input data
20885   *     to output
20886   *   - update tp to point at next unconverted input, and xpp to point
20887   *     at next location for converted output
20888   */
20889   long i, j, ni;
20890   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20891   uint64 *xp;
20892   int nrange = 0;         /* number of range errors */
20893   int realign = 0;        /* "do we need to fix input data alignment?" */
20894   long cxp = (long) *((char**)xpp);
20895 
20896   realign = (cxp & 7) % SIZEOF_UINT64;
20897   /* sjl: manually stripmine so we can limit amount of
20898    * vector work space reserved to LOOPCNT elements. Also
20899    * makes vectorisation easy */
20900   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20901     ni=Min(nelems-j,LOOPCNT);
20902     if (realign) {
20903       xp = tmp;
20904     } else {
20905       xp = (uint64 *) *xpp;
20906     }
20907    /* copy the next block */
20908 #pragma cdir loopcnt=LOOPCNT
20909 #pragma cdir shortloop
20910     for (i=0; i<ni; i++) {
20911       /* the normal case: */
20912       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20913      /* test for range errors (not always needed but do it anyway) */
20914      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20915      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20916       nrange += tp[i] > X_UINT64_MAX ;
20917     }
20918    /* copy workspace back if necessary */
20919     if (realign) {
20920       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20921       xp = (uint64 *) *xpp;
20922     }
20923    /* update xpp and tp */
20924     xp += ni;
20925     tp += ni;
20926     *xpp = (void*)xp;
20927   }
20928   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20929 
20930 #else   /* not SX */
20931 
20932 	char *xp = (char *) *xpp;
20933 	int status = NC_NOERR;
20934 
20935 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
20936 	{
20937 		int lstatus = ncx_put_ulonglong_ushort(xp, tp, fillp);
20938 		if (status == NC_NOERR) /* report the first encountered error */
20939 			status = lstatus;
20940 	}
20941 
20942 	*xpp = (void *)xp;
20943 	return status;
20944 #endif
20945 }
20946 
20947 int
ncx_putn_ulonglong_uint(void ** xpp,size_t nelems,const uint * tp,void * fillp)20948 ncx_putn_ulonglong_uint(void **xpp, size_t nelems, const uint *tp, void *fillp)
20949 {
20950 #if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64
20951 
20952  /* basic algorithm is:
20953   *   - ensure sane alignment of output data
20954   *   - copy (conversion happens automatically) input data
20955   *     to output
20956   *   - update tp to point at next unconverted input, and xpp to point
20957   *     at next location for converted output
20958   */
20959   long i, j, ni;
20960   uint64 tmp[LOOPCNT];        /* in case input is misaligned */
20961   uint64 *xp;
20962   int nrange = 0;         /* number of range errors */
20963   int realign = 0;        /* "do we need to fix input data alignment?" */
20964   long cxp = (long) *((char**)xpp);
20965 
20966   realign = (cxp & 7) % SIZEOF_UINT64;
20967   /* sjl: manually stripmine so we can limit amount of
20968    * vector work space reserved to LOOPCNT elements. Also
20969    * makes vectorisation easy */
20970   for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
20971     ni=Min(nelems-j,LOOPCNT);
20972     if (realign) {
20973       xp = tmp;
20974     } else {
20975       xp = (uint64 *) *xpp;
20976     }
20977    /* copy the next block */
20978 #pragma cdir loopcnt=LOOPCNT
20979 #pragma cdir shortloop
20980     for (i=0; i<ni; i++) {
20981       /* the normal case: */
20982       xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
20983      /* test for range errors (not always needed but do it anyway) */
20984      /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
20985      /* if tp is unsigned, we need not check if tp[i] < X__MIN */
20986       nrange += tp[i] > X_UINT64_MAX ;
20987     }
20988    /* copy workspace back if necessary */
20989     if (realign) {
20990       memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
20991       xp = (uint64 *) *xpp;
20992     }
20993    /* update xpp and tp */
20994     xp += ni;
20995     tp += ni;
20996     *xpp = (void*)xp;
20997   }
20998   return nrange == 0 ? NC_NOERR : NC_ERANGE;
20999 
21000 #else   /* not SX */
21001 
21002 	char *xp = (char *) *xpp;
21003 	int status = NC_NOERR;
21004 
21005 	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
21006 	{
21007 		int lstatus = ncx_put_ulonglong_uint(xp, tp, fillp);
21008 		if (status == NC_NOERR) /* report the first encountered error */
21009 			status = lstatus;
21010 	}
21011 
21012 	*xpp = (void *)xp;
21013 	return status;
21014 #endif
21015 }
21016 
21017 
21018 
21019 /*
21020  * Other aggregate conversion functions.
21021  */
21022 
21023 /* text */
21024 
21025 int
ncx_getn_text(const void ** xpp,size_t nelems,char * tp)21026 ncx_getn_text(const void **xpp, size_t nelems, char *tp)
21027 {
21028 	(void) memcpy(tp, *xpp, (size_t)nelems);
21029 	*xpp = (void *)((char *)(*xpp) + nelems);
21030 	return NC_NOERR;
21031 
21032 }
21033 
21034 int
ncx_pad_getn_text(const void ** xpp,size_t nelems,char * tp)21035 ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
21036 {
21037 	size_t rndup = nelems % X_ALIGN;
21038 
21039 	if (rndup)
21040 		rndup = X_ALIGN - rndup;
21041 
21042 	(void) memcpy(tp, *xpp, (size_t)nelems);
21043 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
21044 
21045 	return NC_NOERR;
21046 
21047 }
21048 
21049 int
ncx_putn_text(void ** xpp,size_t nelems,const char * tp)21050 ncx_putn_text(void **xpp, size_t nelems, const char *tp)
21051 {
21052 	(void) memcpy(*xpp, tp, (size_t)nelems);
21053 	*xpp = (void *)((char *)(*xpp) + nelems);
21054 
21055 	return NC_NOERR;
21056 
21057 }
21058 
21059 int
ncx_pad_putn_text(void ** xpp,size_t nelems,const char * tp)21060 ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
21061 {
21062 	size_t rndup = nelems % X_ALIGN;
21063 
21064 	if (rndup)
21065 		rndup = X_ALIGN - rndup;
21066 
21067 	(void) memcpy(*xpp, tp, (size_t)nelems);
21068 	*xpp = (void *)((char *)(*xpp) + nelems);
21069 
21070 	if (rndup)
21071 	{
21072 		(void) memcpy(*xpp, nada, (size_t)rndup);
21073 		*xpp = (void *)((char *)(*xpp) + rndup);
21074 	}
21075 
21076 	return NC_NOERR;
21077 
21078 }
21079 
21080 
21081 /* opaque */
21082 
21083 int
ncx_getn_void(const void ** xpp,size_t nelems,void * tp)21084 ncx_getn_void(const void **xpp, size_t nelems, void *tp)
21085 {
21086 	(void) memcpy(tp, *xpp, (size_t)nelems);
21087 	*xpp = (void *)((char *)(*xpp) + nelems);
21088 	return NC_NOERR;
21089 
21090 }
21091 
21092 int
ncx_pad_getn_void(const void ** xpp,size_t nelems,void * tp)21093 ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
21094 {
21095 	size_t rndup = nelems % X_ALIGN;
21096 
21097 	if (rndup)
21098 		rndup = X_ALIGN - rndup;
21099 
21100 	(void) memcpy(tp, *xpp, (size_t)nelems);
21101 	*xpp = (void *)((char *)(*xpp) + nelems + rndup);
21102 
21103 	return NC_NOERR;
21104 
21105 }
21106 
21107 int
ncx_putn_void(void ** xpp,size_t nelems,const void * tp)21108 ncx_putn_void(void **xpp, size_t nelems, const void *tp)
21109 {
21110 	(void) memcpy(*xpp, tp, (size_t)nelems);
21111 	*xpp = (void *)((char *)(*xpp) + nelems);
21112 
21113 	return NC_NOERR;
21114 
21115 }
21116 
21117 int
ncx_pad_putn_void(void ** xpp,size_t nelems,const void * tp)21118 ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
21119 {
21120 	size_t rndup = nelems % X_ALIGN;
21121 
21122 	if (rndup)
21123 		rndup = X_ALIGN - rndup;
21124 
21125 	(void) memcpy(*xpp, tp, (size_t)nelems);
21126 	*xpp = (void *)((char *)(*xpp) + nelems);
21127 
21128 	if (rndup)
21129 	{
21130 		(void) memcpy(*xpp, nada, (size_t)rndup);
21131 		*xpp = (void *)((char *)(*xpp) + rndup);
21132 	}
21133 
21134 	return NC_NOERR;
21135 
21136 }
21137