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