<
1/* Do not edit this file. It is produced from the corresponding .m4 source */
2/*
3 * Copyright 1996, University Corporation for Atmospheric Research
4 * See netcdf/COPYRIGHT file for copying and redistribution conditions.
5 *
6 *  This file contains some routines derived from code
7 * which is copyrighted by Sun Microsystems, Inc.
8 * The "#ifdef vax" versions of
9 *  ncx_put_float_float()
10 *  ncx_get_float_float()
11 *  ncx_put_double_double()
12 *  ncx_get_double_double()
13 *  ncx_putn_float_float()
14 *  ncx_getn_float_float()
15 *  ncx_putn_double_double()
16 *  ncx_getn_double_double()
17 *  are derived from xdr_float() and xdr_double() routines
18 * in the freely available, copyrighted Sun RPCSRC 3.9
19 * distribution, xdr_float.c.
20 *  Our "value added" is that these are always memory to memory,
21 * they handle IEEE subnormals properly, and their "n" versions
22 * operate speedily on arrays.
23 */
24/* $Id: ncx.m4 2795 2014-10-27 23:12:51Z wkliao $ */
25
26/*
27 * An external data representation interface.
28 */
29
30#pragma GCC diagnostic ignored "-Wdeprecated"
31
32#include "ncx.h"
33#include "nc3dispatch.h"
34#include <string.h>
35#include <limits.h>
36
37/* alias poorly named limits.h macros */
38#define  SHORT_MAX  SHRT_MAX
39#define  SHORT_MIN  SHRT_MIN
40#define USHORT_MAX USHRT_MAX
41#ifndef LLONG_MAX
42#   define LLONG_MAX 9223372036854775807LL
43#   define LLONG_MIN (-LLONG_MAX - 1LL)
44#   define ULLONG_MAX 18446744073709551615ULL
45#endif
46#ifndef LONG_LONG_MAX
47#define LONG_LONG_MAX LLONG_MAX
48#endif
49#ifndef LONGLONG_MAX
50#define LONGLONG_MAX LONG_LONG_MAX
51#endif
52#ifndef LONG_LONG_MIN
53#define LONG_LONG_MIN LLONG_MIN
54#endif
55#ifndef LONGLONG_MIN
56#define LONGLONG_MIN LONG_LONG_MIN
57#endif
58#ifndef ULONG_LONG_MAX
59#define ULONG_LONG_MAX ULLONG_MAX
60#endif
61#ifndef ULONGLONG_MAX
62#define ULONGLONG_MAX ULONG_LONG_MAX
63#endif
64#include <float.h>
65#ifndef FLT_MAX /* This POSIX macro missing on some systems */
66# ifndef NO_IEEE_FLOAT
67# define FLT_MAX 3.40282347e+38f
68# else
69# error "You will need to define FLT_MAX"
70# endif
71#endif
72/* alias poorly named float.h macros */
73#define FLOAT_MAX FLT_MAX
74#define FLOAT_MIN (-FLT_MAX)
75#define DOUBLE_MAX DBL_MAX
76#define DOUBLE_MIN (-DBL_MAX)
77#define FLOAT_MAX_EXP FLT_MAX_EXP
78#define DOUBLE_MAX_EXP DBL_MAX_EXP
79#include <assert.h>
80#define UCHAR_MIN 0
81#define Min(a,b) ((a) < (b) ? (a) : (b))
82#define Max(a,b) ((a) > (b) ? (a) : (b))
83
84#ifndef SIZEOF_USHORT
85#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
86#endif
87#ifndef SIZEOF_UINT
88#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
89#endif
90#ifndef SIZEOF_ULONG_LONG
91#define SIZEOF_ULONG_LONG SIZEOF_UNSIGNED_LONG_LONG
92#endif
93
94/*
95 * If the machine's float domain is "smaller" than the external one
96 * use the machine domain
97 */
98#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */
99#undef X_FLOAT_MAX
100# define X_FLOAT_MAX FLT_MAX
101#undef X_FLOAT_MIN
102# define X_FLOAT_MIN (-X_FLOAT_MAX)
103#endif
104
105#if _SX /* NEC SUPER UX */
106#define LOOPCNT 256    /* must be no longer than hardware vector length */
107#if _INT64
108#undef  INT_MAX /* workaround cpp bug */
109#define INT_MAX  X_INT_MAX
110#undef  INT_MIN /* workaround cpp bug */
111#define INT_MIN  X_INT_MIN
112#undef  LONG_MAX /* workaround cpp bug */
113#define LONG_MAX  X_INT_MAX
114#undef  LONG_MIN /* workaround cpp bug */
115#define LONG_MIN  X_INT_MIN
116#elif _LONG64
117#undef  LONG_MAX /* workaround cpp bug */
118#define LONG_MAX  4294967295L
119#undef  LONG_MIN /* workaround cpp bug */
120#define LONG_MIN -4294967295L
121#endif
122#if !_FLOAT0
123#error "FLOAT1 and FLOAT2 not supported"
124#endif
125#endif /* _SX */
126
127static const char nada[X_ALIGN] = {0, 0, 0, 0};
128
129#ifndef WORDS_BIGENDIAN
130/* LITTLE_ENDIAN: DEC and intel */
131/*
132 * Routines to convert to BIGENDIAN.
133 * Optimize the swapn?b() and swap?b() routines aggressivly.
134 */
135
136#define SWAP2(a) ( (((a) & 0xff) << 8) | \
137 (((a) >> 8) & 0xff) )
138
139#define SWAP4(a) ( ((a) << 24) | \
140 (((a) <<  8) & 0x00ff0000) | \
141 (((a) >>  8) & 0x0000ff00) | \
142 (((a) >> 24) & 0x000000ff) )
143
144
145static void
146swapn2b(void *dst, const void *src, size_t nn)
147{
148 char *op = dst;
149 const char *ip = src;
150
151/* unroll the following to reduce loop overhead
152 *
153 * while(nn-- != 0)
154 * {
155 * *op++ = *(++ip);
156 * *op++ = *(ip++ -1);
157 * }
158 */
159 while(nn > 3)
160 {
161 *op++ = *(++ip);
162 *op++ = *(ip++ -1);
163 *op++ = *(++ip);
164 *op++ = *(ip++ -1);
165 *op++ = *(++ip);
166 *op++ = *(ip++ -1);
167 *op++ = *(++ip);
168 *op++ = *(ip++ -1);
169 nn -= 4;
170 }
171 while(nn-- > 0)
172 {
173 *op++ = *(++ip);
174 *op++ = *(ip++ -1);
175 }
176}
177
178# ifndef vax
179void
180swap4b(void *dst, const void *src)
181{
182    unsigned int *op = dst;
183    const char *ip = src;
184    unsigned int tempIn;
185    unsigned int tempOut;
186
187    tempIn = *(unsigned int *)(ip+0);
188    tempOut =
189    ( tempIn << 24) |
190    ((tempIn & 0x0000ff00) << 8) |
191    ((tempIn & 0x00ff0000) >> 8) |
192    ( tempIn >> 24);
193
194    *(float *)op = *(float *)(&tempOut);
195}
196# endif /* !vax */
197
198static void
199swapn4b(void *dst, const void *src, size_t nn)
200{
201 char *op = dst;
202 const char *ip = src;
203
204/* unroll the following to reduce loop overhead
205 * while(nn-- != 0)
206 * {
207 * op[0] = ip[3];
208 * op[1] = ip[2];
209 * op[2] = ip[1];
210 * op[3] = ip[0];
211 * op += 4;
212 * ip += 4;
213 * }
214 */
215 while(nn > 3)
216 {
217 op[0] = ip[3];
218 op[1] = ip[2];
219 op[2] = ip[1];
220 op[3] = ip[0];
221 op[4] = ip[7];
222 op[5] = ip[6];
223 op[6] = ip[5];
224 op[7] = ip[4];
225 op[8] = ip[11];
226 op[9] = ip[10];
227 op[10] = ip[9];
228 op[11] = ip[8];
229 op[12] = ip[15];
230 op[13] = ip[14];
231 op[14] = ip[13];
232 op[15] = ip[12];
233 op += 16;
234 ip += 16;
235 nn -= 4;
236 }
237 while(nn-- > 0)
238 {
239 op[0] = ip[3];
240 op[1] = ip[2];
241 op[2] = ip[1];
242 op[3] = ip[0];
243 op += 4;
244 ip += 4;
245 }
246}
247
248# ifndef vax
249static void
250swap8b(void *dst, const void *src)
251{
252 char *op = dst;
253 const char *ip = src;
254#  ifndef FLOAT_WORDS_BIGENDIAN
255 op[0] = ip[7];
256 op[1] = ip[6];
257 op[2] = ip[5];
258 op[3] = ip[4];
259 op[4] = ip[3];
260 op[5] = ip[2];
261 op[6] = ip[1];
262 op[7] = ip[0];
263#  else
264 op[0] = ip[3];
265 op[1] = ip[2];
266 op[2] = ip[1];
267 op[3] = ip[0];
268 op[4] = ip[7];
269 op[5] = ip[6];
270 op[6] = ip[5];
271 op[7] = ip[4];
272#  endif
273}
274# endif /* !vax */
275
276# ifndef vax
277static void
278swapn8b(void *dst, const void *src, size_t nn)
279{
280 char *op = dst;
281 const char *ip = src;
282
283/* unroll the following to reduce loop overhead
284 * while(nn-- != 0)
285 * {
286 * op[0] = ip[7];
287 * op[1] = ip[6];
288 * op[2] = ip[5];
289 * op[3] = ip[4];
290 * op[4] = ip[3];
291 * op[5] = ip[2];
292 * op[6] = ip[1];
293 * op[7] = ip[0];
294 * op += 8;
295 * ip += 8;
296 * }
297 */
298#  ifndef FLOAT_WORDS_BIGENDIAN
299 while(nn > 1)
300 {
301 op[0] = ip[7];
302 op[1] = ip[6];
303 op[2] = ip[5];
304 op[3] = ip[4];
305 op[4] = ip[3];
306 op[5] = ip[2];
307 op[6] = ip[1];
308 op[7] = ip[0];
309 op[8] = ip[15];
310 op[9] = ip[14];
311 op[10] = ip[13];
312 op[11] = ip[12];
313 op[12] = ip[11];
314 op[13] = ip[10];
315 op[14] = ip[9];
316 op[15] = ip[8];
317 op += 16;
318 ip += 16;
319 nn -= 2;
320 }
321 while(nn-- != 0)
322 {
323 op[0] = ip[7];
324 op[1] = ip[6];
325 op[2] = ip[5];
326 op[3] = ip[4];
327 op[4] = ip[3];
328 op[5] = ip[2];
329 op[6] = ip[1];
330 op[7] = ip[0];
331 op += 8;
332 ip += 8;
333 }
334#  else
335 while(nn-- != 0)
336 {
337 op[0] = ip[3];
338 op[1] = ip[2];
339 op[2] = ip[1];
340 op[3] = ip[0];
341 op[4] = ip[7];
342 op[5] = ip[6];
343 op[6] = ip[5];
344 op[7] = ip[4];
345 op += 8;
346 ip += 8;
347 }
348#  endif
349}
350# endif /* !vax */
351
352#endif /* LITTLE_ENDIAN */
353
354
355
356
357
358
359
360
361
362
363
364
365/*
366 * Primitive numeric conversion functions.
367 */
368
369
370
371
372
373/* x_schar */
374/* x_uchar */
375
376/* We don't implement any x_schar and x_uchar primitives. */
377
378
379/* x_short -------------------------------------------------------------------*/
380
381#if SHORT_MAX == X_SHORT_MAX
382typedef short ix_short;
383#define SIZEOF_IX_SHORT SIZEOF_SHORT
384#define IX_SHORT_MAX SHORT_MAX
385#elif INT_MAX >= X_SHORT_MAX
386typedef int ix_short;
387#define SIZEOF_IX_SHORT SIZEOF_INT
388#define IX_SHORT_MAX INT_MAX
389#elif LONG_MAX >= X_SHORT_MAX
390typedef long ix_short;
391#define SIZEOF_IX_SHORT SIZEOF_LONG
392#define IX_SHORT_MAX LONG_MAX
393#elif LLONG_MAX >= X_SHORT_MAX
394typedef long long ix_short;
395#define SIZEOF_IX_SHORT SIZEOF_LONG_LONG
396#define IX_SHORT_MAX LLONG_MAX
397#else
398#error "ix_short implementation"
399#endif
400
401static void
402get_ix_short(const void *xpix_short *ip)
403{
404 const uchar *cp = (const uchar *) xp;
405 *ip = *cp++ << 8;
406#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
407 if(*ip & 0x8000)
408 {
409 /* extern is negative */
410 *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
411 }
412#endif
413 *ip |= *cp;
414}
415
416static void
417put_ix_short(void *xp, const ix_short *ip)
418{
419 uchar *cp = (uchar *) xp;
420 *cp++ = (*ip) >> 8;
421 *cp = (*ip) & 0xff;
422}
423
424static int
425ncx_get_short_schar(const void *xpschar *ip)
426{
427 ix_short xx;
428 get_ix_short(xp, &xx);
429 *ip = (scharxx;
430#if IX_SHORT_MAX > SCHAR_MAX
431 if (xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE;
432#endif
433
434 return NC_NOERR;
435}
436
437static int
438ncx_get_short_short(const void *xp, short *ip)
439{
440#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
441 get_ix_short(xp, (ix_short *)ip);
442 return NC_NOERR;
443#else
444 ix_short xx;
445 get_ix_short(xp, &xx);
446 *ip = (short) xx;
447#if IX_SHORT_MAX > SHORT_MAX
448 if (xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE;
449#endif
450
451#endif
452 return NC_NOERR;
453}
454
455static int
456ncx_get_short_int(const void *xp, int *ip)
457{
458#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
459 get_ix_short(xp, (ix_short *)ip);
460 return NC_NOERR;
461#else
462 ix_short xx;
463 get_ix_short(xp, &xx);
464 *ip = (int) xx;
465#if IX_SHORT_MAX > INT_MAX
466 if (xx > INT_MAX || xx < INT_MIN) return NC_ERANGE;
467#endif
468
469#endif
470 return NC_NOERR;
471}
472
473static int
474ncx_get_short_longlong(const void *xplonglong *ip)
475{
476#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
477 get_ix_short(xp, (ix_short *)ip);
478 return NC_NOERR;
479#else
480 ix_short xx;
481 get_ix_short(xp, &xx);
482 *ip = (longlongxx;
483#if IX_SHORT_MAX > LONGLONG_MAX
484 if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) return NC_ERANGE;
485#endif
486
487#endif
488 return NC_NOERR;
489}
490
491static int
492ncx_get_short_ushort(const void *xpushort *ip)
493{
494 ix_short xx;
495 get_ix_short(xp, &xx);
496 *ip = (ushortxx;
497#if IX_SHORT_MAX > USHORT_MAX
498 if (xx > USHORT_MAX) return NC_ERANGE;
499#endif
500 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
501 return NC_NOERR;
502}
503
504static int
505ncx_get_short_uchar(const void *xpuchar *ip)
506{
507 ix_short xx;
508 get_ix_short(xp, &xx);
509 *ip = (ucharxx;
510#if IX_SHORT_MAX > UCHAR_MAX
511 if (xx > UCHAR_MAX) return NC_ERANGE;
512#endif
513 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
514 return NC_NOERR;
515}
516
517static int
518ncx_get_short_uint(const void *xpuint *ip)
519{
520 ix_short xx;
521 get_ix_short(xp, &xx);
522 *ip = (uintxx;
523#if IX_SHORT_MAX > UINT_MAX
524 if (xx > UINT_MAX) return NC_ERANGE;
525#endif
526 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
527 return NC_NOERR;
528}
529
530static int
531ncx_get_short_ulonglong(const void *xpulonglong *ip)
532{
533 ix_short xx;
534 get_ix_short(xp, &xx);
535 *ip = (ulonglongxx;
536#if IX_SHORT_MAX > ULONGLONG_MAX
537 if (xx > ULONGLONG_MAX) return NC_ERANGE;
538#endif
539 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
540 return NC_NOERR;
541}
542
543static int
544ncx_get_short_float(const void *xp, float *ip)
545{
546 ix_short xx;
547 get_ix_short(xp, &xx);
548 *ip = (float) xx;
549
550 return NC_NOERR;
551}
552
553static int
554ncx_get_short_double(const void *xp, double *ip)
555{
556 ix_short xx;
557 get_ix_short(xp, &xx);
558 *ip = (double) xx;
559
560 return NC_NOERR;
561}
562
563
564static int
565ncx_put_short_schar(void *xp, const schar *ip)
566{
567 uchar *cp = (uchar *) xp;
568 if(*ip & 0x80)
569 *cp++ = 0xff;
570 else
571 *cp++ = 0;
572 *cp = (uchar)(signed)*ip;
573 return NC_NOERR;
574}
575
576static int
577ncx_put_short_uchar(void *xp, const uchar *ip)
578{
579 uchar *cp = (uchar *) xp;
580 *cp++ = 0;
581 *cp = *ip;
582 return NC_NOERR;
583}
584
585static int
586ncx_put_short_short(void *xp, const short *ip)
587{
588#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
589 put_ix_short(xp, (const ix_short *)ip);
590 return NC_NOERR;
591#else
592 ix_short xx = (ix_short)*ip;
593 put_ix_short(xp, &xx);
594#if IX_SHORT_MAX < SHORT_MAX
595 if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE;
596#endif
597
598#endif
599 return NC_NOERR;
600}
601
602static int
603ncx_put_short_int(void *xp, const int *ip)
604{
605#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
606 put_ix_short(xp, (const ix_short *)ip);
607 return NC_NOERR;
608#else
609 ix_short xx = (ix_short)*ip;
610 put_ix_short(xp, &xx);
611#if IX_SHORT_MAX < INT_MAX
612 if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE;
613#endif
614
615#endif
616 return NC_NOERR;
617}
618
619static int
620ncx_put_short_longlong(void *xp, const longlong *ip)
621{
622#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
623 put_ix_short(xp, (const ix_short *)ip);
624 return NC_NOERR;
625#else
626 ix_short xx = (ix_short)*ip;
627 put_ix_short(xp, &xx);
628#if IX_SHORT_MAX < LONGLONG_MAX
629 if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE;
630#endif
631
632#endif
633 return NC_NOERR;
634}
635
636static int
637ncx_put_short_ushort(void *xp, const ushort *ip)
638{
639 ix_short xx = (ix_short)*ip;
640 put_ix_short(xp, &xx);
641#if IX_SHORT_MAX < USHORT_MAX
642 if (*ip > IX_SHORT_MAX) return NC_ERANGE;
643#endif
644
645 return NC_NOERR;
646}
647
648static int
649ncx_put_short_uint(void *xp, const uint *ip)
650{
651 ix_short xx = (ix_short)*ip;
652 put_ix_short(xp, &xx);
653#if IX_SHORT_MAX < UINT_MAX
654 if (*ip > IX_SHORT_MAX) return NC_ERANGE;
655#endif
656
657 return NC_NOERR;
658}
659
660static int
661ncx_put_short_ulonglong(void *xp, const ulonglong *ip)
662{
663 ix_short xx = (ix_short)*ip;
664 put_ix_short(xp, &xx);
665#if IX_SHORT_MAX < ULONGLONG_MAX
666 if (*ip > IX_SHORT_MAX) return NC_ERANGE;
667#endif
668
669 return NC_NOERR;
670}
671
672static int
673ncx_put_short_float(void *xp, const float *ip)
674{
675 ix_short xx = (ix_short)*ip;
676 put_ix_short(xp, &xx);
677 if(*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) return NC_ERANGE;
678 return NC_NOERR;
679}
680
681static int
682ncx_put_short_double(void *xp, const double *ip)
683{
684 ix_short xx = (ix_short)*ip;
685 put_ix_short(xp, &xx);
686 if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE;
687 return NC_NOERR;
688}
689
690
691/* x_ushort ------------------------------------------------------------------*/
692
693#if USHORT_MAX == X_USHORT_MAX
694typedef unsigned short ix_ushort;
695#define SIZEOF_IX_USHORT SIZEOF_USHORT
696#define IX_USHORT_MAX USHORT_MAX
697#elif UINT_MAX >= X_USHORT_MAX
698typedef unsigned int ix_ushort;
699#define SIZEOF_IX_USHORT SIZEOF_UINT
700#define IX_USHORT_MAX UINT_MAX
701#elif ULONG_MAX >= X_USHORT_MAX
702typedef unsigned long ix_ushort;
703#define SIZEOF_IX_USHORT SIZEOF_ULONG
704#define IX_USHORT_MAX ULONG_MAX
705#elif ULLONG_MAX >= X_USHORT_MAX
706typedef unsigned long long ix_ushort;
707#define SIZEOF_IX_USHORT SIZEOF_ULONG_LONG
708#define IX_USHORT_MAX ULLONG_MAX
709#else
710#error "ix_ushort implementation"
711#endif
712
713static void
714get_ix_ushort(const void *xpix_ushort *ip)
715{
716 const uchar *cp = (const uchar *) xp;
717 *ip = *cp++ << 8;
718#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
719 if(*ip & 0x8000)
720 {
721 /* extern is negative */
722 *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
723 }
724#endif
725 *ip |= *cp;
726}
727
728static void
729put_ix_ushort(void *xp, const ix_ushort *ip)
730{
731 uchar *cp = (uchar *) xp;
732 *cp++ = (*ip) >> 8;
733 *cp = (*ip) & 0xff;
734}
735
736static int
737ncx_get_ushort_schar(const void *xpschar *ip)
738{
739 ix_ushort xx;
740 get_ix_ushort(xp, &xx);
741 *ip = (scharxx;
742#if IX_USHORT_MAX > SCHAR_MAX
743 if (xx > SCHAR_MAX) return NC_ERANGE;
744#endif
745
746 return NC_NOERR;
747}
748
749static int
750ncx_get_ushort_short(const void *xp, short *ip)
751{
752 ix_ushort xx;
753 get_ix_ushort(xp, &xx);
754 *ip = (short) xx;
755#if IX_USHORT_MAX > SHORT_MAX
756 if (xx > SHORT_MAX) return NC_ERANGE;
757#endif
758
759 return NC_NOERR;
760}
761
762static int
763ncx_get_ushort_int(const void *xp, int *ip)
764{
765 ix_ushort xx;
766 get_ix_ushort(xp, &xx);
767 *ip = (int) xx;
768#if IX_USHORT_MAX > INT_MAX
769 if (xx > INT_MAX) return NC_ERANGE;
770#endif
771
772 return NC_NOERR;
773}
774
775static int
776ncx_get_ushort_longlong(const void *xplonglong *ip)
777{
778 ix_ushort xx;
779 get_ix_ushort(xp, &xx);
780 *ip = (longlongxx;
781#if IX_USHORT_MAX > LONGLONG_MAX
782 if (xx > LONGLONG_MAX) return NC_ERANGE;
783#endif
784
785 return NC_NOERR;
786}
787
788static int
789ncx_get_ushort_ushort(const void *xpushort *ip)
790{
791#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
792 get_ix_ushort(xp, (ix_ushort *)ip);
793 return NC_NOERR;
794#else
795 ix_ushort xx;
796 get_ix_ushort(xp, &xx);
797 *ip = (ushortxx;
798#if IX_USHORT_MAX > USHORT_MAX
799 if (xx > USHORT_MAX) return NC_ERANGE;
800#endif
801
802#endif
803 return NC_NOERR;
804}
805
806static int
807ncx_get_ushort_uchar(const void *xpuchar *ip)
808{
809#if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
810 get_ix_ushort(xp, (ix_ushort *)ip);
811 return NC_NOERR;
812#else
813 ix_ushort xx;
814 get_ix_ushort(xp, &xx);
815 *ip = (ucharxx;
816#if IX_USHORT_MAX > UCHAR_MAX
817 if (xx > UCHAR_MAX) return NC_ERANGE;
818#endif
819
820#endif
821 return NC_NOERR;
822}
823
824static int
825ncx_get_ushort_uint(const void *xpuint *ip)
826{
827#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
828 get_ix_ushort(xp, (ix_ushort *)ip);
829 return NC_NOERR;
830#else
831 ix_ushort xx;
832 get_ix_ushort(xp, &xx);
833 *ip = (uintxx;
834#if IX_USHORT_MAX > UINT_MAX
835 if (xx > UINT_MAX) return NC_ERANGE;
836#endif
837
838#endif
839 return NC_NOERR;
840}
841
842static int
843ncx_get_ushort_ulonglong(const void *xpulonglong *ip)
844{
845#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
846 get_ix_ushort(xp, (ix_ushort *)ip);
847 return NC_NOERR;
848#else
849 ix_ushort xx;
850 get_ix_ushort(xp, &xx);
851 *ip = (ulonglongxx;
852#if IX_USHORT_MAX > ULONGLONG_MAX
853 if (xx > ULONGLONG_MAX) return NC_ERANGE;
854#endif
855
856#endif
857 return NC_NOERR;
858}
859
860static int
861ncx_get_ushort_float(const void *xp, float *ip)
862{
863 ix_ushort xx;
864 get_ix_ushort(xp, &xx);
865 *ip = (float) xx;
866
867 return NC_NOERR;
868}
869
870static int
871ncx_get_ushort_double(const void *xp, double *ip)
872{
873 ix_ushort xx;
874 get_ix_ushort(xp, &xx);
875 *ip = (double) xx;
876
877 return NC_NOERR;
878}
879
880
881static int
882ncx_put_ushort_schar(void *xp, const schar *ip)
883{
884 uchar *cp = (uchar *) xp;
885 if(*ip & 0x80)
886 *cp++ = 0xff;
887 else
888 *cp++ = 0;
889 *cp = (uchar)(signed)*ip;
890        if (*ip < 0) return NC_ERANGE;
891
892 return NC_NOERR;
893}
894
895static int
896ncx_put_ushort_uchar(void *xp, const uchar *ip)
897{
898 uchar *cp = (uchar *) xp;
899 *cp++ = 0;
900 *cp = *ip;
901 return NC_NOERR;
902}
903
904static int
905ncx_put_ushort_short(void *xp, const short *ip)
906{
907 ix_ushort xx = (ix_ushort)*ip;
908 put_ix_ushort(xp, &xx);
909#if IX_USHORT_MAX < SHORT_MAX
910 if (*ip > IX_USHORT_MAX) return NC_ERANGE;
911#endif
912 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
913 return NC_NOERR;
914}
915
916static int
917ncx_put_ushort_int(void *xp, const int *ip)
918{
919 ix_ushort xx = (ix_ushort)*ip;
920 put_ix_ushort(xp, &xx);
921#if IX_USHORT_MAX < INT_MAX
922 if (*ip > IX_USHORT_MAX) return NC_ERANGE;
923#endif
924 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
925 return NC_NOERR;
926}
927
928static int
929ncx_put_ushort_longlong(void *xp, const longlong *ip)
930{
931 ix_ushort xx = (ix_ushort)*ip;
932 put_ix_ushort(xp, &xx);
933#if IX_USHORT_MAX < LONGLONG_MAX
934 if (*ip > IX_USHORT_MAX) return NC_ERANGE;
935#endif
936 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
937 return NC_NOERR;
938}
939
940static int
941ncx_put_ushort_ushort(void *xp, const ushort *ip)
942{
943#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
944 put_ix_ushort(xp, (const ix_ushort *)ip);
945 return NC_NOERR;
946#else
947 ix_ushort xx = (ix_ushort)*ip;
948 put_ix_ushort(xp, &xx);
949#if IX_USHORT_MAX < USHORT_MAX
950 if (*ip > IX_USHORT_MAX) return NC_ERANGE;
951#endif
952
953#endif
954 return NC_NOERR;
955}
956
957static int
958ncx_put_ushort_uint(void *xp, const uint *ip)
959{
960#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
961 put_ix_ushort(xp, (const ix_ushort *)ip);
962 return NC_NOERR;
963#else
964 ix_ushort xx = (ix_ushort)*ip;
965 put_ix_ushort(xp, &xx);
966#if IX_USHORT_MAX < UINT_MAX
967 if (*ip > IX_USHORT_MAX) return NC_ERANGE;
968#endif
969
970#endif
971 return NC_NOERR;
972}
973
974static int
975ncx_put_ushort_ulonglong(void *xp, const ulonglong *ip)
976{
977#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
978 put_ix_ushort(xp, (const ix_ushort *)ip);
979 return NC_NOERR;
980#else
981 ix_ushort xx = (ix_ushort)*ip;
982 put_ix_ushort(xp, &xx);
983#if IX_USHORT_MAX < ULONGLONG_MAX
984 if (*ip > IX_USHORT_MAX) return NC_ERANGE;
985#endif
986
987#endif
988 return NC_NOERR;
989}
990
991static int
992ncx_put_ushort_float(void *xp, const float *ip)
993{
994 ix_ushort xx = (ix_ushort)*ip;
995 put_ix_ushort(xp, &xx);
996 if(*ip > (double)X_USHORT_MAX || *ip < 0) return NC_ERANGE;
997 return NC_NOERR;
998}
999
1000static int
1001ncx_put_ushort_double(void *xp, const double *ip)
1002{
1003 ix_ushort xx = (ix_ushort)*ip;
1004 put_ix_ushort(xp, &xx);
1005 if(*ip > X_USHORT_MAX || *ip < 0) return NC_ERANGE;
1006 return NC_NOERR;
1007}
1008
1009
1010/* x_int ---------------------------------------------------------------------*/
1011
1012#if SHORT_MAX == X_INT_MAX
1013typedef short ix_int;
1014#define SIZEOF_IX_INT SIZEOF_SHORT
1015#define IX_INT_MAX SHORT_MAX
1016#elif INT_MAX  >= X_INT_MAX
1017typedef int ix_int;
1018#define SIZEOF_IX_INT SIZEOF_INT
1019#define IX_INT_MAX INT_MAX
1020#elif LONG_MAX  >= X_INT_MAX
1021typedef long ix_int;
1022#define SIZEOF_IX_INT SIZEOF_LONG
1023#define IX_INT_MAX LONG_MAX
1024#else
1025#error "ix_int implementation"
1026#endif
1027
1028
1029static void
1030get_ix_int(const void *xpix_int *ip)
1031{
1032 const uchar *cp = (const uchar *) xp;
1033
1034 *ip = *cp++ << 24;
1035#if SIZEOF_IX_INT > X_SIZEOF_INT
1036 if(*ip & 0x80000000)
1037 {
1038 /* extern is negative */
1039 *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
1040 }
1041#endif
1042 *ip |= (*cp++ << 16);
1043 *ip |= (*cp++ << 8);
1044 *ip |= *cp;
1045}
1046
1047static void
1048put_ix_int(void *xp, const ix_int *ip)
1049{
1050 uchar *cp = (uchar *) xp;
1051
1052 *cp++ = (*ip) >> 24;
1053 *cp++ = ((*ip) & 0x00ff0000) >> 16;
1054 *cp++ = ((*ip) & 0x0000ff00) >>  8;
1055 *cp   = ((*ip) & 0x000000ff);
1056}
1057
1058static int
1059ncx_get_int_schar(const void *xpschar *ip)
1060{
1061 ix_int xx;
1062 get_ix_int(xp, &xx);
1063 *ip = (scharxx;
1064#if IX_INT_MAX > SCHAR_MAX
1065 if (xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE;
1066#endif
1067
1068 return NC_NOERR;
1069}
1070
1071static int
1072ncx_get_int_short(const void *xp, short *ip)
1073{
1074#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1075 get_ix_int(xp, (ix_int *)ip);
1076 return NC_NOERR;
1077#else
1078 ix_int xx;
1079 get_ix_int(xp, &xx);
1080 *ip = (short) xx;
1081#if IX_INT_MAX > SHORT_MAX
1082 if (xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE;
1083#endif
1084
1085#endif
1086 return NC_NOERR;
1087}
1088
1089       int
1090ncx_get_int_int(const void *xp, int *ip)
1091{
1092#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1093 get_ix_int(xp, (ix_int *)ip);
1094 return NC_NOERR;
1095#else
1096 ix_int xx;
1097 get_ix_int(xp, &xx);
1098 *ip = (int) xx;
1099#if IX_INT_MAX > INT_MAX
1100 if (xx > INT_MAX || xx < INT_MIN) return NC_ERANGE;
1101#endif
1102
1103#endif
1104 return NC_NOERR;
1105}
1106
1107static int
1108ncx_get_int_longlong(const void *xplonglong *ip)
1109{
1110#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1111 get_ix_int(xp, (ix_int *)ip);
1112 return NC_NOERR;
1113#else
1114 ix_int xx;
1115 get_ix_int(xp, &xx);
1116 *ip = (longlongxx;
1117#if IX_INT_MAX > LONGLONG_MAX
1118 if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) return NC_ERANGE;
1119#endif
1120
1121#endif
1122 return NC_NOERR;
1123}
1124
1125static int
1126ncx_get_int_ushort(const void *xpushort *ip)
1127{
1128 ix_int xx;
1129 get_ix_int(xp, &xx);
1130 *ip = (ushortxx;
1131#if IX_INT_MAX > USHORT_MAX
1132 if (xx > USHORT_MAX) return NC_ERANGE;
1133#endif
1134 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
1135 return NC_NOERR;
1136}
1137
1138static int
1139ncx_get_int_uchar(const void *xpuchar *ip)
1140{
1141 ix_int xx;
1142 get_ix_int(xp, &xx);
1143 *ip = (ucharxx;
1144#if IX_INT_MAX > UCHAR_MAX
1145 if (xx > UCHAR_MAX) return NC_ERANGE;
1146#endif
1147 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
1148 return NC_NOERR;
1149}
1150
1151static int
1152ncx_get_int_uint(const void *xpuint *ip)
1153{
1154 ix_int xx;
1155 get_ix_int(xp, &xx);
1156 *ip = (uintxx;
1157#if IX_INT_MAX > UINT_MAX
1158 if (xx > UINT_MAX) return NC_ERANGE;
1159#endif
1160 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
1161 return NC_NOERR;
1162}
1163
1164static int
1165ncx_get_int_ulonglong(const void *xpulonglong *ip)
1166{
1167 ix_int xx;
1168 get_ix_int(xp, &xx);
1169 *ip = (ulonglongxx;
1170#if IX_INT_MAX > ULONGLONG_MAX
1171 if (xx > ULONGLONG_MAX) return NC_ERANGE;
1172#endif
1173 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
1174 return NC_NOERR;
1175}
1176
1177static int
1178ncx_get_int_float(const void *xp, float *ip)
1179{
1180 ix_int xx;
1181 get_ix_int(xp, &xx);
1182 *ip = (float) xx;
1183
1184 return NC_NOERR;
1185}
1186
1187static int
1188ncx_get_int_double(const void *xp, double *ip)
1189{
1190 ix_int xx;
1191 get_ix_int(xp, &xx);
1192 *ip = (double) xx;
1193
1194 return NC_NOERR;
1195}
1196
1197
1198static int
1199ncx_put_int_schar(void *xp, const schar *ip)
1200{
1201 uchar *cp = (uchar *) xp;
1202 if(*ip & 0x80)
1203 {
1204 *cp++ = 0xff;
1205 *cp++ = 0xff;
1206 *cp++ = 0xff;
1207 }
1208 else
1209 {
1210 *cp++ = 0x00;
1211 *cp++ = 0x00;
1212 *cp++ = 0x00;
1213 }
1214 *cp = (uchar)(signed)*ip;
1215 return NC_NOERR;
1216}
1217
1218static int
1219ncx_put_int_uchar(void *xp, const uchar *ip)
1220{
1221 uchar *cp = (uchar *) xp;
1222 *cp++ = 0x00;
1223 *cp++ = 0x00;
1224 *cp++ = 0x00;
1225 *cp   = *ip;
1226 return NC_NOERR;
1227}
1228
1229static int
1230ncx_put_int_short(void *xp, const short *ip)
1231{
1232#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
1233 put_ix_int(xp, (const ix_int *)ip);
1234 return NC_NOERR;
1235#else
1236 ix_int xx = (ix_int)*ip;
1237 put_ix_int(xp, &xx);
1238#if IX_INT_MAX < SHORT_MAX
1239 if (*ip > IX_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE;
1240#endif
1241
1242#endif
1243 return NC_NOERR;
1244}
1245
1246       int
1247ncx_put_int_int(void *xp, const int *ip)
1248{
1249#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
1250 put_ix_int(xp, (const ix_int *)ip);
1251 return NC_NOERR;
1252#else
1253 ix_int xx = (ix_int)*ip;
1254 put_ix_int(xp, &xx);
1255#if IX_INT_MAX < INT_MAX
1256 if (*ip > IX_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE;
1257#endif
1258
1259#endif
1260 return NC_NOERR;
1261}
1262
1263static int
1264ncx_put_int_longlong(void *xp, const longlong *ip)
1265{
1266#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
1267 put_ix_int(xp, (const ix_int *)ip);
1268 return NC_NOERR;
1269#else
1270 ix_int xx = (ix_int)*ip;
1271 put_ix_int(xp, &xx);
1272#if IX_INT_MAX < LONGLONG_MAX
1273 if (*ip > IX_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE;
1274#endif
1275
1276#endif
1277 return NC_NOERR;
1278}
1279
1280static int
1281ncx_put_int_ushort(void *xp, const ushort *ip)
1282{
1283 ix_int xx = (ix_int)*ip;
1284 put_ix_int(xp, &xx);
1285#if IX_INT_MAX < USHORT_MAX
1286 if (*ip > IX_INT_MAX) return NC_ERANGE;
1287#endif
1288
1289 return NC_NOERR;
1290}
1291
1292static int
1293ncx_put_int_uint(void *xp, const uint *ip)
1294{
1295 ix_int xx = (ix_int)*ip;
1296 put_ix_int(xp, &xx);
1297#if IX_INT_MAX < UINT_MAX
1298 if (*ip > IX_INT_MAX) return NC_ERANGE;
1299#endif
1300
1301 return NC_NOERR;
1302}
1303
1304static int
1305ncx_put_int_ulonglong(void *xp, const ulonglong *ip)
1306{
1307 ix_int xx = (ix_int)*ip;
1308 put_ix_int(xp, &xx);
1309#if IX_INT_MAX < ULONGLONG_MAX
1310 if (*ip > IX_INT_MAX) return NC_ERANGE;
1311#endif
1312
1313 return NC_NOERR;
1314}
1315
1316static int
1317ncx_put_int_float(void *xp, const float *ip)
1318{
1319 ix_int xx = (ix_int)*ip;
1320 put_ix_int(xp, &xx);
1321 if(*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) return NC_ERANGE;
1322 return NC_NOERR;
1323}
1324
1325static int
1326ncx_put_int_double(void *xp, const double *ip)
1327{
1328 ix_int xx = (ix_int)*ip;
1329 put_ix_int(xp, &xx);
1330 if(*ip > X_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE;
1331 return NC_NOERR;
1332}
1333
1334
1335
1336/* x_uint --------------------------------------------------------------------*/
1337
1338#if USHORT_MAX == X_UINT_MAX
1339typedef ushort ix_uint;
1340#define SIZEOF_IX_UINT SIZEOF_USHORT
1341#define IX_UINT_MAX USHORT_MAX
1342#elif UINT_MAX  >= X_UINT_MAX
1343typedef uint ix_uint;
1344#define SIZEOF_IX_UINT SIZEOF_UINT
1345#define IX_UINT_MAX UINT_MAX
1346#elif ULONG_MAX  >= X_UINT_MAX
1347typedef ulong ix_uint;
1348#define SIZEOF_IX_UINT SIZEOF_ULONG
1349#define IX_UINT_MAX ULONG_MAX
1350#else
1351#error "ix_uint implementation"
1352#endif
1353
1354
1355static void
1356get_ix_uint(const void *xpix_uint *ip)
1357{
1358 const uchar *cp = (const uchar *) xp;
1359
1360 *ip = *cp++ << 24;
1361 *ip |= (*cp++ << 16);
1362 *ip |= (*cp++ << 8);
1363 *ip |= *cp;
1364}
1365
1366static void
1367put_ix_uint(void *xp, const ix_uint *ip)
1368{
1369 uchar *cp = (uchar *) xp;
1370
1371 *cp++ = (*ip) >> 24;
1372 *cp++ = ((*ip) & 0x00ff0000) >> 16;
1373 *cp++ = ((*ip) & 0x0000ff00) >>  8;
1374 *cp   = ((*ip) & 0x000000ff);
1375}
1376
1377#if X_SIZEOF_UINT != SIZEOF_UINT
1378static int
1379ncx_get_uint_uint(const void *xpuint *ip)
1380{
1381#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
1382 get_ix_uint(xp, (ix_uint *)ip);
1383 return NC_NOERR;
1384#else
1385 ix_uint xx;
1386 get_ix_uint(xp, &xx);
1387 *ip = (uintxx;
1388#if IX_UINT_MAX > UINT_MAX
1389 if (xx > UINT_MAX) return NC_ERANGE;
1390#endif
1391
1392#endif
1393 return NC_NOERR;
1394}
1395
1396#endif
1397
1398static int
1399ncx_get_uint_schar(const void *xpschar *ip)
1400{
1401 ix_uint xx;
1402 get_ix_uint(xp, &xx);
1403 *ip = (scharxx;
1404#if IX_UINT_MAX > SCHAR_MAX
1405 if (xx > SCHAR_MAX) return NC_ERANGE;
1406#endif
1407
1408 return NC_NOERR;
1409}
1410
1411static int
1412ncx_get_uint_short(const void *xp, short *ip)
1413{
1414 ix_uint xx;
1415 get_ix_uint(xp, &xx);
1416 *ip = (short) xx;
1417#if IX_UINT_MAX > SHORT_MAX
1418 if (xx > SHORT_MAX) return NC_ERANGE;
1419#endif
1420
1421 return NC_NOERR;
1422}
1423
1424static int
1425ncx_get_uint_int(const void *xp, int *ip)
1426{
1427 ix_uint xx;
1428 get_ix_uint(xp, &xx);
1429 *ip = (int) xx;
1430#if IX_UINT_MAX > INT_MAX
1431 if (xx > INT_MAX) return NC_ERANGE;
1432#endif
1433
1434 return NC_NOERR;
1435}
1436
1437static int
1438ncx_get_uint_longlong(const void *xplonglong *ip)
1439{
1440 ix_uint xx;
1441 get_ix_uint(xp, &xx);
1442 *ip = (longlongxx;
1443#if IX_UINT_MAX > LONGLONG_MAX
1444 if (xx > LONGLONG_MAX) return NC_ERANGE;
1445#endif
1446
1447 return NC_NOERR;
1448}
1449
1450static int
1451ncx_get_uint_ushort(const void *xpushort *ip)
1452{
1453#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
1454 get_ix_uint(xp, (ix_uint *)ip);
1455 return NC_NOERR;
1456#else
1457 ix_uint xx;
1458 get_ix_uint(xp, &xx);
1459 *ip = (ushortxx;
1460#if IX_UINT_MAX > USHORT_MAX
1461 if (xx > USHORT_MAX) return NC_ERANGE;
1462#endif
1463
1464#endif
1465 return NC_NOERR;
1466}
1467
1468static int
1469ncx_get_uint_uchar(const void *xpuchar *ip)
1470{
1471#if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
1472 get_ix_uint(xp, (ix_uint *)ip);
1473 return NC_NOERR;
1474#else
1475 ix_uint xx;
1476 get_ix_uint(xp, &xx);
1477 *ip = (ucharxx;
1478#if IX_UINT_MAX > UCHAR_MAX
1479 if (xx > UCHAR_MAX) return NC_ERANGE;
1480#endif
1481
1482#endif
1483 return NC_NOERR;
1484}
1485
1486static int
1487ncx_get_uint_ulonglong(const void *xpulonglong *ip)
1488{
1489#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
1490 get_ix_uint(xp, (ix_uint *)ip);
1491 return NC_NOERR;
1492#else
1493 ix_uint xx;
1494 get_ix_uint(xp, &xx);
1495 *ip = (ulonglongxx;
1496#if IX_UINT_MAX > ULONGLONG_MAX
1497 if (xx > ULONGLONG_MAX) return NC_ERANGE;
1498#endif
1499
1500#endif
1501 return NC_NOERR;
1502}
1503
1504static int
1505ncx_get_uint_float(const void *xp, float *ip)
1506{
1507 ix_uint xx;
1508 get_ix_uint(xp, &xx);
1509 *ip = (float) xx;
1510
1511 return NC_NOERR;
1512}
1513
1514static int
1515ncx_get_uint_double(const void *xp, double *ip)
1516{
1517 ix_uint xx;
1518 get_ix_uint(xp, &xx);
1519 *ip = (double) xx;
1520
1521 return NC_NOERR;
1522}
1523
1524
1525static int
1526ncx_put_uint_schar(void *xp, const schar *ip)
1527{
1528 uchar *cp = (uchar *) xp;
1529 *cp++ = 0x00;
1530 *cp++ = 0x00;
1531 *cp++ = 0x00;
1532 *cp = (uchar)(signed)*ip;
1533
1534 if (*ip < 0) return NC_ERANGE;
1535
1536 return NC_NOERR;
1537}
1538
1539static int
1540ncx_put_uint_uchar(void *xp, const uchar *ip)
1541{
1542 uchar *cp = (uchar *) xp;
1543 *cp++ = 0x00;
1544 *cp++ = 0x00;
1545 *cp++ = 0x00;
1546 *cp   = *ip;
1547 return NC_NOERR;
1548}
1549
1550#if X_SIZEOF_UINT != SIZEOF_UINT
1551static int
1552ncx_put_uint_uint(void *xp, const uint *ip)
1553{
1554#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
1555 put_ix_uint(xp, (const ix_uint *)ip);
1556 return NC_NOERR;
1557#else
1558 ix_uint xx = (ix_uint)*ip;
1559 put_ix_uint(xp, &xx);
1560#if IX_UINT_MAX < UINT_MAX
1561 if (*ip > IX_UINT_MAX) return NC_ERANGE;
1562#endif
1563
1564#endif
1565 return NC_NOERR;
1566}
1567
1568#endif
1569
1570static int
1571ncx_put_uint_short(void *xp, const short *ip)
1572{
1573 ix_uint xx = (ix_uint)*ip;
1574 put_ix_uint(xp, &xx);
1575#if IX_UINT_MAX < SHORT_MAX
1576 if (*ip > IX_UINT_MAX) return NC_ERANGE;
1577#endif
1578 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
1579 return NC_NOERR;
1580}
1581
1582static int
1583ncx_put_uint_int(void *xp, const int *ip)
1584{
1585 ix_uint xx = (ix_uint)*ip;
1586 put_ix_uint(xp, &xx);
1587#if IX_UINT_MAX < INT_MAX
1588 if (*ip > IX_UINT_MAX) return NC_ERANGE;
1589#endif
1590 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
1591 return NC_NOERR;
1592}
1593
1594static int
1595ncx_put_uint_longlong(void *xp, const longlong *ip)
1596{
1597 ix_uint xx = (ix_uint)*ip;
1598 put_ix_uint(xp, &xx);
1599#if IX_UINT_MAX < LONGLONG_MAX
1600 if (*ip > IX_UINT_MAX) return NC_ERANGE;
1601#endif
1602 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
1603 return NC_NOERR;
1604}
1605
1606static int
1607ncx_put_uint_ushort(void *xp, const ushort *ip)
1608{
1609#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
1610 put_ix_uint(xp, (const ix_uint *)ip);
1611 return NC_NOERR;
1612#else
1613 ix_uint xx = (ix_uint)*ip;
1614 put_ix_uint(xp, &xx);
1615#if IX_UINT_MAX < USHORT_MAX
1616 if (*ip > IX_UINT_MAX) return NC_ERANGE;
1617#endif
1618
1619#endif
1620 return NC_NOERR;
1621}
1622
1623static int
1624ncx_put_uint_ulonglong(void *xp, const ulonglong *ip)
1625{
1626#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
1627 put_ix_uint(xp, (const ix_uint *)ip);
1628 return NC_NOERR;
1629#else
1630 ix_uint xx = (ix_uint)*ip;
1631 put_ix_uint(xp, &xx);
1632#if IX_UINT_MAX < ULONGLONG_MAX
1633 if (*ip > IX_UINT_MAX) return NC_ERANGE;
1634#endif
1635
1636#endif
1637 return NC_NOERR;
1638}
1639
1640static int
1641ncx_put_uint_float(void *xp, const float *ip)
1642{
1643 ix_uint xx = (ix_uint)*ip;
1644 put_ix_uint(xp, &xx);
1645 if(*ip > (double)X_UINT_MAX || *ip < 0) return NC_ERANGE;
1646 return NC_NOERR;
1647}
1648
1649static int
1650ncx_put_uint_double(void *xp, const double *ip)
1651{
1652 ix_uint xx = (ix_uint)*ip;
1653 put_ix_uint(xp, &xx);
1654 if(*ip > X_UINT_MAX || *ip < 0) return NC_ERANGE;
1655 return NC_NOERR;
1656}
1657
1658
1659/* x_float -------------------------------------------------------------------*/
1660
1661#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
1662
1663static void
1664get_ix_float(const void *xp, float *ip)
1665{
1666#ifdef WORDS_BIGENDIAN
1667 (void) memcpy(ipxp, sizeof(float));
1668#else
1669 swap4b(ipxp);
1670#endif
1671}
1672
1673static void
1674put_ix_float(void *xp, const float *ip)
1675{
1676#ifdef WORDS_BIGENDIAN
1677 (void) memcpy(xpipX_SIZEOF_FLOAT);
1678#else
1679 swap4b(xpip);
1680#endif
1681}
1682
1683#elif vax
1684
1685/* What IEEE single precision floating point looks like on a Vax */
1686struct ieee_single {
1687 unsigned int exp_hi       : 7;
1688 unsigned int sign         : 1;
1689 unsigned int  mant_hi      : 7;
1690 unsigned int exp_lo       : 1;
1691 unsigned int mant_lo_hi   : 8;
1692 unsigned int mant_lo_lo   : 8;
1693};
1694
1695/* Vax single precision floating point */
1696struct vax_single {
1697 unsigned int mantissa1 : 7;
1698 unsigned int exp       : 8;
1699 unsigned int sign      : 1;
1700 unsigned int mantissa2 : 16;
1701};
1702
1703#define VAX_SNG_BIAS 0x81
1704#define IEEE_SNG_BIAS 0x7f
1705
1706static struct sgl_limits {
1707 struct vax_single s;
1708 struct ieee_single ieee;
1709max = {
1710 { 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
1711 { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 } /* Max IEEE */
1712};
1713static struct sgl_limits min = {
1714 { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
1715 { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } /* Min IEEE */
1716};
1717
1718static void
1719get_ix_float(const void *xp, float *ip)
1720{
1721 struct vax_single *const vsp = (struct vax_single *) ip;
1722 const struct ieee_single *const isp =
1723  (const struct ieee_single *) xp;
1724 unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
1725
1726 switch(exp) {
1727 case 0 :
1728 /* ieee subnormal */
1729 if(isp->mant_hi == min.ieee.mant_hi
1730 && isp->mant_lo_hi == min.ieee.mant_lo_hi
1731 && isp->mant_lo_lo == min.ieee.mant_lo_lo)
1732 {
1733 *vsp = min.s;
1734 }
1735 else
1736 {
1737 unsigned mantissa = (isp->mant_hi << 16)
1738  | isp->mant_lo_hi << 8
1739  | isp->mant_lo_lo;
1740 unsigned tmp = mantissa >> 20;
1741 if(tmp >= 4) {
1742 vsp->exp = 2;
1743 } else if (tmp >= 2) {
1744 vsp->exp = 1;
1745 } else {
1746 *vsp = min.s;
1747 break;
1748 } /* else */
1749 tmp = mantissa - (1 << (20 + vsp->exp ));
1750 tmp <<= 3 - vsp->exp;
1751 vsp->mantissa2 = tmp;
1752 vsp->mantissa1 = (tmp >> 16);
1753 }
1754 break;
1755 case 0xfe :
1756 case 0xff :
1757 *vsp = max.s;
1758 break;
1759 default :
1760 vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
1761 vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
1762 vsp->mantissa1 = isp->mant_hi;
1763 }
1764
1765 vsp->sign = isp->sign;
1766
1767}
1768
1769
1770static void
1771put_ix_float(void *xp, const float *ip)
1772{
1773 const struct vax_single *const vsp =
1774  (const struct vax_single *)ip;
1775 struct ieee_single *const isp = (struct ieee_single *) xp;
1776
1777 switch(vsp->exp){
1778 case 0 :
1779 /* all vax float with zero exponent map to zero */
1780 *isp = min.ieee;
1781 break;
1782 case 2 :
1783 case 1 :
1784 {
1785 /* These will map to subnormals */
1786 unsigned mantissa = (vsp->mantissa1 << 16)
1787  | vsp->mantissa2;
1788 mantissa >>= 3 - vsp->exp;
1789 mantissa += (1 << (20 + vsp->exp));
1790 isp->mant_lo_lo = mantissa;
1791 isp->mant_lo_hi = mantissa >> 8;
1792 isp->mant_hi = mantissa >> 16;
1793 isp->exp_lo = 0;
1794 isp->exp_hi = 0;
1795 }
1796 break;
1797 case 0xff : /* max.s.exp */
1798 if( vsp->mantissa2 == max.s.mantissa2
1799 && vsp->mantissa1 == max.s.mantissa1)
1800 {
1801 /* map largest vax float to ieee infinity */
1802 *isp = max.ieee;
1803 break;
1804 } /* else, fall thru */
1805 default :
1806 {
1807 unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
1808 isp->exp_hi = exp >> 1;
1809 isp->exp_lo = exp;
1810 isp->mant_lo_lo = vsp->mantissa2;
1811 isp->mant_lo_hi = vsp->mantissa2 >> 8;
1812 isp->mant_hi = vsp->mantissa1;
1813 }
1814 }
1815
1816 isp->sign = vsp->sign;
1817
1818}
1819
1820 /* vax */
1821#elif defined(_CRAY) && !defined(__crayx1)
1822
1823/*
1824 * Return the number of bytes until the next "word" boundary
1825 * N.B. This is based on the very weird YMP address structure,
1826 * which puts the address within a word in the leftmost 3 bits
1827 * of the address.
1828 */
1829static size_t
1830word_align(const void *vp)
1831{
1832 const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
1833 return (rem != 0);
1834}
1835
1836struct ieee_single_hi {
1837 unsigned int sign : 1;
1838 unsigned int  exp : 8;
1839 unsigned int mant :23;
1840 unsigned int pad :32;
1841};
1842typedef struct ieee_single_hi ieee_single_hi;
1843
1844struct ieee_single_lo {
1845 unsigned int pad :32;
1846 unsigned int sign : 1;
1847 unsigned int  exp : 8;
1848 unsigned int mant :23;
1849};
1850typedef struct ieee_single_lo ieee_single_lo;
1851
1852static const int ieee_single_bias = 0x7f;
1853
1854struct ieee_double {
1855 unsigned int sign : 1;
1856 unsigned int  exp :11;
1857 unsigned int mant :52;
1858};
1859typedef struct ieee_double ieee_double;
1860
1861static const int ieee_double_bias = 0x3ff;
1862
1863#if defined(NO_IEEE_FLOAT)
1864
1865struct cray_single {
1866 unsigned int sign : 1;
1867 unsigned int  exp :15;
1868 unsigned int mant :48;
1869};
1870typedef struct cray_single cray_single;
1871
1872static const int cs_ieis_bias = 0x4000 - 0x7f;
1873
1874static const int cs_id_bias = 0x4000 - 0x3ff;
1875
1876
1877static void
1878get_ix_float(const void *xp, float *ip)
1879{
1880
1881 if(word_align(xp) == 0)
1882 {
1883 const ieee_single_hi *isp = (const ieee_single_hi *) xp;
1884 cray_single *csp = (cray_single *) ip;
1885
1886 if(isp->exp == 0)
1887 {
1888 /* ieee subnormal */
1889 *ip = (double)isp->mant;
1890 if(isp->mant != 0)
1891 {
1892 csp->exp -= (ieee_single_bias + 22);
1893 }
1894 }
1895 else
1896 {
1897 csp->exp  = isp->exp + cs_ieis_bias + 1;
1898 csp->mant = isp->mant << (48 - 1 - 23);
1899 csp->mant |= (1 << (48 - 1));
1900 }
1901 csp->sign = isp->sign;
1902
1903
1904 }
1905 else
1906 {
1907 const ieee_single_lo *isp = (const ieee_single_lo *) xp;
1908 cray_single *csp = (cray_single *) ip;
1909
1910 if(isp->exp == 0)
1911 {
1912 /* ieee subnormal */
1913 *ip = (double)isp->mant;
1914 if(isp->mant != 0)
1915 {
1916 csp->exp -= (ieee_single_bias + 22);
1917 }
1918 }
1919 else
1920 {
1921 csp->exp  = isp->exp + cs_ieis_bias + 1;
1922 csp->mant = isp->mant << (48 - 1 - 23);
1923 csp->mant |= (1 << (48 - 1));
1924 }
1925 csp->sign = isp->sign;
1926
1927
1928 }
1929}
1930
1931static void
1932put_ix_float(void *xp, const float *ip)
1933{
1934 if(word_align(xp) == 0)
1935 {
1936 ieee_single_hi *isp = (ieee_single_hi*)xp;
1937 const cray_single *csp = (const cray_single *) ip;
1938 int ieee_exp = csp->exp - cs_ieis_bias -1;
1939
1940 isp->sign = csp->sign;
1941
1942 if(ieee_exp >= 0xff)
1943 {
1944 /* NC_ERANGE => ieee Inf */
1945 isp->exp = 0xff;
1946 isp->mant = 0x0;
1947 }
1948 else if(ieee_exp > 0)
1949 {
1950 /* normal ieee representation */
1951 isp->exp  = ieee_exp;
1952 /* assumes cray rep is in normal form */
1953 assert(csp->mant & 0x800000000000);
1954 isp->mant = (((csp->mant << 1) &
1955 0xffffffffffff) >> (48 - 23));
1956 }
1957 else if(ieee_exp > -23)
1958 {
1959 /* ieee subnormal, right shift */
1960 const int rshift = (48 - 23 - ieee_exp);
1961
1962 isp->mant = csp->mant >> rshift;
1963
1964#if 0
1965 if(csp->mant & (1 << (rshift -1)))
1966 {
1967 /* round up */
1968 isp->mant++;
1969 }
1970#endif
1971
1972 isp->exp  = 0;
1973 }
1974 else
1975 {
1976 /* smaller than ieee can represent */
1977 isp->exp = 0;
1978 isp->mant = 0;
1979 }
1980
1981 }
1982 else
1983 {
1984 ieee_single_lo *isp = (ieee_single_lo*)xp;
1985 const cray_single *csp = (const cray_single *) ip;
1986 int ieee_exp = csp->exp - cs_ieis_bias -1;
1987
1988 isp->sign = csp->sign;
1989
1990 if(ieee_exp >= 0xff)
1991 {
1992 /* NC_ERANGE => ieee Inf */
1993 isp->exp = 0xff;
1994 isp->mant = 0x0;
1995 }
1996 else if(ieee_exp > 0)
1997 {
1998 /* normal ieee representation */
1999 isp->exp  = ieee_exp;
2000 /* assumes cray rep is in normal form */
2001 assert(csp->mant & 0x800000000000);
2002 isp->mant = (((csp->mant << 1) &
2003 0xffffffffffff) >> (48 - 23));
2004 }
2005 else if(ieee_exp > -23)
2006 {
2007 /* ieee subnormal, right shift */
2008 const int rshift = (48 - 23 - ieee_exp);
2009
2010 isp->mant = csp->mant >> rshift;
2011
2012#if 0
2013 if(csp->mant & (1 << (rshift -1)))
2014 {
2015 /* round up */
2016 isp->mant++;
2017 }
2018#endif
2019
2020 isp->exp  = 0;
2021 }
2022 else
2023 {
2024 /* smaller than ieee can represent */
2025 isp->exp = 0;
2026 isp->mant = 0;
2027 }
2028
2029 }
2030}
2031
2032#else
2033 /* IEEE Cray with only doubles */
2034static void
2035get_ix_float(const void *xp, float *ip)
2036{
2037
2038 ieee_double *idp = (ieee_double *) ip;
2039
2040 if(word_align(xp) == 0)
2041 {
2042 const ieee_single_hi *isp = (const ieee_single_hi *) xp;
2043 if(isp->exp == 0 && isp->mant == 0)
2044 {
2045 idp->exp = 0;
2046 idp->mant = 0;
2047 }
2048 else
2049 {
2050 idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
2051 idp->mant = isp->mant << (52 - 23);
2052 }
2053 idp->sign = isp->sign;
2054 }
2055 else
2056 {
2057 const ieee_single_lo *isp = (const ieee_single_lo *) xp;
2058 if(isp->exp == 0 && isp->mant == 0)
2059 {
2060 idp->exp = 0;
2061 idp->mant = 0;
2062 }
2063 else
2064 {
2065 idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
2066 idp->mant = isp->mant << (52 - 23);
2067 }
2068 idp->sign = isp->sign;
2069 }
2070}
2071
2072static void
2073put_ix_float(void *xp, const float *ip)
2074{
2075 const ieee_double *idp = (const ieee_double *) ip;
2076 if(word_align(xp) == 0)
2077 {
2078 ieee_single_hi *isp = (ieee_single_hi*)xp;
2079 if(idp->exp > (ieee_double_bias - ieee_single_bias))
2080 isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
2081 else
2082 isp->exp = 0;
2083 isp->mant = idp->mant >> (52 - 23);
2084 isp->sign = idp->sign;
2085 }
2086 else
2087 {
2088 ieee_single_lo *isp = (ieee_single_lo*)xp;
2089 if(idp->exp > (ieee_double_bias - ieee_single_bias))
2090 isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
2091 else
2092 isp->exp = 0;
2093 isp->mant = idp->mant >> (52 - 23);
2094 isp->sign = idp->sign;
2095 }
2096}
2097#endif
2098
2099#else
2100#error "ix_float implementation"
2101#endif
2102
2103#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
2104static int
2105ncx_get_float_float(const void *xp, float *ip)
2106{
2107 /* TODO */
2108 get_ix_float(xpip);
2109 return NC_NOERR;
2110}
2111#endif
2112
2113#define ix_float float
2114
2115static int
2116ncx_get_float_schar(const void *xpschar *ip)
2117{
2118 ix_float xx;
2119 get_ix_float(xp, &xx);
2120 *ip = (scharxx;
2121 if(xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) return NC_ERANGE;
2122 return NC_NOERR;
2123}
2124
2125static int
2126ncx_get_float_short(const void *xp, short *ip)
2127{
2128 ix_float xx;
2129 get_ix_float(xp, &xx);
2130 *ip = (short) xx;
2131 if(xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) return NC_ERANGE;
2132 return NC_NOERR;
2133}
2134
2135static int
2136ncx_get_float_int(const void *xp, int *ip)
2137{
2138 ix_float xx;
2139 get_ix_float(xp, &xx);
2140 *ip = (int) xx;
2141 if(xx > (double)INT_MAX || xx < (double)INT_MIN) return NC_ERANGE;
2142 return NC_NOERR;
2143}
2144
2145static int
2146ncx_get_float_double(const void *xp, double *ip)
2147{
2148 ix_float xx;
2149 get_ix_float(xp, &xx);
2150 *ip = (double) xx;
2151
2152 return NC_NOERR;
2153}
2154
2155static int
2156ncx_get_float_longlong(const void *xplonglong *ip)
2157{
2158 ix_float xx;
2159 get_ix_float(xp, &xx);
2160 *ip = (longlongxx;
2161 if(xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) return NC_ERANGE;
2162 return NC_NOERR;
2163}
2164
2165static int
2166ncx_get_float_uchar(const void *xpuchar *ip)
2167{
2168 ix_float xx;
2169 get_ix_float(xp, &xx);
2170 *ip = (ucharxx;
2171 if(xx > (double)UCHAR_MAX || xx < 0) return NC_ERANGE;
2172 return NC_NOERR;
2173}
2174
2175static int
2176ncx_get_float_ushort(const void *xpushort *ip)
2177{
2178 ix_float xx;
2179 get_ix_float(xp, &xx);
2180 *ip = (ushortxx;
2181 if(xx > (double)USHORT_MAX || xx < 0) return NC_ERANGE;
2182 return NC_NOERR;
2183}
2184
2185static int
2186ncx_get_float_uint(const void *xpuint *ip)
2187{
2188 ix_float xx;
2189 get_ix_float(xp, &xx);
2190 *ip = (uintxx;
2191 if(xx > (double)UINT_MAX || xx < 0) return NC_ERANGE;
2192 return NC_NOERR;
2193}
2194
2195static int
2196ncx_get_float_ulonglong(const void *xpulonglong *ip)
2197{
2198 ix_float xx;
2199 get_ix_float(xp, &xx);
2200 *ip = (ulonglongxx;
2201 if(xx > (double)ULONGLONG_MAX || xx < 0) return NC_ERANGE;
2202 return NC_NOERR;
2203}
2204
2205
2206#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
2207static int
2208ncx_put_float_float(void *xp, const float *ip)
2209{
2210 put_ix_float(xpip);
2211#ifdef NO_IEEE_FLOAT
2212 if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
2213 return NC_ERANGE;
2214#endif
2215 return NC_NOERR;
2216}
2217#endif
2218
2219static int
2220ncx_put_float_schar(void *xp, const schar *ip)
2221{
2222 ix_float xx = (ix_float)*ip;
2223 put_ix_float(xp, &xx);
2224
2225 return NC_NOERR;
2226}
2227
2228static int
2229ncx_put_float_short(void *xp, const short *ip)
2230{
2231 ix_float xx = (ix_float)*ip;
2232 put_ix_float(xp, &xx);
2233
2234 return NC_NOERR;
2235}
2236
2237static int
2238ncx_put_float_int(void *xp, const int *ip)
2239{
2240 ix_float xx = (ix_float)*ip;
2241 put_ix_float(xp, &xx);
2242
2243 return NC_NOERR;
2244}
2245
2246static int
2247ncx_put_float_double(void *xp, const double *ip)
2248{
2249 ix_float xx = (ix_float)*ip;
2250 put_ix_float(xp, &xx);
2251 if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) return NC_ERANGE;
2252 return NC_NOERR;
2253}
2254
2255static int
2256ncx_put_float_longlong(void *xp, const longlong *ip)
2257{
2258 ix_float xx = (ix_float)*ip;
2259 put_ix_float(xp, &xx);
2260
2261 return NC_NOERR;
2262}
2263
2264static int
2265ncx_put_float_uchar(void *xp, const uchar *ip)
2266{
2267 ix_float xx = (ix_float)*ip;
2268 put_ix_float(xp, &xx);
2269
2270 return NC_NOERR;
2271}
2272
2273static int
2274ncx_put_float_ushort(void *xp, const ushort *ip)
2275{
2276 ix_float xx = (ix_float)*ip;
2277 put_ix_float(xp, &xx);
2278
2279 return NC_NOERR;
2280}
2281
2282static int
2283ncx_put_float_uint(void *xp, const uint *ip)
2284{
2285 ix_float xx = (ix_float)*ip;
2286 put_ix_float(xp, &xx);
2287
2288 return NC_NOERR;
2289}
2290
2291static int
2292ncx_put_float_ulonglong(void *xp, const ulonglong *ip)
2293{
2294 ix_float xx = (ix_float)*ip;
2295 put_ix_float(xp, &xx);
2296
2297 return NC_NOERR;
2298}
2299
2300
2301
2302/* x_double ------------------------------------------------------------------*/
2303
2304#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
2305
2306static void
2307get_ix_double(const void *xp, double *ip)
2308{
2309#ifdef WORDS_BIGENDIAN
2310 (void) memcpy(ipxp, sizeof(double));
2311#else
2312 swap8b(ipxp);
2313#endif
2314}
2315
2316static void
2317put_ix_double(void *xp, const double *ip)
2318{
2319#ifdef WORDS_BIGENDIAN
2320 (void) memcpy(xpipX_SIZEOF_DOUBLE);
2321#else
2322 swap8b(xpip);
2323#endif
2324}
2325
2326#elif vax
2327
2328/* What IEEE double precision floating point looks like on a Vax */
2329struct ieee_double {
2330 unsigned int exp_hi   : 7;
2331 unsigned int sign     : 1;
2332 unsigned int  mant_6   : 4;
2333 unsigned int exp_lo   : 4;
2334 unsigned int mant_5   : 8;
2335 unsigned int mant_4   : 8;
2336
2337 unsigned int mant_lo  : 32;
2338};
2339
2340/* Vax double precision floating point */
2341struct  vax_double {
2342 unsigned int mantissa1 : 7;
2343 unsigned int exp       : 8;
2344 unsigned int sign      : 1;
2345 unsigned int mantissa2 : 16;
2346 unsigned int mantissa3 : 16;
2347 unsigned int mantissa4 : 16;
2348};
2349
2350#define VAX_DBL_BIAS 0x81
2351#define IEEE_DBL_BIAS 0x3ff
2352#define MASK(nbits) ((1 << nbits) - 1)
2353
2354static const struct dbl_limits {
2355 struct vax_double d;
2356 struct ieee_double ieee;
2357dbl_limits[2] = {
2358 {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
2359 { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
2360 {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
2361 { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
2362};
2363
2364
2365static void
2366get_ix_double(const void *xp, double *ip)
2367{
2368 struct vax_double *const vdp =
2369  (struct vax_double *)ip;
2370 const struct ieee_double *const idp =
2371  (const struct ieee_double *) xp;
2372 {
2373 const struct dbl_limits *lim;
2374 int ii;
2375 for (ii = 0, lim = dbl_limits;
2376 ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
2377 ii++, lim++)
2378 {
2379 if ((idp->mant_lo == lim->ieee.mant_lo)
2380 && (idp->mant_4 == lim->ieee.mant_4)
2381 && (idp->mant_5 == lim->ieee.mant_5)
2382 && (idp->mant_6 == lim->ieee.mant_6)
2383 && (idp->exp_lo == lim->ieee.exp_lo)
2384 && (idp->exp_hi == lim->ieee.exp_hi)
2385 )
2386 {
2387 *vdp = lim->d;
2388 goto doneit;
2389 }
2390 }
2391 }
2392 {
2393 unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
2394 vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
2395 }
2396 {
2397 unsigned mant_hi = ((idp->mant_6 << 16)
2398  | (idp->mant_5 << 8)
2399  | idp->mant_4);
2400 unsigned mant_lo = SWAP4(idp->mant_lo);
2401 vdp->mantissa1 = (mant_hi >> 13);
2402 vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
2403 | (mant_lo >> 29);
2404 vdp->mantissa3 = (mant_lo >> 13);
2405 vdp->mantissa4 = (mant_lo << 3);
2406 }
2407 doneit:
2408 vdp->sign = idp->sign;
2409
2410}
2411
2412
2413static void
2414put_ix_double(void *xp, const double *ip)
2415{
2416 const struct vax_double *const vdp =
2417 (const struct vax_double *)ip;
2418 struct ieee_double *const idp =
2419  (struct ieee_double *) xp;
2420
2421 if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
2422 (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
2423 (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
2424 (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
2425 (vdp->exp == dbl_limits[0].d.exp))
2426 {
2427 *idp = dbl_limits[0].ieee;
2428 goto shipit;
2429 }
2430 if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
2431 (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
2432 (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
2433 (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
2434 (vdp->exp == dbl_limits[1].d.exp))
2435 {
2436 *idp = dbl_limits[1].ieee;
2437 goto shipit;
2438 }
2439
2440 {
2441 unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
2442
2443 unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
2444 (vdp->mantissa3 << 13) |
2445 ((vdp->mantissa4 >> 3) & MASK(13));
2446
2447 unsigned mant_hi = (vdp->mantissa1 << 13)
2448  | (vdp->mantissa2 >> 3);
2449
2450 if((vdp->mantissa4 & 7) > 4)
2451 {
2452 /* round up */
2453 mant_lo++;
2454 if(mant_lo == 0)
2455 {
2456 mant_hi++;
2457 if(mant_hi > 0xffffff)
2458 {
2459 mant_hi = 0;
2460 exp++;
2461 }
2462 }
2463 }
2464
2465 idp->mant_lo = SWAP4(mant_lo);
2466 idp->mant_6 = mant_hi >> 16;
2467 idp->mant_5 = (mant_hi & 0xff00) >> 8;
2468 idp->mant_4 = mant_hi;
2469 idp->exp_hi = exp >> 4;
2470 idp->exp_lo = exp;
2471 }
2472
2473 shipit:
2474 idp->sign = vdp->sign;
2475
2476}
2477
2478 /* vax */
2479#elif defined(_CRAY) && !defined(__crayx1)
2480
2481static void
2482get_ix_double(const void *xp, double *ip)
2483{
2484 const ieee_double *idp = (const ieee_double *) xp;
2485 cray_single *csp = (cray_single *) ip;
2486
2487 if(idp->exp == 0)
2488 {
2489 /* ieee subnormal */
2490 *ip = (double)idp->mant;
2491 if(idp->mant != 0)
2492 {
2493 csp->exp -= (ieee_double_bias + 51);
2494 }
2495 }
2496 else
2497 {
2498 csp->exp  = idp->exp + cs_id_bias + 1;
2499 csp->mant = idp->mant >> (52 - 48 + 1);
2500 csp->mant |= (1 << (48 - 1));
2501 }
2502 csp->sign = idp->sign;
2503}
2504
2505static void
2506put_ix_double(void *xp, const double *ip)
2507{
2508 ieee_double *idp = (ieee_double *) xp;
2509 const cray_single *csp = (const cray_single *) ip;
2510
2511 int ieee_exp = csp->exp - cs_id_bias -1;
2512
2513 idp->sign = csp->sign;
2514
2515 if(ieee_exp >= 0x7ff)
2516 {
2517 /* NC_ERANGE => ieee Inf */
2518 idp->exp = 0x7ff;
2519 idp->mant = 0x0;
2520 }
2521 else if(ieee_exp > 0)
2522 {
2523 /* normal ieee representation */
2524 idp->exp  = ieee_exp;
2525 /* assumes cray rep is in normal form */
2526 assert(csp->mant & 0x800000000000);
2527 idp->mant = (((csp->mant << 1) &
2528 0xffffffffffff) << (52 - 48));
2529 }
2530 else if(ieee_exp >= (-(52 -48)))
2531 {
2532 /* ieee subnormal, left shift */
2533 const int lshift = (52 - 48) + ieee_exp;
2534 idp->mant = csp->mant << lshift;
2535 idp->exp  = 0;
2536 }
2537 else if(ieee_exp >= -52)
2538 {
2539 /* ieee subnormal, right shift */
2540 const int rshift = (- (52 - 48) - ieee_exp);
2541
2542 idp->mant = csp->mant >> rshift;
2543
2544#if 0
2545 if(csp->mant & (1 << (rshift -1)))
2546 {
2547 /* round up */
2548 idp->mant++;
2549 }
2550#endif
2551
2552 idp->exp  = 0;
2553 }
2554 else
2555 {
2556 /* smaller than ieee can represent */
2557 idp->exp = 0;
2558 idp->mant = 0;
2559 }
2560}
2561#else
2562#error "ix_double implementation"
2563#endif
2564
2565#define ix_double double
2566
2567static int
2568ncx_get_double_schar(const void *xpschar *ip)
2569{
2570 ix_double xx;
2571 get_ix_double(xp, &xx);
2572 *ip = (scharxx;
2573 if(xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE;
2574 return NC_NOERR;
2575}
2576
2577static int
2578ncx_get_double_short(const void *xp, short *ip)
2579{
2580 ix_double xx;
2581 get_ix_double(xp, &xx);
2582 *ip = (short) xx;
2583 if(xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE;
2584 return NC_NOERR;
2585}
2586
2587static int
2588ncx_get_double_int(const void *xp, int *ip)
2589{
2590 ix_double xx;
2591 get_ix_double(xp, &xx);
2592 *ip = (int) xx;
2593 if(xx > INT_MAX || xx < INT_MIN) return NC_ERANGE;
2594 return NC_NOERR;
2595}
2596
2597static int
2598ncx_get_double_longlong(const void *xplonglong *ip)
2599{
2600 ix_double xx;
2601 get_ix_double(xp, &xx);
2602 *ip = (longlongxx;
2603 if(xx > LONGLONG_MAX || xx < LONGLONG_MIN) return NC_ERANGE;
2604 return NC_NOERR;
2605}
2606
2607static int
2608ncx_get_double_uchar(const void *xpuchar *ip)
2609{
2610 ix_double xx;
2611 get_ix_double(xp, &xx);
2612 *ip = (ucharxx;
2613 if(xx > UCHAR_MAX || xx < 0) return NC_ERANGE;
2614 return NC_NOERR;
2615}
2616
2617static int
2618ncx_get_double_ushort(const void *xpushort *ip)
2619{
2620 ix_double xx;
2621 get_ix_double(xp, &xx);
2622 *ip = (ushortxx;
2623 if(xx > USHORT_MAX || xx < 0) return NC_ERANGE;
2624 return NC_NOERR;
2625}
2626
2627static int
2628ncx_get_double_uint(const void *xpuint *ip)
2629{
2630 ix_double xx;
2631 get_ix_double(xp, &xx);
2632 *ip = (uintxx;
2633 if(xx > UINT_MAX || xx < 0) return NC_ERANGE;
2634 return NC_NOERR;
2635}
2636
2637
2638int
2639ncx_get_double_ulonglong(const void *xp, unsigned long long *ip)
2640{
2641 double xx;
2642 get_ix_double(xp, &xx);
2643 *ip = (unsigned long long) xx;
2644 if(xx > ULONG_LONG_MAX || xx < 0)
2645 return NC_ERANGE;
2646 return NC_NOERR;
2647}
2648
2649static int
2650ncx_get_double_float(const void *xp, float *ip)
2651{
2652 double xx;
2653 get_ix_double(xp, &xx);
2654 if(xx > FLT_MAX)
2655 {
2656 *ip = FLT_MAX;
2657 return NC_ERANGE;
2658 }
2659 if(xx < (-FLT_MAX))
2660 {
2661 *ip = (-FLT_MAX);
2662 return NC_ERANGE;
2663 }
2664 *ip = (float) xx;
2665 return NC_NOERR;
2666}
2667
2668#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
2669static int
2670ncx_get_double_double(const void *xp, double *ip)
2671{
2672 /* TODO */
2673 get_ix_double(xpip);
2674 return NC_NOERR;
2675}
2676#endif
2677
2678static int
2679ncx_put_double_schar(void *xp, const schar *ip)
2680{
2681 ix_double xx = (ix_double)*ip;
2682 put_ix_double(xp, &xx);
2683
2684 return NC_NOERR;
2685}
2686
2687static int
2688ncx_put_double_uchar(void *xp, const uchar *ip)
2689{
2690 ix_double xx = (ix_double)*ip;
2691 put_ix_double(xp, &xx);
2692
2693 return NC_NOERR;
2694}
2695
2696static int
2697ncx_put_double_short(void *xp, const short *ip)
2698{
2699 ix_double xx = (ix_double)*ip;
2700 put_ix_double(xp, &xx);
2701
2702 return NC_NOERR;
2703}
2704
2705static int
2706ncx_put_double_ushort(void *xp, const ushort *ip)
2707{
2708 ix_double xx = (ix_double)*ip;
2709 put_ix_double(xp, &xx);
2710
2711 return NC_NOERR;
2712}
2713
2714static int
2715ncx_put_double_int(void *xp, const int *ip)
2716{
2717 ix_double xx = (ix_double)*ip;
2718 put_ix_double(xp, &xx);
2719
2720 return NC_NOERR;
2721}
2722
2723static int
2724ncx_put_double_uint(void *xp, const uint *ip)
2725{
2726 ix_double xx = (ix_double)*ip;
2727 put_ix_double(xp, &xx);
2728
2729 return NC_NOERR;
2730}
2731
2732static int
2733ncx_put_double_longlong(void *xp, const longlong *ip)
2734{
2735 ix_double xx = (ix_double)*ip;
2736 put_ix_double(xp, &xx);
2737
2738 return NC_NOERR;
2739}
2740
2741static int
2742ncx_put_double_ulonglong(void *xp, const ulonglong *ip)
2743{
2744 ix_double xx = (ix_double)*ip;
2745 put_ix_double(xp, &xx);
2746
2747 return NC_NOERR;
2748}
2749
2750
2751static int
2752ncx_put_double_float(void *xp, const float *ip)
2753{
2754 double xx = (double) *ip;
2755 put_ix_double(xp, &xx);
2756#if 1 /* TODO: figure this out */
2757 if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
2758 return NC_ERANGE;
2759#endif
2760 return NC_NOERR;
2761}
2762
2763#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
2764static int
2765ncx_put_double_double(void *xp, const double *ip)
2766{
2767 put_ix_double(xpip);
2768#ifdef NO_IEEE_FLOAT
2769 if(*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN)
2770 return NC_ERANGE;
2771#endif
2772 return NC_NOERR;
2773}
2774#endif
2775
2776
2777/* x_longlong ---------------------------------------------------------------------*/
2778
2779#if SHORT_MAX == X_LONGLONG_MAX
2780typedef short ix_longlong;
2781#define SIZEOF_IX_LONGLONG SIZEOF_SHORT
2782#define IX_LONGLONG_MAX SHORT_MAX
2783#elif LONG_LONG_MAX  >= X_LONGLONG_MAX
2784typedef longlong ix_longlong;
2785#define SIZEOF_IX_LONGLONG SIZEOF_LONGLONG
2786#define IX_LONGLONG_MAX LONG_LONG_MAX
2787#elif LONG_MAX  >= X_LONGLONG_MAX
2788typedef long ix_longlong;
2789#define SIZEOF_IX_LONGLONG SIZEOF_LONG
2790#define IX_LONGLONG_MAX LONG_MAX
2791#else
2792#error "ix_longlong implementation"
2793#endif
2794
2795
2796static void
2797get_ix_longlong(const void *xpix_longlong *ip)
2798{
2799    const uchar *cp = (const uchar *) xp;
2800
2801    *ip  = ((long long)(*cp++) << 56);
2802    *ip |= ((long long)(*cp++) << 48);
2803    *ip |= ((long long)(*cp++) << 40);
2804    *ip |= ((long long)(*cp++) << 32);
2805    *ip |= ((long long)(*cp++) << 24);
2806    *ip |= ((long long)(*cp++) << 16);
2807    *ip |= ((long long)(*cp++) <<  8);
2808    *ip |=  (long long)*cp;
2809}
2810
2811static void
2812put_ix_longlong(void *xp, const ix_longlong *ip)
2813{
2814    uchar *cp = (uchar *) xp;
2815
2816    *cp++ = (*ip) >> 56;
2817    *cp++ = ((*ip) & 0x00ff000000000000LL) >> 48;
2818    *cp++ = ((*ip) & 0x0000ff0000000000LL) >> 40;
2819    *cp++ = ((*ip) & 0x000000ff00000000LL) >> 32;
2820    *cp++ = ((*ip) & 0x00000000ff000000LL) >> 24;
2821    *cp++ = ((*ip) & 0x0000000000ff0000LL) >> 16;
2822    *cp++ = ((*ip) & 0x000000000000ff00LL) >>  8;
2823    *cp   = ((*ip) & 0x00000000000000ffLL);
2824}
2825
2826static int
2827ncx_get_longlong_schar(const void *xpschar *ip)
2828{
2829 ix_longlong xx;
2830 get_ix_longlong(xp, &xx);
2831 *ip = (scharxx;
2832#if IX_LONGLONG_MAX > SCHAR_MAX
2833 if (xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE;
2834#endif
2835
2836 return NC_NOERR;
2837}
2838
2839static int
2840ncx_get_longlong_short(const void *xp, short *ip)
2841{
2842#if SIZEOF_IX_LONGLONG == SIZEOF_SHORT && IX_LONGLONG_MAX == SHORT_MAX
2843 get_ix_longlong(xp, (ix_longlong *)ip);
2844 return NC_NOERR;
2845#else
2846 ix_longlong xx;
2847 get_ix_longlong(xp, &xx);
2848 *ip = (short) xx;
2849#if IX_LONGLONG_MAX > SHORT_MAX
2850 if (xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE;
2851#endif
2852
2853#endif
2854 return NC_NOERR;
2855}
2856
2857static int
2858ncx_get_longlong_int(const void *xp, int *ip)
2859{
2860#if SIZEOF_IX_LONGLONG == SIZEOF_INT && IX_LONGLONG_MAX == INT_MAX
2861 get_ix_longlong(xp, (ix_longlong *)ip);
2862 return NC_NOERR;
2863#else
2864 ix_longlong xx;
2865 get_ix_longlong(xp, &xx);
2866 *ip = (int) xx;
2867#if IX_LONGLONG_MAX > INT_MAX
2868 if (xx > INT_MAX || xx < INT_MIN) return NC_ERANGE;
2869#endif
2870
2871#endif
2872 return NC_NOERR;
2873}
2874
2875static int
2876ncx_get_longlong_longlong(const void *xplonglong *ip)
2877{
2878#if SIZEOF_IX_LONGLONG == SIZEOF_LONGLONG && IX_LONGLONG_MAX == LONGLONG_MAX
2879 get_ix_longlong(xp, (ix_longlong *)ip);
2880 return NC_NOERR;
2881#else
2882 ix_longlong xx;
2883 get_ix_longlong(xp, &xx);
2884 *ip = (longlongxx;
2885#if IX_LONGLONG_MAX > LONGLONG_MAX
2886 if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) return NC_ERANGE;
2887#endif
2888
2889#endif
2890 return NC_NOERR;
2891}
2892
2893static int
2894ncx_get_longlong_ushort(const void *xpushort *ip)
2895{
2896 ix_longlong xx;
2897 get_ix_longlong(xp, &xx);
2898 *ip = (ushortxx;
2899#if IX_LONGLONG_MAX > USHORT_MAX
2900 if (xx > USHORT_MAX) return NC_ERANGE;
2901#endif
2902 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
2903 return NC_NOERR;
2904}
2905
2906static int
2907ncx_get_longlong_uchar(const void *xpuchar *ip)
2908{
2909 ix_longlong xx;
2910 get_ix_longlong(xp, &xx);
2911 *ip = (ucharxx;
2912#if IX_LONGLONG_MAX > UCHAR_MAX
2913 if (xx > UCHAR_MAX) return NC_ERANGE;
2914#endif
2915 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
2916 return NC_NOERR;
2917}
2918
2919static int
2920ncx_get_longlong_uint(const void *xpuint *ip)
2921{
2922 ix_longlong xx;
2923 get_ix_longlong(xp, &xx);
2924 *ip = (uintxx;
2925#if IX_LONGLONG_MAX > UINT_MAX
2926 if (xx > UINT_MAX) return NC_ERANGE;
2927#endif
2928 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
2929 return NC_NOERR;
2930}
2931
2932static int
2933ncx_get_longlong_ulonglong(const void *xpulonglong *ip)
2934{
2935 ix_longlong xx;
2936 get_ix_longlong(xp, &xx);
2937 *ip = (ulonglongxx;
2938#if IX_LONGLONG_MAX > ULONGLONG_MAX
2939 if (xx > ULONGLONG_MAX) return NC_ERANGE;
2940#endif
2941 if (xx < 0) return NC_ERANGE; /* because ip is unsigned */
2942 return NC_NOERR;
2943}
2944
2945static int
2946ncx_get_longlong_float(const void *xp, float *ip)
2947{
2948 ix_longlong xx;
2949 get_ix_longlong(xp, &xx);
2950 *ip = (float) xx;
2951
2952 return NC_NOERR;
2953}
2954
2955static int
2956ncx_get_longlong_double(const void *xp, double *ip)
2957{
2958 ix_longlong xx;
2959 get_ix_longlong(xp, &xx);
2960 *ip = (double) xx;
2961
2962 return NC_NOERR;
2963}
2964
2965
2966static int
2967ncx_put_longlong_schar(void *xp, const schar *ip)
2968{
2969 ix_longlong xx = (ix_longlong)*ip;
2970 put_ix_longlong(xp, &xx);
2971#if IX_LONGLONG_MAX < SCHAR_MAX
2972 if (*ip > IX_LONGLONG_MAX || *ip < X_LONGLONG_MIN) return NC_ERANGE;
2973#endif
2974
2975 return NC_NOERR;
2976}
2977
2978static int
2979ncx_put_longlong_short(void *xp, const short *ip)
2980{
2981#if SIZEOF_IX_LONGLONG == SIZEOF_SHORT && IX_LONGLONG_MAX == SHORT_MAX
2982 put_ix_longlong(xp, (const ix_longlong *)ip);
2983 return NC_NOERR;
2984#else
2985 ix_longlong xx = (ix_longlong)*ip;
2986 put_ix_longlong(xp, &xx);
2987#if IX_LONGLONG_MAX < SHORT_MAX
2988 if (*ip > IX_LONGLONG_MAX || *ip < X_LONGLONG_MIN) return NC_ERANGE;
2989#endif
2990
2991#endif
2992 return NC_NOERR;
2993}
2994
2995static int
2996ncx_put_longlong_int(void *xp, const int *ip)
2997{
2998#if SIZEOF_IX_LONGLONG == SIZEOF_INT && IX_LONGLONG_MAX == INT_MAX
2999 put_ix_longlong(xp, (const ix_longlong *)ip);
3000 return NC_NOERR;
3001#else
3002 ix_longlong xx = (ix_longlong)*ip;
3003 put_ix_longlong(xp, &xx);
3004#if IX_LONGLONG_MAX < INT_MAX
3005 if (*ip > IX_LONGLONG_MAX || *ip < X_LONGLONG_MIN) return NC_ERANGE;
3006#endif
3007
3008#endif
3009 return NC_NOERR;
3010}
3011
3012static int
3013ncx_put_longlong_longlong(void *xp, const longlong *ip)
3014{
3015#if SIZEOF_IX_LONGLONG == SIZEOF_LONGLONG && IX_LONGLONG_MAX == LONGLONG_MAX
3016 put_ix_longlong(xp, (const ix_longlong *)ip);
3017 return NC_NOERR;
3018#else
3019 ix_longlong xx = (ix_longlong)*ip;
3020 put_ix_longlong(xp, &xx);
3021#if IX_LONGLONG_MAX < LONGLONG_MAX
3022 if (*ip > IX_LONGLONG_MAX || *ip < X_LONGLONG_MIN) return NC_ERANGE;
3023#endif
3024
3025#endif
3026 return NC_NOERR;
3027}
3028
3029static int
3030ncx_put_longlong_ushort(void *xp, const ushort *ip)
3031{
3032 ix_longlong xx = (ix_longlong)*ip;
3033 put_ix_longlong(xp, &xx);
3034#if IX_LONGLONG_MAX < USHORT_MAX
3035 if (*ip > IX_LONGLONG_MAX) return NC_ERANGE;
3036#endif
3037
3038 return NC_NOERR;
3039}
3040
3041static int
3042ncx_put_longlong_uchar(void *xp, const uchar *ip)
3043{
3044 ix_longlong xx = (ix_longlong)*ip;
3045 put_ix_longlong(xp, &xx);
3046#if IX_LONGLONG_MAX < UCHAR_MAX
3047 if (*ip > IX_LONGLONG_MAX) return NC_ERANGE;
3048#endif
3049
3050 return NC_NOERR;
3051}
3052
3053static int
3054ncx_put_longlong_uint(void *xp, const uint *ip)
3055{
3056 ix_longlong xx = (ix_longlong)*ip;
3057 put_ix_longlong(xp, &xx);
3058#if IX_LONGLONG_MAX < UINT_MAX
3059 if (*ip > IX_LONGLONG_MAX) return NC_ERANGE;
3060#endif
3061
3062 return NC_NOERR;
3063}
3064
3065static int
3066ncx_put_longlong_ulonglong(void *xp, const ulonglong *ip)
3067{
3068 ix_longlong xx = (ix_longlong)*ip;
3069 put_ix_longlong(xp, &xx);
3070#if IX_LONGLONG_MAX < ULONGLONG_MAX
3071 if (*ip > IX_LONGLONG_MAX) return NC_ERANGE;
3072#endif
3073
3074 return NC_NOERR;
3075}
3076
3077static int
3078ncx_put_longlong_float(void *xp, const float *ip)
3079{
3080 ix_longlong xx = (ix_longlong)*ip;
3081 put_ix_longlong(xp, &xx);
3082 if(*ip > (double)X_LONGLONG_MAX || *ip < (double)X_LONGLONG_MIN) return NC_ERANGE;
3083 return NC_NOERR;
3084}
3085
3086static int
3087ncx_put_longlong_double(void *xp, const double *ip)
3088{
3089 ix_longlong xx = (ix_longlong)*ip;
3090 put_ix_longlong(xp, &xx);
3091 if(*ip > X_LONGLONG_MAX || *ip < X_LONGLONG_MIN) return NC_ERANGE;
3092 return NC_NOERR;
3093}
3094
3095
3096/* x_ulonglong --------------------------------------------------------------------*/
3097
3098#if USHORT_MAX == X_ULONGLONG_MAX
3099typedef ushort ix_ulonglong;
3100#define SIZEOF_IX_ULONGLONG SIZEOF_USHORT
3101#define IX_ULONGLONG_MAX USHORT_MAX
3102#elif ULONG_LONG_MAX  >= X_ULONGLONG_MAX
3103typedef ulonglong ix_ulonglong;
3104#define SIZEOF_IX_ULONGLONG SIZEOF_ULONGLONG
3105#define IX_ULONGLONG_MAX ULONG_LONG_MAX
3106#elif ULONG_MAX  >= X_ULONGLONG_MAX
3107typedef ulong ix_ulonglong;
3108#define SIZEOF_IX_ULONGLONG SIZEOF_ULONG
3109#define IX_ULONGLONG_MAX ULONG_MAX
3110#else
3111#error "ix_ulonglong implementation"
3112#endif
3113
3114
3115static void
3116get_ix_ulonglong(const void *xpix_ulonglong *ip)
3117{
3118    const uchar *cp = (const uchar *) xp;
3119
3120    *ip  = ((unsigned long long)(*cp++) << 56);
3121    *ip |= ((unsigned long long)(*cp++) << 48);
3122    *ip |= ((unsigned long long)(*cp++) << 40);
3123    *ip |= ((unsigned long long)(*cp++) << 32);
3124    *ip |= ((unsigned long long)(*cp++) << 24);
3125    *ip |= ((unsigned long long)(*cp++) << 16);
3126    *ip |= ((unsigned long long)(*cp++) <<  8);
3127    *ip |=  (unsigned long long)*cp;
3128}
3129
3130static void
3131put_ix_ulonglong(void *xp, const ix_ulonglong *ip)
3132{
3133    uchar *cp = (uchar *) xp;
3134
3135    *cp++ = (*ip) >> 56;
3136    *cp++ = ((*ip) & 0x00ff000000000000ULL) >> 48;
3137    *cp++ = ((*ip) & 0x0000ff0000000000ULL) >> 40;
3138    *cp++ = ((*ip) & 0x000000ff00000000ULL) >> 32;
3139    *cp++ = ((*ip) & 0x00000000ff000000ULL) >> 24;
3140    *cp++ = ((*ip) & 0x0000000000ff0000ULL) >> 16;
3141    *cp++ = ((*ip) & 0x000000000000ff00ULL) >>  8;
3142    *cp   = ((*ip) & 0x00000000000000ffULL);
3143}
3144
3145static int
3146ncx_get_ulonglong_schar(const void *xpschar *ip)
3147{
3148 ix_ulonglong xx;
3149 get_ix_ulonglong(xp, &xx);
3150 *ip = (scharxx;
3151#if IX_ULONGLONG_MAX > SCHAR_MAX
3152 if (xx > SCHAR_MAX) return NC_ERANGE;
3153#endif
3154
3155 return NC_NOERR;
3156}
3157
3158static int
3159ncx_get_ulonglong_short(const void *xp, short *ip)
3160{
3161 ix_ulonglong xx;
3162 get_ix_ulonglong(xp, &xx);
3163 *ip = (short) xx;
3164#if IX_ULONGLONG_MAX > SHORT_MAX
3165 if (xx > SHORT_MAX) return NC_ERANGE;
3166#endif
3167
3168 return NC_NOERR;
3169}
3170
3171static int
3172ncx_get_ulonglong_int(const void *xp, int *ip)
3173{
3174 ix_ulonglong xx;
3175 get_ix_ulonglong(xp, &xx);
3176 *ip = (int) xx;
3177#if IX_ULONGLONG_MAX > INT_MAX
3178 if (xx > INT_MAX) return NC_ERANGE;
3179#endif
3180
3181 return NC_NOERR;
3182}
3183
3184static int
3185ncx_get_ulonglong_longlong(const void *xplonglong *ip)
3186{
3187 ix_ulonglong xx;
3188 get_ix_ulonglong(xp, &xx);
3189 *ip = (longlongxx;
3190#if IX_ULONGLONG_MAX > LONGLONG_MAX
3191 if (xx > LONGLONG_MAX) return NC_ERANGE;
3192#endif
3193
3194 return NC_NOERR;
3195}
3196
3197static int
3198ncx_get_ulonglong_ushort(const void *xpushort *ip)
3199{
3200#if SIZEOF_IX_ULONGLONG == SIZEOF_USHORT && IX_ULONGLONG_MAX == USHORT_MAX
3201 get_ix_ulonglong(xp, (ix_ulonglong *)ip);
3202 return NC_NOERR;
3203#else
3204 ix_ulonglong xx;
3205 get_ix_ulonglong(xp, &xx);
3206 *ip = (ushortxx;
3207#if IX_ULONGLONG_MAX > USHORT_MAX
3208 if (xx > USHORT_MAX) return NC_ERANGE;
3209#endif
3210
3211#endif
3212 return NC_NOERR;
3213}
3214
3215static int
3216ncx_get_ulonglong_uchar(const void *xpuchar *ip)
3217{
3218#if SIZEOF_IX_ULONGLONG == SIZEOF_UCHAR && IX_ULONGLONG_MAX == UCHAR_MAX
3219 get_ix_ulonglong(xp, (ix_ulonglong *)ip);
3220 return NC_NOERR;
3221#else
3222 ix_ulonglong xx;
3223 get_ix_ulonglong(xp, &xx);
3224 *ip = (ucharxx;
3225#if IX_ULONGLONG_MAX > UCHAR_MAX
3226 if (xx > UCHAR_MAX) return NC_ERANGE;
3227#endif
3228
3229#endif
3230 return NC_NOERR;
3231}
3232
3233static int
3234ncx_get_ulonglong_uint(const void *xpuint *ip)
3235{
3236#if SIZEOF_IX_ULONGLONG == SIZEOF_UINT && IX_ULONGLONG_MAX == UINT_MAX
3237 get_ix_ulonglong(xp, (ix_ulonglong *)ip);
3238 return NC_NOERR;
3239#else
3240 ix_ulonglong xx;
3241 get_ix_ulonglong(xp, &xx);
3242 *ip = (uintxx;
3243#if IX_ULONGLONG_MAX > UINT_MAX
3244 if (xx > UINT_MAX) return NC_ERANGE;
3245#endif
3246
3247#endif
3248 return NC_NOERR;
3249}
3250
3251static int
3252ncx_get_ulonglong_ulonglong(const void *xpulonglong *ip)
3253{
3254#if SIZEOF_IX_ULONGLONG == SIZEOF_ULONGLONG && IX_ULONGLONG_MAX == ULONGLONG_MAX
3255 get_ix_ulonglong(xp, (ix_ulonglong *)ip);
3256 return NC_NOERR;
3257#else
3258 ix_ulonglong xx;
3259 get_ix_ulonglong(xp, &xx);
3260 *ip = (ulonglongxx;
3261#if IX_ULONGLONG_MAX > ULONGLONG_MAX
3262 if (xx > ULONGLONG_MAX) return NC_ERANGE;
3263#endif
3264
3265#endif
3266 return NC_NOERR;
3267}
3268
3269static int
3270ncx_get_ulonglong_float(const void *xp, float *ip)
3271{
3272 ix_ulonglong xx;
3273 get_ix_ulonglong(xp, &xx);
3274 *ip = (float) xx;
3275
3276 return NC_NOERR;
3277}
3278
3279static int
3280ncx_get_ulonglong_double(const void *xp, double *ip)
3281{
3282 ix_ulonglong xx;
3283 get_ix_ulonglong(xp, &xx);
3284 *ip = (double) xx;
3285
3286 return NC_NOERR;
3287}
3288
3289
3290static int
3291ncx_put_ulonglong_schar(void *xp, const schar *ip)
3292{
3293 ix_ulonglong xx = (ix_ulonglong)*ip;
3294 put_ix_ulonglong(xp, &xx);
3295#if IX_ULONGLONG_MAX < SCHAR_MAX
3296 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3297#endif
3298 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
3299 return NC_NOERR;
3300}
3301
3302static int
3303ncx_put_ulonglong_short(void *xp, const short *ip)
3304{
3305 ix_ulonglong xx = (ix_ulonglong)*ip;
3306 put_ix_ulonglong(xp, &xx);
3307#if IX_ULONGLONG_MAX < SHORT_MAX
3308 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3309#endif
3310 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
3311 return NC_NOERR;
3312}
3313
3314static int
3315ncx_put_ulonglong_int(void *xp, const int *ip)
3316{
3317 ix_ulonglong xx = (ix_ulonglong)*ip;
3318 put_ix_ulonglong(xp, &xx);
3319#if IX_ULONGLONG_MAX < INT_MAX
3320 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3321#endif
3322 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
3323 return NC_NOERR;
3324}
3325
3326static int
3327ncx_put_ulonglong_longlong(void *xp, const longlong *ip)
3328{
3329 ix_ulonglong xx = (ix_ulonglong)*ip;
3330 put_ix_ulonglong(xp, &xx);
3331#if IX_ULONGLONG_MAX < LONGLONG_MAX
3332 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3333#endif
3334 if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */
3335 return NC_NOERR;
3336}
3337
3338static int
3339ncx_put_ulonglong_uchar(void *xp, const uchar *ip)
3340{
3341#if SIZEOF_IX_ULONGLONG == SIZEOF_UCHAR && IX_ULONGLONG_MAX == UCHAR_MAX
3342 put_ix_ulonglong(xp, (const ix_ulonglong *)ip);
3343 return NC_NOERR;
3344#else
3345 ix_ulonglong xx = (ix_ulonglong)*ip;
3346 put_ix_ulonglong(xp, &xx);
3347#if IX_ULONGLONG_MAX < UCHAR_MAX
3348 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3349#endif
3350
3351#endif
3352 return NC_NOERR;
3353}
3354
3355static int
3356ncx_put_ulonglong_ushort(void *xp, const ushort *ip)
3357{
3358#if SIZEOF_IX_ULONGLONG == SIZEOF_USHORT && IX_ULONGLONG_MAX == USHORT_MAX
3359 put_ix_ulonglong(xp, (const ix_ulonglong *)ip);
3360 return NC_NOERR;
3361#else
3362 ix_ulonglong xx = (ix_ulonglong)*ip;
3363 put_ix_ulonglong(xp, &xx);
3364#if IX_ULONGLONG_MAX < USHORT_MAX
3365 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3366#endif
3367
3368#endif
3369 return NC_NOERR;
3370}
3371
3372static int
3373ncx_put_ulonglong_uint(void *xp, const uint *ip)
3374{
3375#if SIZEOF_IX_ULONGLONG == SIZEOF_UINT && IX_ULONGLONG_MAX == UINT_MAX
3376 put_ix_ulonglong(xp, (const ix_ulonglong *)ip);
3377 return NC_NOERR;
3378#else
3379 ix_ulonglong xx = (ix_ulonglong)*ip;
3380 put_ix_ulonglong(xp, &xx);
3381#if IX_ULONGLONG_MAX < UINT_MAX
3382 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3383#endif
3384
3385#endif
3386 return NC_NOERR;
3387}
3388
3389static int
3390ncx_put_ulonglong_ulonglong(void *xp, const ulonglong *ip)
3391{
3392#if SIZEOF_IX_ULONGLONG == SIZEOF_ULONGLONG && IX_ULONGLONG_MAX == ULONGLONG_MAX
3393 put_ix_ulonglong(xp, (const ix_ulonglong *)ip);
3394 return NC_NOERR;
3395#else
3396 ix_ulonglong xx = (ix_ulonglong)*ip;
3397 put_ix_ulonglong(xp, &xx);
3398#if IX_ULONGLONG_MAX < ULONGLONG_MAX
3399 if (*ip > IX_ULONGLONG_MAX) return NC_ERANGE;
3400#endif
3401
3402#endif
3403 return NC_NOERR;
3404}
3405
3406static int
3407ncx_put_ulonglong_float(void *xp, const float *ip)
3408{
3409 ix_ulonglong xx = (ix_ulonglong)*ip;
3410 put_ix_ulonglong(xp, &xx);
3411 if(*ip > (double)X_ULONGLONG_MAX || *ip < 0) return NC_ERANGE;
3412 return NC_NOERR;
3413}
3414
3415static int
3416ncx_put_ulonglong_double(void *xp, const double *ip)
3417{
3418 ix_ulonglong xx = (ix_ulonglong)*ip;
3419 put_ix_ulonglong(xp, &xx);
3420 if(*ip > X_ULONGLONG_MAX || *ip < 0) return NC_ERANGE;
3421 return NC_NOERR;
3422}
3423
3424
3425/* x_size_t */
3426
3427#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
3428#error "x_size_t implementation"
3429/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
3430#endif
3431
3432int
3433ncx_put_size_t(void **xpp, const size_t *ulp)
3434{
3435 /* similar to put_ix_int() */
3436 uchar *cp = (uchar *) *xpp;
3437 assert(*ulp <= X_SIZE_MAX);
3438
3439 *cp++ = (uchar)((*ulp) >> 24);
3440 *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
3441 *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
3442 *cp   = (uchar)((*ulp) & 0x000000ff);
3443
3444 *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
3445 return NC_NOERR;
3446}
3447
3448int
3449ncx_get_size_t(const void **xpp,  size_t *ulp)
3450{
3451 /* similar to get_ix_int */
3452 const uchar *cp = (const uchar *) *xpp;
3453
3454 *ulp = (unsigned)(*cp++ << 24);
3455 *ulp |= (*cp++ << 16);
3456 *ulp |= (*cp++ << 8);
3457 *ulp |= *cp;
3458
3459 *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
3460 return NC_NOERR;
3461}
3462
3463/* x_off_t */
3464
3465int
3466ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
3467{
3468 /* similar to put_ix_int() */
3469 uchar *cp = (uchar *) *xpp;
3470 /* No negative offsets stored in netcdf */
3471 if (*lp < 0) {
3472   /* Assume this is an overflow of a 32-bit int... */
3473   return NC_ERANGE;
3474 }
3475
3476 assert(sizeof_off_t == 4 || sizeof_off_t == 8);
3477
3478 if (sizeof_off_t == 4) {
3479 *cp++ = (uchar) ((*lp)               >> 24);
3480 *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
3481 *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
3482 *cp   = (uchar)( (*lp) & 0x000000ff);
3483 } else {
3484#if SIZEOF_OFF_T == 4
3485/* Write a 64-bit offset on a system with only a 32-bit offset */
3486 *cp++ = (uchar)0;
3487 *cp++ = (uchar)0;
3488 *cp++ = (uchar)0;
3489 *cp++ = (uchar)0;
3490
3491 *cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
3492 *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
3493 *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
3494 *cp   = (uchar)( (*lp) & 0x000000ff);
3495#else
3496 *cp++ = (uchar) ((*lp)                          >> 56);
3497 *cp++ = (uchar)(((*lp) & 0x00ff000000000000ULL) >> 48);
3498 *cp++ = (uchar)(((*lp) & 0x0000ff0000000000ULL) >> 40);
3499 *cp++ = (uchar)(((*lp) & 0x000000ff00000000ULL) >> 32);
3500 *cp++ = (uchar)(((*lp) & 0x00000000ff000000ULL) >> 24);
3501 *cp++ = (uchar)(((*lp) & 0x0000000000ff0000ULL) >> 16);
3502 *cp++ = (uchar)(((*lp) & 0x000000000000ff00ULL) >>  8);
3503 *cp   = (uchar)( (*lp) & 0x00000000000000ffULL);
3504#endif
3505 }
3506 *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
3507 return NC_NOERR;
3508}
3509
3510int
3511ncx_get_off_t(const void **xppoff_t *lp, size_t sizeof_off_t)
3512{
3513 /* similar to get_ix_int() */
3514 const uchar *cp = (const uchar *) *xpp;
3515 assert(sizeof_off_t == 4 || sizeof_off_t == 8);
3516
3517  if (sizeof_off_t == 4) {
3518 *lp =  (off_t)(*cp++ << 24);
3519 *lp |= (off_t)(*cp++ << 16);
3520 *lp |= (off_t)(*cp++ <<  8);
3521 *lp |= (off_t)*cp;
3522 } else {
3523#if SIZEOF_OFF_T == 4
3524/* Read a 64-bit offset on a system with only a 32-bit offset */
3525/* If the offset overflows, set an error code and return */
3526 *lp =  ((off_t)(*cp++) << 24);
3527 *lp |= ((off_t)(*cp++) << 16);
3528 *lp |= ((off_t)(*cp++) <<  8);
3529 *lp |= ((off_t)(*cp++));
3530/*
3531 * lp now contains the upper 32-bits of the 64-bit offset.  if lp is
3532 * not zero, then the dataset is larger than can be represented
3533 * on this system.  Set an error code and return.
3534 */
3535 if (*lp != 0) {
3536   return NC_ERANGE;
3537 }
3538
3539 *lp  = ((off_t)(*cp++) << 24);
3540 *lp |= ((off_t)(*cp++) << 16);
3541 *lp |= ((off_t)(*cp++) <<  8);
3542 *lp |=  (off_t)*cp;
3543
3544 if (*lp < 0) {
3545   /*
3546    * If this fails, then the offset is >2^31, but less
3547    * than 2^32 which is not allowed, but is not caught
3548    * by the previous check
3549    */
3550   return NC_ERANGE;
3551 }
3552#else
3553 *lp =  ((off_t)(*cp++) << 56);
3554 *lp |= ((off_t)(*cp++) << 48);
3555 *lp |= ((off_t)(*cp++) << 40);
3556 *lp |= ((off_t)(*cp++) << 32);
3557 *lp |= ((off_t)(*cp++) << 24);
3558 *lp |= ((off_t)(*cp++) << 16);
3559 *lp |= ((off_t)(*cp++) <<  8);
3560 *lp |=  (off_t)*cp;
3561#endif
3562 }
3563 *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
3564 return NC_NOERR;
3565}
3566
3567/*----< ncx_get_int32() >--------------------------------------------------*/
3568int
3569ncx_get_int32(const void **xpp,
3570              int         *ip)
3571{
3572    const uchar *cp = (const uchar *) *xpp;
3573
3574    /* cannot call swap4b(), as lp is 8-byte */
3575    *ip  = (*cp++ << 24);
3576    *ip |= (*cp++ << 16);
3577    *ip |= (*cp++ <<  8);
3578    *ip |=  *cp;
3579
3580    /* advance *xpp 4 bytes */
3581    *xpp = (void *)((const char *)(*xpp) + 4);
3582
3583    return NC_NOERR;
3584}
3585
3586/*----< ncx_get_int64() >-------------------------------------------------*/
3587int
3588ncx_get_int64(const void **xpp,
3589              long long   *llp)
3590{
3591    const uchar *cp = (const uchar *) *xpp;
3592
3593    /* below is the same as calling swap8b(llp, *xpp) */
3594    *llp  = ((long long)(*cp++) << 56);
3595    *llp |= ((long long)(*cp++) << 48);
3596    *llp |= ((long long)(*cp++) << 40);
3597    *llp |= ((long long)(*cp++) << 32);
3598    *llp |= ((long long)(*cp++) << 24);
3599    *llp |= ((long long)(*cp++) << 16);
3600    *llp |= ((long long)(*cp++) <<  8);
3601    *llp |=  (long long)*cp;
3602
3603    /* advance *xpp 8 bytes */
3604    *xpp = (void *)((const char *)(*xpp) + 8);
3605
3606    return NC_NOERR;
3607}
3608
3609/*---< ncx_put_int32() >-----------------------------------------------------*/
3610/* copy the contents of lp (a signed 32-bit integer) to xpp in Big Endian
3611 * form and advance *xpp 4 bytes
3612 */
3613int
3614ncx_put_int32(void      **xpp,
3615              const int   ip)
3616{
3617#ifdef WORDS_BIGENDIAN
3618    int *ptr = (int*) (*xpp); /* typecast to 4-byte integer */
3619    *ptr = ip;
3620#else
3621    /* bitwise shifts below are to produce an integer in Big Endian */
3622    /* cannot call swap4b(), as lp is 8-byte */
3623    uchar *cp = (uchar *) *xpp;
3624    *cp++ = (uchar)((ip & 0xff000000) >> 24);
3625    *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
3626    *cp++ = (uchar)((ip & 0x0000ff00) >>  8);
3627    *cp   = (uchar)( ip & 0x000000ff);
3628#endif
3629    /* advance *xpp 4 bytes */
3630    *xpp  = (void *)((char *)(*xpp) + 4);
3631
3632    return NC_NOERR;
3633}
3634
3635/*---< ncx_put_int64() >-----------------------------------------------------*/
3636/* copy the contents of lp (a signed 64-bit integer) to xpp in Big Endian
3637 * form and advance *xpp 8 bytes
3638 */
3639int
3640ncx_put_int64(void             **xpp,
3641              const long long    ip)
3642{
3643#ifdef WORDS_BIGENDIAN
3644    long long *ptr = (long long*) (*xpp); /* typecast to 8-byte integer */
3645    *ptr = ip;
3646#else
3647    uchar *cp = (uchar *) *xpp;
3648    /* below is the same as calling swap8b(*xpp, &ip) */
3649    *cp++ = (uchar)((ip & 0xff00000000000000ULL) >> 56);
3650    *cp++ = (uchar)((ip & 0x00ff000000000000ULL) >> 48);
3651    *cp++ = (uchar)((ip & 0x0000ff0000000000ULL) >> 40);
3652    *cp++ = (uchar)((ip & 0x000000ff00000000ULL) >> 32);
3653    *cp++ = (uchar)((ip & 0x00000000ff000000ULL) >> 24);
3654    *cp++ = (uchar)((ip & 0x0000000000ff0000ULL) >> 16);
3655    *cp++ = (uchar)((ip & 0x000000000000ff00ULL) >>  8);
3656    *cp   = (uchar)( ip & 0x00000000000000ffULL);
3657#endif
3658    /* advance *xpp 8 bytes */
3659    *xpp  = (void *)((char *)(*xpp) + 8);
3660
3661    return NC_NOERR;
3662}
3663
3664
3665/*
3666 * Aggregate numeric conversion functions.
3667 */
3668
3669
3670
3671/* schar ---------------------------------------------------------------------*/
3672
3673int
3674ncx_getn_schar_schar(const void **xpp, size_t nelemsschar *tp)
3675{
3676 (void) memcpy(tp, *xppnelems);
3677 *xpp = (void *)((schar *)(*xpp) + nelems);
3678 return NC_NOERR;
3679
3680}
3681int
3682ncx_getn_schar_uchar(const void **xpp, size_t nelemsuchar *tp)
3683{
3684 (void) memcpy(tp, *xppnelems);
3685 *xpp = (void *)((schar *)(*xpp) + nelems);
3686 return NC_NOERR;
3687
3688}
3689int
3690ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
3691{
3692 int status = NC_NOERR;
3693 schar *xp = (schar *)(*xpp);
3694
3695 while(nelems-- != 0)
3696 {
3697
3698 *tp++ = *xp++;
3699 }
3700
3701 *xpp = (const void *)xp;
3702 return status;
3703}
3704
3705int
3706ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
3707{
3708 int status = NC_NOERR;
3709 schar *xp = (schar *)(*xpp);
3710
3711 while(nelems-- != 0)
3712 {
3713
3714 *tp++ = *xp++;
3715 }
3716
3717 *xpp = (const void *)xp;
3718 return status;
3719}
3720
3721int
3722ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
3723{
3724 int status = NC_NOERR;
3725 schar *xp = (schar *)(*xpp);
3726
3727 while(nelems-- != 0)
3728 {
3729
3730 *tp++ = *xp++;
3731 }
3732
3733 *xpp = (const void *)xp;
3734 return status;
3735}
3736
3737int
3738ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
3739{
3740 int status = NC_NOERR;
3741 schar *xp = (schar *)(*xpp);
3742
3743 while(nelems-- != 0)
3744 {
3745
3746 *tp++ = *xp++;
3747 }
3748
3749 *xpp = (const void *)xp;
3750 return status;
3751}
3752
3753int
3754ncx_getn_schar_longlong(const void **xpp, size_t nelemslonglong *tp)
3755{
3756 int status = NC_NOERR;
3757 schar *xp = (schar *)(*xpp);
3758
3759 while(nelems-- != 0)
3760 {
3761
3762 *tp++ = *xp++;
3763 }
3764
3765 *xpp = (const void *)xp;
3766 return status;
3767}
3768
3769int
3770ncx_getn_schar_ushort(const void **xpp, size_t nelemsushort *tp)
3771{
3772 int status = NC_NOERR;
3773 schar *xp = (schar *)(*xpp);
3774
3775 while(nelems-- != 0)
3776 {
3777 if (*xp < 0) status = NC_ERANGE;
3778 *tp++ = *xp++;
3779 }
3780
3781 *xpp = (const void *)xp;
3782 return status;
3783}
3784
3785int
3786ncx_getn_schar_uint(const void **xpp, size_t nelemsuint *tp)
3787{
3788 int status = NC_NOERR;
3789 schar *xp = (schar *)(*xpp);
3790
3791 while(nelems-- != 0)
3792 {
3793 if (*xp < 0) status = NC_ERANGE;
3794 *tp++ = *xp++;
3795 }
3796
3797 *xpp = (const void *)xp;
3798 return status;
3799}
3800
3801int
3802ncx_getn_schar_ulonglong(const void **xpp, size_t nelemsulonglong *tp)
3803{
3804 int status = NC_NOERR;
3805 schar *xp = (schar *)(*xpp);
3806
3807 while(nelems-- != 0)
3808 {
3809 if (*xp < 0) status = NC_ERANGE;
3810 *tp++ = *xp++;
3811 }
3812
3813 *xpp = (const void *)xp;
3814 return status;
3815}
3816
3817
3818int
3819ncx_pad_getn_schar_schar(const void **xpp, size_t nelemsschar *tp)
3820{
3821 size_t rndup = nelems % X_ALIGN;
3822
3823 if(rndup)
3824 rndup = X_ALIGN - rndup;
3825
3826 (void) memcpy(tp, *xppnelems);
3827 *xpp = (void *)((char *)(*xpp) + nelems + rndup);
3828
3829 return NC_NOERR;
3830
3831}
3832int
3833ncx_pad_getn_schar_uchar(const void **xpp, size_t nelemsuchar *tp)
3834{
3835 size_t rndup = nelems % X_ALIGN;
3836
3837 if(rndup)
3838 rndup = X_ALIGN - rndup;
3839
3840 (void) memcpy(tp, *xppnelems);
3841 *xpp = (void *)((char *)(*xpp) + nelems + rndup);
3842
3843 return NC_NOERR;
3844
3845}
3846int
3847ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
3848{
3849 int status = NC_NOERR;
3850 size_t rndup = nelems % X_ALIGN;
3851 schar *xp = (schar *) *xpp;
3852
3853 if(rndup)
3854 rndup = X_ALIGN - rndup;
3855
3856 while(nelems-- != 0)
3857 {
3858
3859 *tp++ = *xp++;
3860 }
3861
3862 *xpp = (void *)(xp + rndup);
3863 return status;
3864}
3865
3866int
3867ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
3868{
3869 int status = NC_NOERR;
3870 size_t rndup = nelems % X_ALIGN;
3871 schar *xp = (schar *) *xpp;
3872
3873 if(rndup)
3874 rndup = X_ALIGN - rndup;
3875
3876 while(nelems-- != 0)
3877 {
3878
3879 *tp++ = *xp++;
3880 }
3881
3882 *xpp = (void *)(xp + rndup);
3883 return status;
3884}
3885
3886int
3887ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
3888{
3889 int status = NC_NOERR;
3890 size_t rndup = nelems % X_ALIGN;
3891 schar *xp = (schar *) *xpp;
3892
3893 if(rndup)
3894 rndup = X_ALIGN - rndup;
3895
3896 while(nelems-- != 0)
3897 {
3898
3899 *tp++ = *xp++;
3900 }
3901
3902 *xpp = (void *)(xp + rndup);
3903 return status;
3904}
3905
3906int
3907ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
3908{
3909 int status = NC_NOERR;
3910 size_t rndup = nelems % X_ALIGN;
3911 schar *xp = (schar *) *xpp;
3912
3913 if(rndup)
3914 rndup = X_ALIGN - rndup;
3915
3916 while(nelems-- != 0)
3917 {
3918
3919 *tp++ = *xp++;
3920 }
3921
3922 *xpp = (void *)(xp + rndup);
3923 return status;
3924}
3925
3926int
3927ncx_pad_getn_schar_longlong(const void **xpp, size_t nelemslonglong *tp)
3928{
3929 int status = NC_NOERR;
3930 size_t rndup = nelems % X_ALIGN;
3931 schar *xp = (schar *) *xpp;
3932
3933 if(rndup)
3934 rndup = X_ALIGN - rndup;
3935
3936 while(nelems-- != 0)
3937 {
3938
3939 *tp++ = *xp++;
3940 }
3941
3942 *xpp = (void *)(xp + rndup);
3943 return status;
3944}
3945
3946int
3947ncx_pad_getn_schar_ushort(const void **xpp, size_t nelemsushort *tp)
3948{
3949 int status = NC_NOERR;
3950 size_t rndup = nelems % X_ALIGN;
3951 schar *xp = (schar *) *xpp;
3952
3953 if(rndup)
3954 rndup = X_ALIGN - rndup;
3955
3956 while(nelems-- != 0)
3957 {
3958 if (*xp < 0) status = NC_ERANGE;
3959 *tp++ = *xp++;
3960 }
3961
3962 *xpp = (void *)(xp + rndup);
3963 return status;
3964}
3965
3966int
3967ncx_pad_getn_schar_uint(const void **xpp, size_t nelemsuint *tp)
3968{
3969 int status = NC_NOERR;
3970 size_t rndup = nelems % X_ALIGN;
3971 schar *xp = (schar *) *xpp;
3972
3973 if(rndup)
3974 rndup = X_ALIGN - rndup;
3975
3976 while(nelems-- != 0)
3977 {
3978 if (*xp < 0) status = NC_ERANGE;
3979 *tp++ = *xp++;
3980 }
3981
3982 *xpp = (void *)(xp + rndup);
3983 return status;
3984}
3985
3986int
3987ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelemsulonglong *tp)
3988{
3989 int status = NC_NOERR;
3990 size_t rndup = nelems % X_ALIGN;
3991 schar *xp = (schar *) *xpp;
3992
3993 if(rndup)
3994 rndup = X_ALIGN - rndup;
3995
3996 while(nelems-- != 0)
3997 {
3998 if (*xp < 0) status = NC_ERANGE;
3999 *tp++ = *xp++;
4000 }
4001
4002 *xpp = (void *)(xp + rndup);
4003 return status;
4004}
4005
4006
4007int
4008ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
4009{
4010 (void) memcpy(*xpptpnelems);
4011 *xpp = (void *)((char *)(*xpp) + nelems);
4012
4013 return NC_NOERR;
4014
4015}
4016int
4017ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
4018{
4019 (void) memcpy(*xpptpnelems);
4020 *xpp = (void *)((char *)(*xpp) + nelems);
4021
4022 return NC_NOERR;
4023
4024}
4025int
4026ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp)
4027{
4028 int status = NC_NOERR;
4029 schar *xp = (schar *) *xpp;
4030
4031 while(nelems-- != 0)
4032 {
4033 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4034 status = NC_ERANGE;
4035 *xp++ = (schar) (signed)*tp++;
4036 }
4037
4038 *xpp = (void *)xp;
4039 return status;
4040}
4041
4042int
4043ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp)
4044{
4045 int status = NC_NOERR;
4046 schar *xp = (schar *) *xpp;
4047
4048 while(nelems-- != 0)
4049 {
4050 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4051 status = NC_ERANGE;
4052 *xp++ = (schar) (signed)*tp++;
4053 }
4054
4055 *xpp = (void *)xp;
4056 return status;
4057}
4058
4059int
4060ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp)
4061{
4062 int status = NC_NOERR;
4063 schar *xp = (schar *) *xpp;
4064
4065 while(nelems-- != 0)
4066 {
4067 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4068 status = NC_ERANGE;
4069 *xp++ = (schar) (signed)*tp++;
4070 }
4071
4072 *xpp = (void *)xp;
4073 return status;
4074}
4075
4076int
4077ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp)
4078{
4079 int status = NC_NOERR;
4080 schar *xp = (schar *) *xpp;
4081
4082 while(nelems-- != 0)
4083 {
4084 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4085 status = NC_ERANGE;
4086 *xp++ = (schar) (signed)*tp++;
4087 }
4088
4089 *xpp = (void *)xp;
4090 return status;
4091}
4092
4093int
4094ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp)
4095{
4096 int status = NC_NOERR;
4097 schar *xp = (schar *) *xpp;
4098
4099 while(nelems-- != 0)
4100 {
4101 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4102 status = NC_ERANGE;
4103 *xp++ = (schar) (signed)*tp++;
4104 }
4105
4106 *xpp = (void *)xp;
4107 return status;
4108}
4109
4110int
4111ncx_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp)
4112{
4113 int status = NC_NOERR;
4114 schar *xp = (schar *) *xpp;
4115
4116 while(nelems-- != 0)
4117 {
4118 if(*tp > X_SCHAR_MAX )
4119 status = NC_ERANGE;
4120 *xp++ = (schar) (signed)*tp++;
4121 }
4122
4123 *xpp = (void *)xp;
4124 return status;
4125}
4126
4127int
4128ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp)
4129{
4130 int status = NC_NOERR;
4131 schar *xp = (schar *) *xpp;
4132
4133 while(nelems-- != 0)
4134 {
4135 if(*tp > X_SCHAR_MAX )
4136 status = NC_ERANGE;
4137 *xp++ = (schar) (signed)*tp++;
4138 }
4139
4140 *xpp = (void *)xp;
4141 return status;
4142}
4143
4144int
4145ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp)
4146{
4147 int status = NC_NOERR;
4148 schar *xp = (schar *) *xpp;
4149
4150 while(nelems-- != 0)
4151 {
4152 if(*tp > X_SCHAR_MAX )
4153 status = NC_ERANGE;
4154 *xp++ = (schar) (signed)*tp++;
4155 }
4156
4157 *xpp = (void *)xp;
4158 return status;
4159}
4160
4161
4162int
4163ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
4164{
4165 size_t rndup = nelems % X_ALIGN;
4166
4167 if(rndup)
4168 rndup = X_ALIGN - rndup;
4169
4170 (void) memcpy(*xpptpnelems);
4171 *xpp = (void *)((char *)(*xpp) + nelems);
4172
4173 if(rndup)
4174 {
4175 (void) memcpy(*xppnadarndup);
4176 *xpp = (void *)((char *)(*xpp) + rndup);
4177 }
4178
4179 return NC_NOERR;
4180
4181}
4182int
4183ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
4184{
4185 size_t rndup = nelems % X_ALIGN;
4186
4187 if(rndup)
4188 rndup = X_ALIGN - rndup;
4189
4190 (void) memcpy(*xpptpnelems);
4191 *xpp = (void *)((char *)(*xpp) + nelems);
4192
4193 if(rndup)
4194 {
4195 (void) memcpy(*xppnadarndup);
4196 *xpp = (void *)((char *)(*xpp) + rndup);
4197 }
4198
4199 return NC_NOERR;
4200
4201}
4202int
4203ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp)
4204{
4205 int status = NC_NOERR;
4206 size_t rndup = nelems % X_ALIGN;
4207 schar *xp = (schar *) *xpp;
4208
4209 if(rndup)
4210 rndup = X_ALIGN - rndup;
4211
4212 while(nelems-- != 0)
4213 {
4214 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4215 status = NC_ERANGE;
4216 *xp++ = (schar) (signed) *tp++;
4217 }
4218
4219
4220 if(rndup)
4221 {
4222 (void) memcpy(xpnadarndup);
4223 xp += rndup;
4224 }
4225
4226 *xpp = (void *)xp;
4227 return status;
4228}
4229
4230int
4231ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp)
4232{
4233 int status = NC_NOERR;
4234 size_t rndup = nelems % X_ALIGN;
4235 schar *xp = (schar *) *xpp;
4236
4237 if(rndup)
4238 rndup = X_ALIGN - rndup;
4239
4240 while(nelems-- != 0)
4241 {
4242 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4243 status = NC_ERANGE;
4244 *xp++ = (schar) (signed) *tp++;
4245 }
4246
4247
4248 if(rndup)
4249 {
4250 (void) memcpy(xpnadarndup);
4251 xp += rndup;
4252 }
4253
4254 *xpp = (void *)xp;
4255 return status;
4256}
4257
4258int
4259ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp)
4260{
4261 int status = NC_NOERR;
4262 size_t rndup = nelems % X_ALIGN;
4263 schar *xp = (schar *) *xpp;
4264
4265 if(rndup)
4266 rndup = X_ALIGN - rndup;
4267
4268 while(nelems-- != 0)
4269 {
4270 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4271 status = NC_ERANGE;
4272 *xp++ = (schar) (signed) *tp++;
4273 }
4274
4275
4276 if(rndup)
4277 {
4278 (void) memcpy(xpnadarndup);
4279 xp += rndup;
4280 }
4281
4282 *xpp = (void *)xp;
4283 return status;
4284}
4285
4286int
4287ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp)
4288{
4289 int status = NC_NOERR;
4290 size_t rndup = nelems % X_ALIGN;
4291 schar *xp = (schar *) *xpp;
4292
4293 if(rndup)
4294 rndup = X_ALIGN - rndup;
4295
4296 while(nelems-- != 0)
4297 {
4298 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4299 status = NC_ERANGE;
4300 *xp++ = (schar) (signed) *tp++;
4301 }
4302
4303
4304 if(rndup)
4305 {
4306 (void) memcpy(xpnadarndup);
4307 xp += rndup;
4308 }
4309
4310 *xpp = (void *)xp;
4311 return status;
4312}
4313
4314int
4315ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp)
4316{
4317 int status = NC_NOERR;
4318 size_t rndup = nelems % X_ALIGN;
4319 schar *xp = (schar *) *xpp;
4320
4321 if(rndup)
4322 rndup = X_ALIGN - rndup;
4323
4324 while(nelems-- != 0)
4325 {
4326 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
4327 status = NC_ERANGE;
4328 *xp++ = (schar) (signed) *tp++;
4329 }
4330
4331
4332 if(rndup)
4333 {
4334 (void) memcpy(xpnadarndup);
4335 xp += rndup;
4336 }
4337
4338 *xpp = (void *)xp;
4339 return status;
4340}
4341
4342int
4343ncx_pad_putn_schar_ushort(void **xpp, size_t nelems, const ushort *tp)
4344{
4345 int status = NC_NOERR;
4346 size_t rndup = nelems % X_ALIGN;
4347 schar *xp = (schar *) *xpp;
4348
4349 if(rndup)
4350 rndup = X_ALIGN - rndup;
4351
4352 while(nelems-- != 0)
4353 {
4354 if(*tp > X_SCHAR_MAX )
4355 status = NC_ERANGE;
4356 *xp++ = (schar) (signed) *tp++;
4357 }
4358
4359
4360 if(rndup)
4361 {
4362 (void) memcpy(xpnadarndup);
4363 xp += rndup;
4364 }
4365
4366 *xpp = (void *)xp;
4367 return status;
4368}
4369
4370int
4371ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp)
4372{
4373 int status = NC_NOERR;
4374 size_t rndup = nelems % X_ALIGN;
4375 schar *xp = (schar *) *xpp;
4376
4377 if(rndup)
4378 rndup = X_ALIGN - rndup;
4379
4380 while(nelems-- != 0)
4381 {
4382 if(*tp > X_SCHAR_MAX )
4383 status = NC_ERANGE;
4384 *xp++ = (schar) (signed) *tp++;
4385 }
4386
4387
4388 if(rndup)
4389 {
4390 (void) memcpy(xpnadarndup);
4391 xp += rndup;
4392 }
4393
4394 *xpp = (void *)xp;
4395 return status;
4396}
4397
4398int
4399ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp)
4400{
4401 int status = NC_NOERR;
4402 size_t rndup = nelems % X_ALIGN;
4403 schar *xp = (schar *) *xpp;
4404
4405 if(rndup)
4406 rndup = X_ALIGN - rndup;
4407
4408 while(nelems-- != 0)
4409 {
4410 if(*tp > X_SCHAR_MAX )
4411 status = NC_ERANGE;
4412 *xp++ = (schar) (signed) *tp++;
4413 }
4414
4415
4416 if(rndup)
4417 {
4418 (void) memcpy(xpnadarndup);
4419 xp += rndup;
4420 }
4421
4422 *xpp = (void *)xp;
4423 return status;
4424}
4425
4426
4427
4428/* uchar ---------------------------------------------------------------------*/
4429int
4430ncx_getn_uchar_schar(const void **xpp, size_t nelemsschar *tp)
4431{
4432 (void) memcpy(tp, *xppnelems);
4433 *xpp = (void *)((schar *)(*xpp) + nelems);
4434 return NC_NOERR;
4435
4436}
4437int
4438ncx_getn_uchar_uchar(const void **xpp, size_t nelemsuchar *tp)
4439{
4440 (void) memcpy(tp, *xppnelems);
4441 *xpp = (void *)((schar *)(*xpp) + nelems);
4442 return NC_NOERR;
4443
4444}
4445int
4446ncx_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
4447{
4448 int status = NC_NOERR;
4449 uchar *xp = (uchar *)(*xpp);
4450
4451 while(nelems-- != 0)
4452 {
4453
4454 *tp++ = *xp++;
4455 }
4456
4457 *xpp = (const void *)xp;
4458 return status;
4459}
4460
4461int
4462ncx_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
4463{
4464 int status = NC_NOERR;
4465 uchar *xp = (uchar *)(*xpp);
4466
4467 while(nelems-- != 0)
4468 {
4469
4470 *tp++ = *xp++;
4471 }
4472
4473 *xpp = (const void *)xp;
4474 return status;
4475}
4476
4477int
4478ncx_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
4479{
4480 int status = NC_NOERR;
4481 uchar *xp = (uchar *)(*xpp);
4482
4483 while(nelems-- != 0)
4484 {
4485
4486 *tp++ = *xp++;
4487 }
4488
4489 *xpp = (const void *)xp;
4490 return status;
4491}
4492
4493int
4494ncx_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
4495{
4496 int status = NC_NOERR;
4497 uchar *xp = (uchar *)(*xpp);
4498
4499 while(nelems-- != 0)
4500 {
4501
4502 *tp++ = *xp++;
4503 }
4504
4505 *xpp = (const void *)xp;
4506 return status;
4507}
4508
4509int
4510ncx_getn_uchar_longlong(const void **xpp, size_t nelemslonglong *tp)
4511{
4512 int status = NC_NOERR;
4513 uchar *xp = (uchar *)(*xpp);
4514
4515 while(nelems-- != 0)
4516 {
4517
4518 *tp++ = *xp++;
4519 }
4520
4521 *xpp = (const void *)xp;
4522 return status;
4523}
4524
4525int
4526ncx_getn_uchar_ushort(const void **xpp, size_t nelemsushort *tp)
4527{
4528 int status = NC_NOERR;
4529 uchar *xp = (uchar *)(*xpp);
4530
4531 while(nelems-- != 0)
4532 {
4533
4534 *tp++ = *xp++;
4535 }
4536
4537 *xpp = (const void *)xp;
4538 return status;
4539}
4540
4541int
4542ncx_getn_uchar_uint(const void **xpp, size_t nelemsuint *tp)
4543{
4544 int status = NC_NOERR;
4545 uchar *xp = (uchar *)(*xpp);
4546
4547 while(nelems-- != 0)
4548 {
4549
4550 *tp++ = *xp++;
4551 }
4552
4553 *xpp = (const void *)xp;
4554 return status;
4555}
4556
4557int
4558ncx_getn_uchar_ulonglong(const void **xpp, size_t nelemsulonglong *tp)
4559{
4560 int status = NC_NOERR;
4561 uchar *xp = (uchar *)(*xpp);
4562
4563 while(nelems-- != 0)
4564 {
4565
4566 *tp++ = *xp++;
4567 }
4568
4569 *xpp = (const void *)xp;
4570 return status;
4571}
4572
4573
4574int
4575ncx_pad_getn_uchar_schar(const void **xpp, size_t nelemsschar *tp)
4576{
4577 size_t rndup = nelems % X_ALIGN;
4578
4579 if(rndup)
4580 rndup = X_ALIGN - rndup;
4581
4582 (void) memcpy(tp, *xppnelems);
4583 *xpp = (void *)((char *)(*xpp) + nelems + rndup);
4584
4585 return NC_NOERR;
4586
4587}
4588int
4589ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelemsuchar *tp)
4590{
4591 size_t rndup = nelems % X_ALIGN;
4592
4593 if(rndup)
4594 rndup = X_ALIGN - rndup;
4595
4596 (void) memcpy(tp, *xppnelems);
4597 *xpp = (void *)((char *)(*xpp) + nelems + rndup);
4598
4599 return NC_NOERR;
4600
4601}
4602int
4603ncx_pad_getn_uchar_short(const void **xpp, size_t nelems, short *tp)
4604{
4605 int status = NC_NOERR;
4606 size_t rndup = nelems % X_ALIGN;
4607 uchar *xp = (uchar *) *xpp;
4608
4609 if(rndup)
4610 rndup = X_ALIGN - rndup;
4611
4612 while(nelems-- != 0)
4613 {
4614
4615 *tp++ = *xp++;
4616 }
4617
4618 *xpp = (void *)(xp + rndup);
4619 return status;
4620}
4621
4622int
4623ncx_pad_getn_uchar_int(const void **xpp, size_t nelems, int *tp)
4624{
4625 int status = NC_NOERR;
4626 size_t rndup = nelems % X_ALIGN;
4627 uchar *xp = (uchar *) *xpp;
4628
4629 if(rndup)
4630 rndup = X_ALIGN - rndup;
4631
4632 while(nelems-- != 0)
4633 {
4634
4635 *tp++ = *xp++;
4636 }
4637
4638 *xpp = (void *)(xp + rndup);
4639 return status;
4640}
4641
4642int
4643ncx_pad_getn_uchar_float(const void **xpp, size_t nelems, float *tp)
4644{
4645 int status = NC_NOERR;
4646 size_t rndup = nelems % X_ALIGN;
4647 uchar *xp = (uchar *) *xpp;
4648
4649 if(rndup)
4650 rndup = X_ALIGN - rndup;
4651
4652 while(nelems-- != 0)
4653 {
4654
4655 *tp++ = *xp++;
4656 }
4657
4658 *xpp = (void *)(xp + rndup);
4659 return status;
4660}
4661
4662int
4663ncx_pad_getn_uchar_double(const void **xpp, size_t nelems, double *tp)
4664{
4665 int status = NC_NOERR;
4666 size_t rndup = nelems % X_ALIGN;
4667 uchar *xp = (uchar *) *xpp;
4668
4669 if(rndup)
4670 rndup = X_ALIGN - rndup;
4671
4672 while(nelems-- != 0)
4673 {
4674
4675 *tp++ = *xp++;
4676 }
4677
4678 *xpp = (void *)(xp + rndup);
4679 return status;
4680}
4681
4682int
4683ncx_pad_getn_uchar_longlong(const void **xpp, size_t nelemslonglong *tp)
4684{
4685 int status = NC_NOERR;
4686 size_t rndup = nelems % X_ALIGN;
4687 uchar *xp = (uchar *) *xpp;
4688
4689 if(rndup)
4690 rndup = X_ALIGN - rndup;
4691
4692 while(nelems-- != 0)
4693 {
4694
4695 *tp++ = *xp++;
4696 }
4697
4698 *xpp = (void *)(xp + rndup);
4699 return status;
4700}
4701
4702int
4703ncx_pad_getn_uchar_ushort(const void **xpp, size_t nelemsushort *tp)
4704{
4705 int status = NC_NOERR;
4706 size_t rndup = nelems % X_ALIGN;
4707 uchar *xp = (uchar *) *xpp;
4708
4709 if(rndup)
4710 rndup = X_ALIGN - rndup;
4711
4712 while(nelems-- != 0)
4713 {
4714
4715 *tp++ = *xp++;
4716 }
4717
4718 *xpp = (void *)(xp + rndup);
4719 return status;
4720}
4721
4722int
4723ncx_pad_getn_uchar_uint(const void **xpp, size_t nelemsuint *tp)
4724{
4725 int status = NC_NOERR;
4726 size_t rndup = nelems % X_ALIGN;
4727 uchar *xp = (uchar *) *xpp;
4728
4729 if(rndup)
4730 rndup = X_ALIGN - rndup;
4731
4732 while(nelems-- != 0)
4733 {
4734
4735 *tp++ = *xp++;
4736 }
4737
4738 *xpp = (void *)(xp + rndup);
4739 return status;
4740}
4741
4742int
4743ncx_pad_getn_uchar_ulonglong(const void **xpp, size_t nelemsulonglong *tp)
4744{
4745 int status = NC_NOERR;
4746 size_t rndup = nelems % X_ALIGN;
4747 uchar *xp = (uchar *) *xpp;
4748
4749 if(rndup)
4750 rndup = X_ALIGN - rndup;
4751
4752 while(nelems-- != 0)
4753 {
4754
4755 *tp++ = *xp++;
4756 }
4757
4758 *xpp = (void *)(xp + rndup);
4759 return status;
4760}
4761
4762
4763int
4764ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp)
4765{
4766 (void) memcpy(*xpptpnelems);
4767 *xpp = (void *)((char *)(*xpp) + nelems);
4768
4769 return NC_NOERR;
4770
4771}
4772int
4773ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp)
4774{
4775 (void) memcpy(*xpptpnelems);
4776 *xpp = (void *)((char *)(*xpp) + nelems);
4777
4778 return NC_NOERR;
4779
4780}
4781int
4782ncx_putn_uchar_short(void **xpp, size_t nelems, const short *tp)
4783{
4784 int status = NC_NOERR;
4785 uchar *xp = (uchar *) *xpp;
4786
4787 while(nelems-- != 0)
4788 {
4789 if(*tp > X_UCHAR_MAX || *tp < 0)
4790 status = NC_ERANGE;
4791 *xp++ = (uchar) (signed)*tp++;
4792 }
4793
4794 *xpp = (void *)xp;
4795 return status;
4796}
4797
4798int
4799ncx_putn_uchar_int(void **xpp, size_t nelems, const int *tp)
4800{
4801 int status = NC_NOERR;
4802 uchar *xp = (uchar *) *xpp;
4803
4804 while(nelems-- != 0)
4805 {
4806 if(*tp > X_UCHAR_MAX || *tp < 0)
4807 status = NC_ERANGE;
4808 *xp++ = (uchar) (signed)*tp++;
4809 }
4810
4811 *xpp = (void *)xp;
4812 return status;
4813}
4814
4815int
4816ncx_putn_uchar_float(void **xpp, size_t nelems, const float *tp)
4817{
4818 int status = NC_NOERR;
4819 uchar *xp = (uchar *) *xpp;
4820
4821 while(nelems-- != 0)
4822 {
4823 if(*tp > X_UCHAR_MAX || *tp < 0)
4824 status = NC_ERANGE;
4825 *xp++ = (uchar) (signed)*tp++;
4826 }
4827
4828 *xpp = (void *)xp;
4829 return status;
4830}
4831
4832int
4833ncx_putn_uchar_double(void **xpp, size_t nelems, const double *tp)
4834{
4835 int status = NC_NOERR;
4836 uchar *xp = (uchar *) *xpp;
4837
4838 while(nelems-- != 0)
4839 {
4840 if(*tp > X_UCHAR_MAX || *tp < 0)
4841 status = NC_ERANGE;
4842 *xp++ = (uchar) (signed)*tp++;
4843 }
4844
4845 *xpp = (void *)xp;
4846 return status;
4847}
4848
4849int
4850ncx_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp)
4851{
4852 int status = NC_NOERR;
4853 uchar *xp = (uchar *) *xpp;
4854
4855 while(nelems-- != 0)
4856 {
4857 if(*tp > X_UCHAR_MAX || *tp < 0)
4858 status = NC_ERANGE;
4859 *xp++ = (uchar) (signed)*tp++;
4860 }
4861
4862 *xpp = (void *)xp;
4863 return status;
4864}
4865
4866int
4867ncx_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp)
4868{
4869 int status = NC_NOERR;
4870 uchar *xp = (uchar *) *xpp;
4871
4872 while(nelems-- != 0)
4873 {
4874 if(*tp > X_UCHAR_MAX )
4875 status = NC_ERANGE;
4876 *xp++ = (uchar) (signed)*tp++;
4877 }
4878
4879 *xpp = (void *)xp;
4880 return status;
4881}
4882
4883int
4884ncx_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp)
4885{
4886 int status = NC_NOERR;
4887 uchar *xp = (uchar *) *xpp;
4888
4889 while(nelems-- != 0)
4890 {
4891 if(*tp > X_UCHAR_MAX )
4892 status = NC_ERANGE;
4893 *xp++ = (uchar) (signed)*tp++;
4894 }
4895
4896 *xpp = (void *)xp;
4897 return status;
4898}
4899
4900int
4901ncx_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp)
4902{
4903 int status = NC_NOERR;
4904 uchar *xp = (uchar *) *xpp;
4905
4906 while(nelems-- != 0)
4907 {
4908 if(*tp > X_UCHAR_MAX )
4909 status = NC_ERANGE;
4910 *xp++ = (uchar) (signed)*tp++;
4911 }
4912
4913 *xpp = (void *)xp;
4914 return status;
4915}
4916
4917
4918int
4919ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp)
4920{
4921 size_t rndup = nelems % X_ALIGN;
4922
4923 if(rndup)
4924 rndup = X_ALIGN - rndup;
4925
4926 (void) memcpy(*xpptpnelems);
4927 *xpp = (void *)((char *)(*xpp) + nelems);
4928
4929 if(rndup)
4930 {
4931 (void) memcpy(*xppnadarndup);
4932 *xpp = (void *)((char *)(*xpp) + rndup);
4933 }
4934
4935 return NC_NOERR;
4936
4937}
4938int
4939ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp)
4940{
4941 size_t rndup = nelems % X_ALIGN;
4942
4943 if(rndup)
4944 rndup = X_ALIGN - rndup;
4945
4946 (void) memcpy(*xpptpnelems);
4947 *xpp = (void *)((char *)(*xpp) + nelems);
4948
4949 if(rndup)
4950 {
4951 (void) memcpy(*xppnadarndup);
4952 *xpp = (void *)((char *)(*xpp) + rndup);
4953 }
4954
4955 return NC_NOERR;
4956
4957}
4958int
4959ncx_pad_putn_uchar_short(void **xpp, size_t nelems, const short *tp)
4960{
4961 int status = NC_NOERR;
4962 size_t rndup = nelems % X_ALIGN;
4963 uchar *xp = (uchar *) *xpp;
4964
4965 if(rndup)
4966 rndup = X_ALIGN - rndup;
4967
4968 while(nelems-- != 0)
4969 {
4970 if(*tp > X_UCHAR_MAX || *tp < 0)
4971 status = NC_ERANGE;
4972 *xp++ = (uchar) (signed) *tp++;
4973 }
4974
4975
4976 if(rndup)
4977 {
4978 (void) memcpy(xpnadarndup);
4979 xp += rndup;
4980 }
4981
4982 *xpp = (void *)xp;
4983 return status;
4984}
4985
4986int
4987ncx_pad_putn_uchar_int(void **xpp, size_t nelems, const int *tp)
4988{
4989 int status = NC_NOERR;
4990 size_t rndup = nelems % X_ALIGN;
4991 uchar *xp = (uchar *) *xpp;
4992
4993 if(rndup)
4994 rndup = X_ALIGN - rndup;
4995
4996 while(nelems-- != 0)
4997 {
4998 if(*tp > X_UCHAR_MAX || *tp < 0)
4999 status = NC_ERANGE;
5000 *xp++ = (uchar) (signed) *tp++;
5001 }
5002
5003
5004 if(rndup)
5005 {
5006 (void) memcpy(xpnadarndup);
5007 xp += rndup;
5008 }
5009
5010 *xpp = (void *)xp;
5011 return status;
5012}
5013
5014int
5015ncx_pad_putn_uchar_float(void **xpp, size_t nelems, const float *tp)
5016{
5017 int status = NC_NOERR;
5018 size_t rndup = nelems % X_ALIGN;
5019 uchar *xp = (uchar *) *xpp;
5020
5021 if(rndup)
5022 rndup = X_ALIGN - rndup;
5023
5024 while(nelems-- != 0)
5025 {
5026 if(*tp > X_UCHAR_MAX || *tp < 0)
5027 status = NC_ERANGE;
5028 *xp++ = (uchar) (signed) *tp++;
5029 }
5030
5031
5032 if(rndup)
5033 {
5034 (void) memcpy(xpnadarndup);
5035 xp += rndup;
5036 }
5037
5038 *xpp = (void *)xp;
5039 return status;
5040}
5041
5042int
5043ncx_pad_putn_uchar_double(void **xpp, size_t nelems, const double *tp)
5044{
5045 int status = NC_NOERR;
5046 size_t rndup = nelems % X_ALIGN;
5047 uchar *xp = (uchar *) *xpp;
5048
5049 if(rndup)
5050 rndup = X_ALIGN - rndup;
5051
5052 while(nelems-- != 0)
5053 {
5054 if(*tp > X_UCHAR_MAX || *tp < 0)
5055 status = NC_ERANGE;
5056 *xp++ = (uchar) (signed) *tp++;
5057 }
5058
5059
5060 if(rndup)
5061 {
5062 (void) memcpy(xpnadarndup);
5063 xp += rndup;
5064 }
5065
5066 *xpp = (void *)xp;
5067 return status;
5068}
5069
5070int
5071ncx_pad_putn_uchar_longlong(void **xpp, size_t nelems, const longlong *tp)
5072{
5073 int status = NC_NOERR;
5074 size_t rndup = nelems % X_ALIGN;
5075 uchar *xp = (uchar *) *xpp;
5076
5077 if(rndup)
5078 rndup = X_ALIGN - rndup;
5079
5080 while(nelems-- != 0)
5081 {
5082 if(*tp > X_UCHAR_MAX || *tp < 0)
5083 status = NC_ERANGE;
5084 *xp++ = (uchar) (signed) *tp++;
5085 }
5086
5087
5088 if(rndup)
5089 {
5090 (void) memcpy(xpnadarndup);
5091 xp += rndup;
5092 }
5093
5094 *xpp = (void *)xp;
5095 return status;
5096}
5097
5098int
5099ncx_pad_putn_uchar_ushort(void **xpp, size_t nelems, const ushort *tp)
5100{
5101 int status = NC_NOERR;
5102 size_t rndup = nelems % X_ALIGN;
5103 uchar *xp = (uchar *) *xpp;
5104
5105 if(rndup)
5106 rndup = X_ALIGN - rndup;
5107
5108 while(nelems-- != 0)
5109 {
5110 if(*tp > X_UCHAR_MAX )
5111 status = NC_ERANGE;
5112 *xp++ = (uchar) (signed) *tp++;
5113 }
5114
5115
5116 if(rndup)
5117 {
5118 (void) memcpy(xpnadarndup);
5119 xp += rndup;
5120 }
5121
5122 *xpp = (void *)xp;
5123 return status;
5124}
5125
5126int
5127ncx_pad_putn_uchar_uint(void **xpp, size_t nelems, const uint *tp)
5128{
5129 int status = NC_NOERR;
5130 size_t rndup = nelems % X_ALIGN;
5131 uchar *xp = (uchar *) *xpp;
5132
5133 if(rndup)
5134 rndup = X_ALIGN - rndup;
5135
5136 while(nelems-- != 0)
5137 {
5138 if(*tp > X_UCHAR_MAX )
5139 status = NC_ERANGE;
5140 *xp++ = (uchar) (signed) *tp++;
5141 }
5142
5143
5144 if(rndup)
5145 {
5146 (void) memcpy(xpnadarndup);
5147 xp += rndup;
5148 }
5149
5150 *xpp = (void *)xp;
5151 return status;
5152}
5153
5154int
5155ncx_pad_putn_uchar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp)
5156{
5157 int status = NC_NOERR;
5158 size_t rndup = nelems % X_ALIGN;
5159 uchar *xp = (uchar *) *xpp;
5160
5161 if(rndup)
5162 rndup = X_ALIGN - rndup;
5163
5164 while(nelems-- != 0)
5165 {
5166 if(*tp > X_UCHAR_MAX )
5167 status = NC_ERANGE;
5168 *xp++ = (uchar) (signed) *tp++;
5169 }
5170
5171
5172 if(rndup)
5173 {
5174 (void) memcpy(xpnadarndup);
5175 xp += rndup;
5176 }
5177
5178 *xpp = (void *)xp;
5179 return status;
5180}
5181
5182
5183/* short ---------------------------------------------------------------------*/
5184
5185#if X_SIZEOF_SHORT == SIZEOF_SHORT
5186/* optimized version */
5187int
5188ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
5189{
5190#ifdef WORDS_BIGENDIAN
5191 (void) memcpy(tp, *xppnelems * sizeof(short));
5192# else
5193 swapn2b(tp, *xppnelems);
5194# endif
5195 *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
5196 return NC_NOERR;
5197}
5198#else
5199int
5200ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
5201{
5202#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5203
5204 /* basic algorithm is:
5205  *   - ensure sane alignment of input data
5206  *   - copy (conversion happens automatically) input data
5207  *     to output
5208  *   - update xpp to point at next unconverted input, and tp to point
5209  *     at next location for converted output
5210  */
5211  long ijni;
5212  short tmp[LOOPCNT];        /* in case input is misaligned */
5213  short *xp;
5214  int nrange = 0;         /* number of range errors */
5215  int realign = 0;        /* "do we need to fix input data alignment?" */
5216  long cxp = (long) *((char**)xpp);
5217
5218  realign = (cxp & 7) % SIZEOF_SHORT;
5219  /* sjl: manually stripmine so we can limit amount of
5220   * vector work space reserved to LOOPCNT elements. Also
5221   * makes vectorisation easy */
5222  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5223    ni=Min(nelems-j,LOOPCNT);
5224    if (realign) {
5225      memcpy(tmp, *xppni*SIZEOF_SHORT);
5226      xp = tmp;
5227    } else {
5228      xp = (short *) *xpp;
5229    }
5230   /* copy the next block */
5231#pragma cdir loopcnt=LOOPCNT
5232#pragma cdir shortloop
5233    for (i=0; i<nii++) {
5234      tp[i] = (short) MaxSHORT_MINMin(SHORT_MAX, (short) xp[i]));
5235     /* test for range errors (not always needed but do it anyway) */
5236     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5237     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5238      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
5239    }
5240   /* update xpp and tp */
5241    if (realignxp = (short *) *xpp;
5242    xp += ni;
5243    tp += ni;
5244    *xpp = (void*)xp;
5245  }
5246  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5247
5248#else   /* not SX */
5249 const char *xp = (const char *) *xpp;
5250 int status = NC_NOERR;
5251
5252 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5253 {
5254 const int lstatus = ncx_get_short_short(xptp);
5255 if(lstatus != NC_NOERR)
5256 status = lstatus;
5257 }
5258
5259 *xpp = (const void *)xp;
5260 return status;
5261#  endif
5262}
5263
5264#endif
5265int
5266ncx_getn_short_schar(const void **xpp, size_t nelemsschar *tp)
5267{
5268#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5269
5270 /* basic algorithm is:
5271  *   - ensure sane alignment of input data
5272  *   - copy (conversion happens automatically) input data
5273  *     to output
5274  *   - update xpp to point at next unconverted input, and tp to point
5275  *     at next location for converted output
5276  */
5277  long ijni;
5278  short tmp[LOOPCNT];        /* in case input is misaligned */
5279  short *xp;
5280  int nrange = 0;         /* number of range errors */
5281  int realign = 0;        /* "do we need to fix input data alignment?" */
5282  long cxp = (long) *((char**)xpp);
5283
5284  realign = (cxp & 7) % SIZEOF_SHORT;
5285  /* sjl: manually stripmine so we can limit amount of
5286   * vector work space reserved to LOOPCNT elements. Also
5287   * makes vectorisation easy */
5288  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5289    ni=Min(nelems-j,LOOPCNT);
5290    if (realign) {
5291      memcpy(tmp, *xppni*SIZEOF_SHORT);
5292      xp = tmp;
5293    } else {
5294      xp = (short *) *xpp;
5295    }
5296   /* copy the next block */
5297#pragma cdir loopcnt=LOOPCNT
5298#pragma cdir shortloop
5299    for (i=0; i<nii++) {
5300      tp[i] = (scharMaxSCHAR_MINMin(SCHAR_MAX, (scharxp[i]));
5301     /* test for range errors (not always needed but do it anyway) */
5302     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5303     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5304      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
5305    }
5306   /* update xpp and tp */
5307    if (realignxp = (short *) *xpp;
5308    xp += ni;
5309    tp += ni;
5310    *xpp = (void*)xp;
5311  }
5312  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5313
5314#else   /* not SX */
5315 const char *xp = (const char *) *xpp;
5316 int status = NC_NOERR;
5317
5318 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5319 {
5320 const int lstatus = ncx_get_short_schar(xptp);
5321 if(lstatus != NC_NOERR)
5322 status = lstatus;
5323 }
5324
5325 *xpp = (const void *)xp;
5326 return status;
5327#  endif
5328}
5329
5330int
5331ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
5332{
5333#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5334
5335 /* basic algorithm is:
5336  *   - ensure sane alignment of input data
5337  *   - copy (conversion happens automatically) input data
5338  *     to output
5339  *   - update xpp to point at next unconverted input, and tp to point
5340  *     at next location for converted output
5341  */
5342  long ijni;
5343  short tmp[LOOPCNT];        /* in case input is misaligned */
5344  short *xp;
5345  int nrange = 0;         /* number of range errors */
5346  int realign = 0;        /* "do we need to fix input data alignment?" */
5347  long cxp = (long) *((char**)xpp);
5348
5349  realign = (cxp & 7) % SIZEOF_SHORT;
5350  /* sjl: manually stripmine so we can limit amount of
5351   * vector work space reserved to LOOPCNT elements. Also
5352   * makes vectorisation easy */
5353  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5354    ni=Min(nelems-j,LOOPCNT);
5355    if (realign) {
5356      memcpy(tmp, *xppni*SIZEOF_SHORT);
5357      xp = tmp;
5358    } else {
5359      xp = (short *) *xpp;
5360    }
5361   /* copy the next block */
5362#pragma cdir loopcnt=LOOPCNT
5363#pragma cdir shortloop
5364    for (i=0; i<nii++) {
5365      tp[i] = (int) MaxINT_MINMin(INT_MAX, (int) xp[i]));
5366     /* test for range errors (not always needed but do it anyway) */
5367     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5368     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5369      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
5370    }
5371   /* update xpp and tp */
5372    if (realignxp = (short *) *xpp;
5373    xp += ni;
5374    tp += ni;
5375    *xpp = (void*)xp;
5376  }
5377  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5378
5379#else   /* not SX */
5380 const char *xp = (const char *) *xpp;
5381 int status = NC_NOERR;
5382
5383 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5384 {
5385 const int lstatus = ncx_get_short_int(xptp);
5386 if(lstatus != NC_NOERR)
5387 status = lstatus;
5388 }
5389
5390 *xpp = (const void *)xp;
5391 return status;
5392#  endif
5393}
5394
5395int
5396ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
5397{
5398#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5399
5400 /* basic algorithm is:
5401  *   - ensure sane alignment of input data
5402  *   - copy (conversion happens automatically) input data
5403  *     to output
5404  *   - update xpp to point at next unconverted input, and tp to point
5405  *     at next location for converted output
5406  */
5407  long ijni;
5408  short tmp[LOOPCNT];        /* in case input is misaligned */
5409  short *xp;
5410  int nrange = 0;         /* number of range errors */
5411  int realign = 0;        /* "do we need to fix input data alignment?" */
5412  long cxp = (long) *((char**)xpp);
5413
5414  realign = (cxp & 7) % SIZEOF_SHORT;
5415  /* sjl: manually stripmine so we can limit amount of
5416   * vector work space reserved to LOOPCNT elements. Also
5417   * makes vectorisation easy */
5418  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5419    ni=Min(nelems-j,LOOPCNT);
5420    if (realign) {
5421      memcpy(tmp, *xppni*SIZEOF_SHORT);
5422      xp = tmp;
5423    } else {
5424      xp = (short *) *xpp;
5425    }
5426   /* copy the next block */
5427#pragma cdir loopcnt=LOOPCNT
5428#pragma cdir shortloop
5429    for (i=0; i<nii++) {
5430      tp[i] = (float) MaxFLOAT_MINMin(FLOAT_MAX, (float) xp[i]));
5431     /* test for range errors (not always needed but do it anyway) */
5432     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5433     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5434      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
5435    }
5436   /* update xpp and tp */
5437    if (realignxp = (short *) *xpp;
5438    xp += ni;
5439    tp += ni;
5440    *xpp = (void*)xp;
5441  }
5442  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5443
5444#else   /* not SX */
5445 const char *xp = (const char *) *xpp;
5446 int status = NC_NOERR;
5447
5448 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5449 {
5450 const int lstatus = ncx_get_short_float(xptp);
5451 if(lstatus != NC_NOERR)
5452 status = lstatus;
5453 }
5454
5455 *xpp = (const void *)xp;
5456 return status;
5457#  endif
5458}
5459
5460int
5461ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
5462{
5463#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5464
5465 /* basic algorithm is:
5466  *   - ensure sane alignment of input data
5467  *   - copy (conversion happens automatically) input data
5468  *     to output
5469  *   - update xpp to point at next unconverted input, and tp to point
5470  *     at next location for converted output
5471  */
5472  long ijni;
5473  short tmp[LOOPCNT];        /* in case input is misaligned */
5474  short *xp;
5475  int nrange = 0;         /* number of range errors */
5476  int realign = 0;        /* "do we need to fix input data alignment?" */
5477  long cxp = (long) *((char**)xpp);
5478
5479  realign = (cxp & 7) % SIZEOF_SHORT;
5480  /* sjl: manually stripmine so we can limit amount of
5481   * vector work space reserved to LOOPCNT elements. Also
5482   * makes vectorisation easy */
5483  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5484    ni=Min(nelems-j,LOOPCNT);
5485    if (realign) {
5486      memcpy(tmp, *xppni*SIZEOF_SHORT);
5487      xp = tmp;
5488    } else {
5489      xp = (short *) *xpp;
5490    }
5491   /* copy the next block */
5492#pragma cdir loopcnt=LOOPCNT
5493#pragma cdir shortloop
5494    for (i=0; i<nii++) {
5495      tp[i] = (double) MaxDOUBLE_MINMin(DOUBLE_MAX, (double) xp[i]));
5496     /* test for range errors (not always needed but do it anyway) */
5497     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5498     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5499      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
5500    }
5501   /* update xpp and tp */
5502    if (realignxp = (short *) *xpp;
5503    xp += ni;
5504    tp += ni;
5505    *xpp = (void*)xp;
5506  }
5507  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5508
5509#else   /* not SX */
5510 const char *xp = (const char *) *xpp;
5511 int status = NC_NOERR;
5512
5513 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5514 {
5515 const int lstatus = ncx_get_short_double(xptp);
5516 if(lstatus != NC_NOERR)
5517 status = lstatus;
5518 }
5519
5520 *xpp = (const void *)xp;
5521 return status;
5522#  endif
5523}
5524
5525int
5526ncx_getn_short_longlong(const void **xpp, size_t nelemslonglong *tp)
5527{
5528#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5529
5530 /* basic algorithm is:
5531  *   - ensure sane alignment of input data
5532  *   - copy (conversion happens automatically) input data
5533  *     to output
5534  *   - update xpp to point at next unconverted input, and tp to point
5535  *     at next location for converted output
5536  */
5537  long ijni;
5538  short tmp[LOOPCNT];        /* in case input is misaligned */
5539  short *xp;
5540  int nrange = 0;         /* number of range errors */
5541  int realign = 0;        /* "do we need to fix input data alignment?" */
5542  long cxp = (long) *((char**)xpp);
5543
5544  realign = (cxp & 7) % SIZEOF_SHORT;
5545  /* sjl: manually stripmine so we can limit amount of
5546   * vector work space reserved to LOOPCNT elements. Also
5547   * makes vectorisation easy */
5548  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5549    ni=Min(nelems-j,LOOPCNT);
5550    if (realign) {
5551      memcpy(tmp, *xppni*SIZEOF_SHORT);
5552      xp = tmp;
5553    } else {
5554      xp = (short *) *xpp;
5555    }
5556   /* copy the next block */
5557#pragma cdir loopcnt=LOOPCNT
5558#pragma cdir shortloop
5559    for (i=0; i<nii++) {
5560      tp[i] = (longlongMaxLONGLONG_MINMin(LONGLONG_MAX, (longlongxp[i]));
5561     /* test for range errors (not always needed but do it anyway) */
5562     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5563     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5564      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
5565    }
5566   /* update xpp and tp */
5567    if (realignxp = (short *) *xpp;
5568    xp += ni;
5569    tp += ni;
5570    *xpp = (void*)xp;
5571  }
5572  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5573
5574#else   /* not SX */
5575 const char *xp = (const char *) *xpp;
5576 int status = NC_NOERR;
5577
5578 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5579 {
5580 const int lstatus = ncx_get_short_longlong(xptp);
5581 if(lstatus != NC_NOERR)
5582 status = lstatus;
5583 }
5584
5585 *xpp = (const void *)xp;
5586 return status;
5587#  endif
5588}
5589
5590int
5591ncx_getn_short_uchar(const void **xpp, size_t nelemsuchar *tp)
5592{
5593#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5594
5595 /* basic algorithm is:
5596  *   - ensure sane alignment of input data
5597  *   - copy (conversion happens automatically) input data
5598  *     to output
5599  *   - update xpp to point at next unconverted input, and tp to point
5600  *     at next location for converted output
5601  */
5602  long ijni;
5603  short tmp[LOOPCNT];        /* in case input is misaligned */
5604  short *xp;
5605  int nrange = 0;         /* number of range errors */
5606  int realign = 0;        /* "do we need to fix input data alignment?" */
5607  long cxp = (long) *((char**)xpp);
5608
5609  realign = (cxp & 7) % SIZEOF_SHORT;
5610  /* sjl: manually stripmine so we can limit amount of
5611   * vector work space reserved to LOOPCNT elements. Also
5612   * makes vectorisation easy */
5613  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5614    ni=Min(nelems-j,LOOPCNT);
5615    if (realign) {
5616      memcpy(tmp, *xppni*SIZEOF_SHORT);
5617      xp = tmp;
5618    } else {
5619      xp = (short *) *xpp;
5620    }
5621   /* copy the next block */
5622#pragma cdir loopcnt=LOOPCNT
5623#pragma cdir shortloop
5624    for (i=0; i<nii++) {
5625      tp[i] = (ucharMaxUCHAR_MINMin(UCHAR_MAX, (ucharxp[i]));
5626     /* test for range errors (not always needed but do it anyway) */
5627     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5628     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5629      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
5630    }
5631   /* update xpp and tp */
5632    if (realignxp = (short *) *xpp;
5633    xp += ni;
5634    tp += ni;
5635    *xpp = (void*)xp;
5636  }
5637  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5638
5639#else   /* not SX */
5640 const char *xp = (const char *) *xpp;
5641 int status = NC_NOERR;
5642
5643 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5644 {
5645 const int lstatus = ncx_get_short_uchar(xptp);
5646 if(lstatus != NC_NOERR)
5647 status = lstatus;
5648 }
5649
5650 *xpp = (const void *)xp;
5651 return status;
5652#  endif
5653}
5654
5655int
5656ncx_getn_short_ushort(const void **xpp, size_t nelemsushort *tp)
5657{
5658#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5659
5660 /* basic algorithm is:
5661  *   - ensure sane alignment of input data
5662  *   - copy (conversion happens automatically) input data
5663  *     to output
5664  *   - update xpp to point at next unconverted input, and tp to point
5665  *     at next location for converted output
5666  */
5667  long ijni;
5668  short tmp[LOOPCNT];        /* in case input is misaligned */
5669  short *xp;
5670  int nrange = 0;         /* number of range errors */
5671  int realign = 0;        /* "do we need to fix input data alignment?" */
5672  long cxp = (long) *((char**)xpp);
5673
5674  realign = (cxp & 7) % SIZEOF_SHORT;
5675  /* sjl: manually stripmine so we can limit amount of
5676   * vector work space reserved to LOOPCNT elements. Also
5677   * makes vectorisation easy */
5678  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5679    ni=Min(nelems-j,LOOPCNT);
5680    if (realign) {
5681      memcpy(tmp, *xppni*SIZEOF_SHORT);
5682      xp = tmp;
5683    } else {
5684      xp = (short *) *xpp;
5685    }
5686   /* copy the next block */
5687#pragma cdir loopcnt=LOOPCNT
5688#pragma cdir shortloop
5689    for (i=0; i<nii++) {
5690      tp[i] = (ushortMaxUSHORT_MINMin(USHORT_MAX, (ushortxp[i]));
5691     /* test for range errors (not always needed but do it anyway) */
5692     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5693     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5694      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
5695    }
5696   /* update xpp and tp */
5697    if (realignxp = (short *) *xpp;
5698    xp += ni;
5699    tp += ni;
5700    *xpp = (void*)xp;
5701  }
5702  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5703
5704#else   /* not SX */
5705 const char *xp = (const char *) *xpp;
5706 int status = NC_NOERR;
5707
5708 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5709 {
5710 const int lstatus = ncx_get_short_ushort(xptp);
5711 if(lstatus != NC_NOERR)
5712 status = lstatus;
5713 }
5714
5715 *xpp = (const void *)xp;
5716 return status;
5717#  endif
5718}
5719
5720int
5721ncx_getn_short_uint(const void **xpp, size_t nelemsuint *tp)
5722{
5723#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5724
5725 /* basic algorithm is:
5726  *   - ensure sane alignment of input data
5727  *   - copy (conversion happens automatically) input data
5728  *     to output
5729  *   - update xpp to point at next unconverted input, and tp to point
5730  *     at next location for converted output
5731  */
5732  long ijni;
5733  short tmp[LOOPCNT];        /* in case input is misaligned */
5734  short *xp;
5735  int nrange = 0;         /* number of range errors */
5736  int realign = 0;        /* "do we need to fix input data alignment?" */
5737  long cxp = (long) *((char**)xpp);
5738
5739  realign = (cxp & 7) % SIZEOF_SHORT;
5740  /* sjl: manually stripmine so we can limit amount of
5741   * vector work space reserved to LOOPCNT elements. Also
5742   * makes vectorisation easy */
5743  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5744    ni=Min(nelems-j,LOOPCNT);
5745    if (realign) {
5746      memcpy(tmp, *xppni*SIZEOF_SHORT);
5747      xp = tmp;
5748    } else {
5749      xp = (short *) *xpp;
5750    }
5751   /* copy the next block */
5752#pragma cdir loopcnt=LOOPCNT
5753#pragma cdir shortloop
5754    for (i=0; i<nii++) {
5755      tp[i] = (uintMaxUINT_MINMin(UINT_MAX, (uintxp[i]));
5756     /* test for range errors (not always needed but do it anyway) */
5757     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5758     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5759      nrange += xp[i] > UINT_MAX || xp[i] < 0;
5760    }
5761   /* update xpp and tp */
5762    if (realignxp = (short *) *xpp;
5763    xp += ni;
5764    tp += ni;
5765    *xpp = (void*)xp;
5766  }
5767  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5768
5769#else   /* not SX */
5770 const char *xp = (const char *) *xpp;
5771 int status = NC_NOERR;
5772
5773 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5774 {
5775 const int lstatus = ncx_get_short_uint(xptp);
5776 if(lstatus != NC_NOERR)
5777 status = lstatus;
5778 }
5779
5780 *xpp = (const void *)xp;
5781 return status;
5782#  endif
5783}
5784
5785int
5786ncx_getn_short_ulonglong(const void **xpp, size_t nelemsulonglong *tp)
5787{
5788#if _SX && X_SIZEOF_SHORT == SIZEOF_SHORT
5789
5790 /* basic algorithm is:
5791  *   - ensure sane alignment of input data
5792  *   - copy (conversion happens automatically) input data
5793  *     to output
5794  *   - update xpp to point at next unconverted input, and tp to point
5795  *     at next location for converted output
5796  */
5797  long ijni;
5798  short tmp[LOOPCNT];        /* in case input is misaligned */
5799  short *xp;
5800  int nrange = 0;         /* number of range errors */
5801  int realign = 0;        /* "do we need to fix input data alignment?" */
5802  long cxp = (long) *((char**)xpp);
5803
5804  realign = (cxp & 7) % SIZEOF_SHORT;
5805  /* sjl: manually stripmine so we can limit amount of
5806   * vector work space reserved to LOOPCNT elements. Also
5807   * makes vectorisation easy */
5808  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
5809    ni=Min(nelems-j,LOOPCNT);
5810    if (realign) {
5811      memcpy(tmp, *xppni*SIZEOF_SHORT);
5812      xp = tmp;
5813    } else {
5814      xp = (short *) *xpp;
5815    }
5816   /* copy the next block */
5817#pragma cdir loopcnt=LOOPCNT
5818#pragma cdir shortloop
5819    for (i=0; i<nii++) {
5820      tp[i] = (ulonglongMaxULONGLONG_MINMin(ULONGLONG_MAX, (ulonglongxp[i]));
5821     /* test for range errors (not always needed but do it anyway) */
5822     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
5823     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
5824      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
5825    }
5826   /* update xpp and tp */
5827    if (realignxp = (short *) *xpp;
5828    xp += ni;
5829    tp += ni;
5830    *xpp = (void*)xp;
5831  }
5832  return nrange == 0 ? NC_NOERR : NC_ERANGE;
5833
5834#else   /* not SX */
5835 const char *xp = (const char *) *xpp;
5836 int status = NC_NOERR;
5837
5838 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5839 {
5840 const int lstatus = ncx_get_short_ulonglong(xptp);
5841 if(lstatus != NC_NOERR)
5842 status = lstatus;
5843 }
5844
5845 *xpp = (const void *)xp;
5846 return status;
5847#  endif
5848}
5849
5850
5851int
5852ncx_pad_getn_short_schar(const void **xpp, size_t nelemsschar *tp)
5853{
5854 const size_t rndup = nelems % 2;
5855
5856 const char *xp = (const char *) *xpp;
5857 int status = NC_NOERR;
5858
5859 for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORTtp++)
5860 {
5861 const int lstatus = ncx_get_short_schar(xptp);
5862 if(lstatus != NC_NOERR)
5863 status = lstatus;
5864 }
5865
5866 if(rndup != 0)
5867 xp += X_SIZEOF_SHORT;