Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

ncx.c

Go to the documentation of this file.
00001 /* Do not edit this file. It is produced from the corresponding .m4 source */
00002 /*
00003  *      Copyright 1996, University Corporation for Atmospheric Research
00004  *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
00005  *      
00006  *      This file contains some routines derived from code
00007  *      which is copyrighted by Sun Microsystems, Inc.
00008  *      The "#ifdef vax" versions of
00009  *               ncx_put_float_float()
00010  *               ncx_get_float_float()
00011  *               ncx_put_double_double()
00012  *               ncx_get_double_double()
00013  *               ncx_putn_float_float()
00014  *               ncx_getn_float_float()
00015  *               ncx_putn_double_double()
00016  *               ncx_getn_double_double()
00017  *      are derived from xdr_float() and xdr_double() routines
00018  *      in the freely available, copyrighted Sun RPCSRC 3.9
00019  *      distribution, xdr_float.c.
00020  *      Our "value added" is that these are always memory to memory,
00021  *      they handle IEEE subnormals properly, and their "n" versions
00022  *      operate speedily on arrays.
00023  */
00024 
00025 /*
00026  * An external data representation interface.
00027  */
00028 
00029 #include "ncx.h"
00030 #include <string.h>
00031 #include <limits.h>
00032 /* alias poorly named limits.h macros */
00033 #define  SHORT_MAX  SHRT_MAX
00034 #define  SHORT_MIN  SHRT_MIN
00035 #define USHORT_MAX USHRT_MAX
00036 #include <float.h>
00037 #ifndef FLT_MAX /* This POSIX macro missing on some systems */
00038 # ifndef NO_IEEE_FLOAT
00039 # define FLT_MAX 3.40282347e+38f
00040 # else
00041 # error "You will need to define FLT_MAX"
00042 # endif
00043 #endif
00044 #include <assert.h>
00045 
00046 #undef  SIZEOF_FLOAT
00047 #define SIZEOF_FLOAT  4
00048 #undef  SIZEOF_DOUBLE
00049 #define SIZEOF_DOUBLE 8
00050 
00051 /*
00052  * If the machine's float domain is "smaller" than the external one
00053  * use the machine domain
00054  */
00055 #if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */
00056 #undef X_FLOAT_MAX
00057 # define X_FLOAT_MAX FLT_MAX
00058 #undef X_FLOAT_MIN
00059 # define X_FLOAT_MIN (-X_FLOAT_MAX)
00060 #endif
00061 
00062 #if _SX /* NEC SUPER UX */
00063 #if _INT64
00064 #undef  INT_MAX /* workaround cpp bug */
00065 #define INT_MAX  X_INT_MAX
00066 #undef  INT_MIN /* workaround cpp bug */
00067 #define INT_MIN  X_INT_MIN
00068 #undef  LONG_MAX /* workaround cpp bug */
00069 #define LONG_MAX  X_INT_MAX
00070 #undef  LONG_MIN /* workaround cpp bug */
00071 #define LONG_MIN  X_INT_MIN
00072 #elif _LONG64
00073 #undef  LONG_MAX /* workaround cpp bug */
00074 #define LONG_MAX  4294967295L
00075 #undef  LONG_MIN /* workaround cpp bug */
00076 #define LONG_MIN -4294967295L
00077 #endif
00078 #endif /* _SX */
00079 
00080 static const char nada[X_ALIGN] = {0, 0, 0, 0};
00081 
00082 #ifndef WORDS_BIGENDIAN
00083 /* LITTLE_ENDIAN: DEC and intel */
00084 /*
00085  * Routines to convert to BIGENDIAN.
00086  * Optimize the swapn?b() and swap?b() routines aggressivly.
00087  */
00088 
00089 #define SWAP2(a) ( (((a) & 0xff) << 8) | \
00090                 (((a) >> 8) & 0xff) )
00091 
00092 #define SWAP4(a) ( ((a) << 24) | \
00093                 (((a) <<  8) & 0x00ff0000) | \
00094                 (((a) >>  8) & 0x0000ff00) | \
00095                 (((a) >> 24) & 0x000000ff) )
00096 
00097 static void
00098 swapn2b(void *dst, const void *src, size_t nn)
00099 {
00100         char *op = dst;
00101         const char *ip = src;
00102         while(nn-- != 0)
00103         {
00104                 *op++ = *(++ip);
00105                 *op++ = *(ip++ -1);
00106         }
00107 }
00108 
00109 # ifndef vax
00110 static void
00111 swap4b(void *dst, const void *src)
00112 {
00113         char *op = dst;
00114         const char *ip = src;
00115         op[0] = ip[3];
00116         op[1] = ip[2];
00117         op[2] = ip[1];
00118         op[3] = ip[0];
00119 }
00120 # endif /* !vax */
00121 
00122 static void
00123 swapn4b(void *dst, const void *src, size_t nn)
00124 {
00125         char *op = dst;
00126         const char *ip = src;
00127         while(nn-- != 0)
00128         {
00129                 op[0] = ip[3];
00130                 op[1] = ip[2];
00131                 op[2] = ip[1];
00132                 op[3] = ip[0];
00133                 op += 4;
00134                 ip += 4;
00135         }
00136 }
00137 
00138 # ifndef vax
00139 static void
00140 swap8b(void *dst, const void *src)
00141 {
00142         char *op = dst;
00143         const char *ip = src;
00144         op[0] = ip[7];
00145         op[1] = ip[6];
00146         op[2] = ip[5];
00147         op[3] = ip[4];
00148         op[4] = ip[3];
00149         op[5] = ip[2];
00150         op[6] = ip[1];
00151         op[7] = ip[0];
00152 }
00153 # endif /* !vax */
00154 
00155 # ifndef vax
00156 static void
00157 swapn8b(void *dst, const void *src, size_t nn)
00158 {
00159         char *op = dst;
00160         const char *ip = src;
00161         while(nn-- != 0)
00162         {
00163                 op[0] = ip[7];
00164                 op[1] = ip[6];
00165                 op[2] = ip[5];
00166                 op[3] = ip[4];
00167                 op[4] = ip[3];
00168                 op[5] = ip[2];
00169                 op[6] = ip[1];
00170                 op[7] = ip[0];
00171                 op += 8;
00172                 ip += 8;
00173         }
00174 }
00175 # endif /* !vax */
00176 
00177 #endif /* LITTLE_ENDIAN */
00178 
00179 
00180 /*
00181  * Primitive numeric conversion functions.
00182  */
00183 
00184 /* x_schar */
00185 
00186  /* We don't implement and x_schar primitives. */
00187 
00188 
00189 /* x_short */
00190 
00191 #if SHORT_MAX == X_SHORT_MAX
00192 typedef short ix_short;
00193 #define SIZEOF_IX_SHORT SIZEOF_SHORT
00194 #define IX_SHORT_MAX SHORT_MAX
00195 #elif INT_MAX >= X_SHORT_MAX
00196 typedef int ix_short;
00197 #define SIZEOF_IX_SHORT SIZEOF_INT
00198 #define IX_SHORT_MAX INT_MAX
00199 #elif LONG_MAX >= X_SHORT_MAX
00200 typedef long ix_short;
00201 #define SIZEOF_IX_SHORT SIZEOF_LONG
00202 #define IX_SHORT_MAX LONG_MAX
00203 #else
00204 #error "ix_short implementation"
00205 #endif
00206 
00207 static void
00208 get_ix_short(const void *xp, ix_short *ip)
00209 {
00210         const uchar *cp = (const uchar *) xp;
00211         *ip = *cp++ << 8;
00212 #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
00213         if(*ip & 0x8000)
00214         {
00215                 /* extern is negative */
00216                 *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
00217         }
00218 #endif
00219         *ip |= *cp; 
00220 }
00221 
00222 static void
00223 put_ix_short(void *xp, const ix_short *ip)
00224 {
00225         uchar *cp = (uchar *) xp;
00226         *cp++ = (*ip) >> 8;
00227         *cp = (*ip) & 0xff;
00228 }
00229 
00230 
00231 int
00232 ncx_get_short_schar(const void *xp, schar *ip)
00233 {
00234         ix_short xx;
00235         get_ix_short(xp, &xx);
00236         *ip = xx;
00237         if(xx > SCHAR_MAX || xx < SCHAR_MIN)
00238                 return NC_ERANGE;
00239         return ENOERR;
00240 }
00241 
00242 int
00243 ncx_get_short_uchar(const void *xp, uchar *ip)
00244 {
00245         ix_short xx;
00246         get_ix_short(xp, &xx);
00247         *ip = xx;
00248         if(xx > UCHAR_MAX || xx < 0)
00249                 return NC_ERANGE;
00250         return ENOERR;
00251 }
00252 
00253 int
00254 ncx_get_short_short(const void *xp, short *ip)
00255 {
00256 #if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
00257         get_ix_short(xp, (ix_short *)ip);
00258         return ENOERR;
00259 #else
00260         ix_short xx;
00261         get_ix_short(xp, &xx);
00262         *ip = xx;
00263 #   if IX_SHORT_MAX > SHORT_MAX
00264         if(xx > SHORT_MAX || xx < SHORT_MIN)
00265                 return NC_ERANGE;
00266 #   endif
00267         return ENOERR;
00268 #endif
00269 }
00270 
00271 int
00272 ncx_get_short_int(const void *xp, int *ip)
00273 {
00274 #if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
00275         get_ix_short(xp, (ix_short *)ip);
00276         return ENOERR;
00277 #else
00278         ix_short xx;
00279         get_ix_short(xp, &xx);
00280         *ip = xx;
00281 #   if IX_SHORT_MAX > INT_MAX
00282         if(xx > INT_MAX || xx < INT_MIN)
00283                 return NC_ERANGE;
00284 #   endif
00285         return ENOERR;
00286 #endif
00287 }
00288 
00289 int
00290 ncx_get_short_long(const void *xp, long *ip)
00291 {
00292 #if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
00293         get_ix_short(xp, (ix_short *)ip);
00294         return ENOERR;
00295 #else
00296         /* assert(LONG_MAX >= X_SHORT_MAX); */
00297         ix_short xx;
00298         get_ix_short(xp, &xx);
00299         *ip = xx;
00300         return ENOERR;
00301 #endif
00302 }
00303 
00304 int
00305 ncx_get_short_float(const void *xp, float *ip)
00306 {
00307         ix_short xx;
00308         get_ix_short(xp, &xx);
00309         *ip = xx;
00310 #if 0   /* TODO: determine when necessary */
00311         if(xx > FLT_MAX || xx < (-FLT_MAX))
00312                 return NC_ERANGE;
00313 #endif
00314         return ENOERR;
00315 }
00316 
00317 int
00318 ncx_get_short_double(const void *xp, double *ip)
00319 {
00320         /* assert(DBL_MAX >= X_SHORT_MAX); */
00321         ix_short xx;
00322         get_ix_short(xp, &xx);
00323         *ip = xx;
00324         return ENOERR;
00325 }
00326 
00327 int
00328 ncx_put_short_schar(void *xp, const schar *ip)
00329 {
00330         uchar *cp = (uchar *) xp;
00331         if(*ip & 0x80)
00332                 *cp++ = 0xff;
00333         else
00334                 *cp++ = 0;
00335         *cp = (uchar)*ip;
00336         return ENOERR;
00337 }
00338 
00339 int
00340 ncx_put_short_uchar(void *xp, const uchar *ip)
00341 {
00342         uchar *cp = (uchar *) xp;
00343         *cp++ = 0;
00344         *cp = *ip;
00345         return ENOERR;
00346 }
00347 
00348 int
00349 ncx_put_short_short(void *xp, const short *ip)
00350 {
00351 #if SIZEOF_IX_SHORT == SIZEOF_SHORT && X_SHORT_MAX == SHORT_MAX
00352         put_ix_short(xp, (const ix_short *)ip);
00353         return ENOERR;
00354 #else
00355         ix_short xx = (ix_short)*ip;
00356         put_ix_short(xp, &xx);
00357 # if X_SHORT_MAX < SHORT_MAX
00358         if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
00359                 return NC_ERANGE;
00360 # endif
00361         return ENOERR;
00362 #endif
00363 }
00364 
00365 int
00366 ncx_put_short_int(void *xp, const int *ip)
00367 {
00368 #if SIZEOF_IX_SHORT == SIZEOF_INT && X_SHORT_MAX == INT_MAX
00369         put_ix_short(xp, (const ix_short *)ip);
00370         return ENOERR;
00371 #else
00372         ix_short xx = (ix_short)*ip;
00373         put_ix_short(xp, &xx);
00374 # if X_SHORT_MAX < INT_MAX
00375         if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
00376                 return NC_ERANGE;
00377 # endif
00378         return ENOERR;
00379 #endif
00380 }
00381 
00382 int
00383 ncx_put_short_long(void *xp, const long *ip)
00384 {
00385 #if SIZEOF_IX_SHORT == SIZEOF_LONG && X_SHORT_MAX == LONG_MAX
00386         put_ix_short(xp, (const ix_short *)ip);
00387         return ENOERR;
00388 #else
00389         ix_short xx = (ix_short)*ip;
00390         put_ix_short(xp, &xx);
00391 # if X_SHORT_MAX < LONG_MAX
00392         if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
00393                 return NC_ERANGE;
00394 # endif
00395         return ENOERR;
00396 #endif
00397 }
00398 
00399 int
00400 ncx_put_short_float(void *xp, const float *ip)
00401 {
00402         ix_short xx = *ip;
00403         put_ix_short(xp, &xx);
00404         if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
00405                 return NC_ERANGE;
00406         return ENOERR;
00407 }
00408 
00409 int
00410 ncx_put_short_double(void *xp, const double *ip)
00411 {
00412         ix_short xx = *ip;
00413         put_ix_short(xp, &xx);
00414         if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
00415                 return NC_ERANGE;
00416         return ENOERR;
00417 }
00418 
00419 /* x_int */
00420 
00421 #if SHORT_MAX == X_INT_MAX
00422 typedef short ix_int;
00423 #define SIZEOF_IX_INT SIZEOF_SHORT
00424 #define IX_INT_MAX SHORT_MAX
00425 #elif INT_MAX  >= X_INT_MAX
00426 typedef int ix_int;
00427 #define SIZEOF_IX_INT SIZEOF_INT
00428 #define IX_INT_MAX INT_MAX
00429 #elif LONG_MAX  >= X_INT_MAX
00430 typedef long ix_int;
00431 #define SIZEOF_IX_INT SIZEOF_LONG
00432 #define IX_INT_MAX LONG_MAX
00433 #else
00434 #error "ix_int implementation"
00435 #endif
00436 
00437 
00438 static void
00439 get_ix_int(const void *xp, ix_int *ip)
00440 {
00441         const uchar *cp = (const uchar *) xp;
00442 
00443         *ip = *cp++ << 24;
00444 #if SIZEOF_IX_INT > X_SIZEOF_INT
00445         if(*ip & 0x80000000)
00446         {
00447                 /* extern is negative */
00448                 *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
00449         }
00450 #endif
00451         *ip |= (*cp++ << 16);
00452         *ip |= (*cp++ << 8);
00453         *ip |= *cp; 
00454 }
00455 
00456 static void
00457 put_ix_int(void *xp, const ix_int *ip)
00458 {
00459         uchar *cp = (uchar *) xp;
00460 
00461         *cp++ = (*ip) >> 24;
00462         *cp++ = ((*ip) & 0x00ff0000) >> 16;
00463         *cp++ = ((*ip) & 0x0000ff00) >>  8;
00464         *cp   = ((*ip) & 0x000000ff);
00465 }
00466 
00467 
00468 int
00469 ncx_get_int_schar(const void *xp, schar *ip)
00470 {
00471         ix_int xx;
00472         get_ix_int(xp, &xx);
00473         *ip = xx;
00474         if(xx > SCHAR_MAX || xx < SCHAR_MIN)
00475                 return NC_ERANGE;
00476         return ENOERR;
00477 }
00478 
00479 int
00480 ncx_get_int_uchar(const void *xp, uchar *ip)
00481 {
00482         ix_int xx;
00483         get_ix_int(xp, &xx);
00484         *ip = xx;
00485         if(xx > UCHAR_MAX || xx < 0)
00486                 return NC_ERANGE;
00487         return ENOERR;
00488 }
00489 
00490 int
00491 ncx_get_int_short(const void *xp, short *ip)
00492 {
00493 #if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
00494         get_ix_int(xp, (ix_int *)ip);
00495         return ENOERR;
00496 #else
00497         ix_int xx;
00498         get_ix_int(xp, &xx);
00499         *ip = xx;
00500 #  if IX_INT_MAX > SHORT_MAX
00501         if(xx > SHORT_MAX || xx < SHORT_MIN)
00502                 return NC_ERANGE;
00503 #  endif
00504         return ENOERR;
00505 #endif
00506 }
00507 
00508 int
00509 ncx_get_int_int(const void *xp, int *ip)
00510 {
00511 #if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
00512         get_ix_int(xp, (ix_int *)ip);
00513         return ENOERR;
00514 #else
00515         ix_int xx;
00516         get_ix_int(xp, &xx);
00517         *ip = xx;
00518 #  if IX_INT_MAX > INT_MAX
00519         if(xx > INT_MAX || xx < INT_MIN)
00520                 return NC_ERANGE;
00521 #  endif
00522         return ENOERR;
00523 #endif
00524 }
00525 
00526 int
00527 ncx_get_int_long(const void *xp, long *ip)
00528 {
00529 #if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
00530         get_ix_int(xp, (ix_int *)ip);
00531         return ENOERR;
00532 #else
00533         ix_int xx;
00534         get_ix_int(xp, &xx);
00535         *ip = xx;
00536 #  if IX_INT_MAX > LONG_MAX     /* unlikely */
00537         if(xx > LONG_MAX || xx < LONG_MIN)
00538                 return NC_ERANGE;
00539 #  endif
00540         return ENOERR;
00541 #endif
00542 }
00543 
00544 int
00545 ncx_get_int_float(const void *xp, float *ip)
00546 {
00547         ix_int xx;
00548         get_ix_int(xp, &xx);
00549         *ip = xx;
00550 #if 0   /* TODO: determine when necessary */
00551         if(xx > FLT_MAX || xx < (-FLT_MAX))
00552                 return NC_ERANGE;
00553 #endif
00554         return ENOERR;
00555 }
00556 
00557 int
00558 ncx_get_int_double(const void *xp, double *ip)
00559 {
00560         /* assert((DBL_MAX >= X_INT_MAX); */
00561         ix_int xx;
00562         get_ix_int(xp, &xx);
00563         *ip = xx;
00564         return ENOERR;
00565 }
00566 
00567 int
00568 ncx_put_int_schar(void *xp, const schar *ip)
00569 {
00570         uchar *cp = (uchar *) xp;
00571         if(*ip & 0x80)
00572         {
00573                 *cp++ = 0xff;
00574                 *cp++ = 0xff;
00575                 *cp++ = 0xff;
00576         }
00577         else
00578         {
00579                 *cp++ = 0x00;
00580                 *cp++ = 0x00;
00581                 *cp++ = 0x00;
00582         }
00583         *cp = (uchar)*ip;
00584         return ENOERR;
00585 }
00586 
00587 int
00588 ncx_put_int_uchar(void *xp, const uchar *ip)
00589 {
00590         uchar *cp = (uchar *) xp;
00591         *cp++ = 0x00;
00592         *cp++ = 0x00;
00593         *cp++ = 0x00;
00594         *cp   = *ip;
00595         return ENOERR;
00596 }
00597 
00598 int
00599 ncx_put_int_short(void *xp, const short *ip)
00600 {
00601 #if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
00602         put_ix_int(xp, (ix_int *)ip);
00603         return ENOERR;
00604 #else
00605         ix_int xx = (ix_int)(*ip);
00606         put_ix_int(xp, &xx);
00607 #   if IX_INT_MAX < SHORT_MAX
00608         if(*ip > X_INT_MAX || *ip < X_INT_MIN)
00609                 return NC_ERANGE;
00610 #   endif
00611         return ENOERR;
00612 #endif
00613 }
00614 
00615 int
00616 ncx_put_int_int(void *xp, const int *ip)
00617 {
00618 #if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
00619         put_ix_int(xp, (ix_int *)ip);
00620         return ENOERR;
00621 #else
00622         ix_int xx = (ix_int)(*ip);
00623         put_ix_int(xp, &xx);
00624 #   if IX_INT_MAX < INT_MAX
00625         if(*ip > X_INT_MAX || *ip < X_INT_MIN)
00626                 return NC_ERANGE;
00627 #   endif
00628         return ENOERR;
00629 #endif
00630 }
00631 
00632 int
00633 ncx_put_int_long(void *xp, const long *ip)
00634 {
00635 #if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
00636         put_ix_int(xp, (ix_int *)ip);
00637         return ENOERR;
00638 #else
00639         ix_int xx = (ix_int)(*ip);
00640         put_ix_int(xp, &xx);
00641 #   if IX_INT_MAX < LONG_MAX
00642         if(*ip > X_INT_MAX || *ip < X_INT_MIN)
00643                 return NC_ERANGE;
00644 #   endif
00645         return ENOERR;
00646 #endif
00647 }
00648 
00649 int
00650 ncx_put_int_float(void *xp, const float *ip)
00651 {
00652         ix_int xx = (ix_int)(*ip);
00653         put_ix_int(xp, &xx);
00654         if(*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN)
00655                 return NC_ERANGE;
00656         return ENOERR;
00657 }
00658 
00659 int
00660 ncx_put_int_double(void *xp, const double *ip)
00661 {
00662         ix_int xx = (ix_int)(*ip);
00663         put_ix_int(xp, &xx);
00664         if(*ip > X_INT_MAX || *ip < X_INT_MIN)
00665                 return NC_ERANGE;
00666         return ENOERR;
00667 }
00668  
00669 
00670 /* x_float */
00671 
00672 #if defined(INTEL_CC) || ( X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT))
00673 
00674 static void
00675 get_ix_float(const void *xp, float *ip)
00676 {
00677 #ifdef WORDS_BIGENDIAN
00678         (void) memcpy(ip, xp, sizeof(float));
00679 #else
00680         swap4b(ip, xp);
00681 #endif
00682 }
00683 
00684 static void
00685 put_ix_float(void *xp, const float *ip)
00686 {
00687 #ifdef WORDS_BIGENDIAN
00688         (void) memcpy(xp, ip, X_SIZEOF_FLOAT);
00689 #else
00690         swap4b(xp, ip);
00691 #endif
00692 }
00693 
00694 #elif vax
00695 
00696 /* What IEEE single precision floating point looks like on a Vax */
00697 struct  ieee_single {
00698         unsigned int    exp_hi       : 7;
00699         unsigned int    sign         : 1;
00700         unsigned int    mant_hi      : 7;
00701         unsigned int    exp_lo       : 1;
00702         unsigned int    mant_lo_hi   : 8;
00703         unsigned int    mant_lo_lo   : 8;
00704 };
00705 
00706 /* Vax single precision floating point */
00707 struct  vax_single {
00708         unsigned int    mantissa1 : 7;
00709         unsigned int    exp       : 8;
00710         unsigned int    sign      : 1;
00711         unsigned int    mantissa2 : 16;
00712 };
00713 
00714 #define VAX_SNG_BIAS    0x81
00715 #define IEEE_SNG_BIAS   0x7f
00716 
00717 static struct sgl_limits {
00718         struct vax_single s;
00719         struct ieee_single ieee;
00720 } max = {
00721         { 0x7f, 0xff, 0x0, 0xffff },    /* Max Vax */
00722         { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }               /* Max IEEE */
00723 };
00724 static struct sgl_limits min = {
00725         { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
00726         { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }                /* Min IEEE */
00727 };
00728 
00729 static void
00730 get_ix_float(const void *xp, float *ip)
00731 {
00732                 struct vax_single *const vsp = (struct vax_single *) ip;
00733                 const struct ieee_single *const isp =
00734                          (const struct ieee_single *) xp;
00735                 unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
00736 
00737                 switch(exp) {
00738                 case 0 :
00739                         /* ieee subnormal */
00740                         if(isp->mant_hi == min.ieee.mant_hi
00741                                 && isp->mant_lo_hi == min.ieee.mant_lo_hi
00742                                 && isp->mant_lo_lo == min.ieee.mant_lo_lo)
00743                         {
00744                                 *vsp = min.s;
00745                         }
00746                         else
00747                         {
00748                                 unsigned mantissa = (isp->mant_hi << 16)
00749                                          | isp->mant_lo_hi << 8
00750                                          | isp->mant_lo_lo;
00751                                 unsigned tmp = mantissa >> 20;
00752                                 if(tmp >= 4) {
00753                                         vsp->exp = 2;
00754                                 } else if (tmp >= 2) {
00755                                         vsp->exp = 1;
00756                                 } else {
00757                                         *vsp = min.s;
00758                                         break;
00759                                 } /* else */
00760                                 tmp = mantissa - (1 << (20 + vsp->exp ));
00761                                 tmp <<= 3 - vsp->exp;
00762                                 vsp->mantissa2 = tmp;
00763                                 vsp->mantissa1 = (tmp >> 16);
00764                         }
00765                         break;
00766                 case 0xfe :
00767                 case 0xff :
00768                         *vsp = max.s;
00769                         break;
00770                 default :
00771                         vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
00772                         vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
00773                         vsp->mantissa1 = isp->mant_hi;
00774                 }
00775 
00776                 vsp->sign = isp->sign;
00777 
00778 }
00779 
00780 
00781 static void
00782 put_ix_float(void *xp, const float *ip)
00783 {
00784                 const struct vax_single *const vsp =
00785                          (const struct vax_single *)ip;
00786                 struct ieee_single *const isp = (struct ieee_single *) xp;
00787 
00788                 switch(vsp->exp){
00789                 case 0 :
00790                         /* all vax float with zero exponent map to zero */
00791                         *isp = min.ieee;
00792                         break;
00793                 case 2 :
00794                 case 1 :
00795                 {
00796                         /* These will map to subnormals */
00797                         unsigned mantissa = (vsp->mantissa1 << 16)
00798                                          | vsp->mantissa2;
00799                         mantissa >>= 3 - vsp->exp;
00800                         mantissa += (1 << (20 + vsp->exp));
00801                         isp->mant_lo_lo = mantissa;
00802                         isp->mant_lo_hi = mantissa >> 8;
00803                         isp->mant_hi = mantissa >> 16;
00804                         isp->exp_lo = 0;
00805                         isp->exp_hi = 0;
00806                 }
00807                         break;
00808                 case 0xff : /* max.s.exp */
00809                         if( vsp->mantissa2 == max.s.mantissa2
00810                                 && vsp->mantissa1 == max.s.mantissa1)
00811                         {
00812                                 /* map largest vax float to ieee infinity */
00813                                 *isp = max.ieee;
00814                                 break;
00815                         } /* else, fall thru */
00816                 default :
00817                 {
00818                         unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
00819                         isp->exp_hi = exp >> 1;
00820                         isp->exp_lo = exp;
00821                         isp->mant_lo_lo = vsp->mantissa2;
00822                         isp->mant_lo_hi = vsp->mantissa2 >> 8;
00823                         isp->mant_hi = vsp->mantissa1;
00824                 }
00825                 }
00826 
00827                 isp->sign = vsp->sign;
00828 
00829 }
00830 
00831         /* vax */
00832 #elif defined(_CRAY)
00833 
00834 /*
00835  * Return the number of bytes until the next "word" boundary
00836  * N.B. This is based on the very wierd YMP address structure,
00837  * which puts the address within a word in the leftmost 3 bits
00838  * of the address.
00839  */
00840 static size_t
00841 word_align(const void *vp)
00842 {
00843         const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
00844         return (rem != 0);
00845 }
00846 
00847 struct ieee_single_hi {
00848         unsigned int    sign    : 1;
00849         unsigned int     exp    : 8;
00850         unsigned int    mant    :23;
00851         unsigned int    pad     :32;
00852 };
00853 typedef struct ieee_single_hi ieee_single_hi;
00854 
00855 struct ieee_single_lo {
00856         unsigned int    pad     :32;
00857         unsigned int    sign    : 1;
00858         unsigned int     exp    : 8;
00859         unsigned int    mant    :23;
00860 };
00861 typedef struct ieee_single_lo ieee_single_lo;
00862 
00863 static const int ieee_single_bias = 0x7f;
00864 
00865 struct ieee_double {
00866         unsigned int    sign    : 1;
00867         unsigned int     exp    :11;
00868         unsigned int    mant    :52;
00869 };
00870 typedef struct ieee_double ieee_double;
00871 
00872 static const int ieee_double_bias = 0x3ff;
00873 
00874 #if defined(NO_IEEE_FLOAT)
00875 
00876 struct cray_single {
00877         unsigned int    sign    : 1;
00878         unsigned int     exp    :15;
00879         unsigned int    mant    :48;
00880 };
00881 typedef struct cray_single cray_single;
00882 
00883 static const int cs_ieis_bias = 0x4000 - 0x7f;
00884 
00885 static const int cs_id_bias = 0x4000 - 0x3ff;
00886 
00887 
00888 static void
00889 get_ix_float(const void *xp, float *ip)
00890 {
00891 
00892         if(word_align(xp) == 0)
00893         {
00894                 const ieee_single_hi *isp = (const ieee_single_hi *) xp;
00895                 cray_single *csp = (cray_single *) ip;
00896 
00897                 if(isp->exp == 0)
00898                 {
00899                         /* ieee subnormal */
00900                         *ip = (double)isp->mant;
00901                         if(isp->mant != 0)
00902                         {
00903                                 csp->exp -= (ieee_single_bias + 22);
00904                         }
00905                 }
00906                 else
00907                 {
00908                         csp->exp  = isp->exp + cs_ieis_bias + 1;
00909                         csp->mant = isp->mant << (48 - 1 - 23);
00910                         csp->mant |= (1 << (48 - 1));
00911                 }
00912                 csp->sign = isp->sign;
00913 
00914 
00915         }
00916         else
00917         {
00918                 const ieee_single_lo *isp = (const ieee_single_lo *) xp;
00919                 cray_single *csp = (cray_single *) ip;
00920 
00921                 if(isp->exp == 0)
00922                 {
00923                         /* ieee subnormal */
00924                         *ip = (double)isp->mant;
00925                         if(isp->mant != 0)
00926                         {
00927                                 csp->exp -= (ieee_single_bias + 22);
00928                         }
00929                 }
00930                 else
00931                 {
00932                         csp->exp  = isp->exp + cs_ieis_bias + 1;
00933                         csp->mant = isp->mant << (48 - 1 - 23);
00934                         csp->mant |= (1 << (48 - 1));
00935                 }
00936                 csp->sign = isp->sign;
00937 
00938 
00939         }
00940 }
00941 
00942 static void
00943 put_ix_float(void *xp, const float *ip)
00944 {
00945         if(word_align(xp) == 0)
00946         {
00947                 ieee_single_hi *isp = (ieee_single_hi*)xp;
00948         const cray_single *csp = (const cray_single *) ip;
00949         int ieee_exp = csp->exp - cs_ieis_bias -1;
00950 
00951         isp->sign = csp->sign;
00952 
00953         if(ieee_exp >= 0xff)
00954         {
00955                 /* NC_ERANGE => ieee Inf */
00956                 isp->exp = 0xff;
00957                 isp->mant = 0x0;
00958         }
00959         else if(ieee_exp > 0)
00960         {
00961                 /* normal ieee representation */
00962                 isp->exp  = ieee_exp;
00963                 /* assumes cray rep is in normal form */
00964                 assert(csp->mant & 0x800000000000);
00965                 isp->mant = (((csp->mant << 1) &
00966                                 0xffffffffffff) >> (48 - 23));
00967         }
00968         else if(ieee_exp > -23)
00969         {
00970                 /* ieee subnormal, right  */
00971                 const int rshift = (48 - 23 - ieee_exp);
00972 
00973                 isp->mant = csp->mant >> rshift;
00974 
00975 #if 0
00976                 if(csp->mant & (1 << (rshift -1)))
00977                 {
00978                         /* round up */
00979                         isp->mant++;
00980                 }
00981 #endif
00982 
00983                 isp->exp  = 0;
00984         }
00985         else
00986         {
00987                 /* smaller than ieee can represent */
00988                 isp->exp = 0;
00989                 isp->mant = 0;
00990         }
00991 
00992         }
00993         else
00994         {
00995                 ieee_single_lo *isp = (ieee_single_lo*)xp;
00996         const cray_single *csp = (const cray_single *) ip;
00997         int ieee_exp = csp->exp - cs_ieis_bias -1;
00998 
00999         isp->sign = csp->sign;
01000 
01001         if(ieee_exp >= 0xff)
01002         {
01003                 /* NC_ERANGE => ieee Inf */
01004                 isp->exp = 0xff;
01005                 isp->mant = 0x0;
01006         }
01007         else if(ieee_exp > 0)
01008         {
01009                 /* normal ieee representation */
01010                 isp->exp  = ieee_exp;
01011                 /* assumes cray rep is in normal form */
01012                 assert(csp->mant & 0x800000000000);
01013                 isp->mant = (((csp->mant << 1) &
01014                                 0xffffffffffff) >> (48 - 23));
01015         }
01016         else if(ieee_exp > -23)
01017         {
01018                 /* ieee subnormal, right  */
01019                 const int rshift = (48 - 23 - ieee_exp);
01020 
01021                 isp->mant = csp->mant >> rshift;
01022 
01023 #if 0
01024                 if(csp->mant & (1 << (rshift -1)))
01025                 {
01026                         /* round up */
01027                         isp->mant++;
01028                 }
01029 #endif
01030 
01031                 isp->exp  = 0;
01032         }
01033         else
01034         {
01035                 /* smaller than ieee can represent */
01036                 isp->exp = 0;
01037                 isp->mant = 0;
01038         }
01039 
01040         }
01041 }
01042 
01043 #else
01044         /* IEEE Cray with only doubles */
01045 static void
01046 get_ix_float(const void *xp, float *ip)
01047 {
01048 
01049         ieee_double *idp = (ieee_double *) ip;
01050 
01051         if(word_align(xp) == 0)
01052         {
01053                 const ieee_single_hi *isp = (const ieee_single_hi *) xp;
01054                 if(isp->exp == 0 && isp->mant == 0)
01055                 {
01056                         idp->exp = 0;
01057                         idp->mant = 0;
01058                 }
01059                 else
01060                 {
01061                         idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
01062                         idp->mant = isp->mant << (52 - 23);
01063                 }
01064                 idp->sign = isp->sign;
01065         }
01066         else
01067         {
01068                 const ieee_single_lo *isp = (const ieee_single_lo *) xp;
01069                 if(isp->exp == 0 && isp->mant == 0)
01070                 {
01071                         idp->exp = 0;
01072                         idp->mant = 0;
01073                 }
01074                 else
01075                 {
01076                         idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
01077                         idp->mant = isp->mant << (52 - 23);
01078                 }
01079                 idp->sign = isp->sign;
01080         }
01081 }
01082 
01083 static void
01084 put_ix_float(void *xp, const float *ip)
01085 {
01086         const ieee_double *idp = (const ieee_double *) ip;
01087         if(word_align(xp) == 0)
01088         {
01089                 ieee_single_hi *isp = (ieee_single_hi*)xp;
01090                 if(idp->exp > (ieee_double_bias - ieee_single_bias))
01091                         isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
01092                 else
01093                         isp->exp = 0;
01094                 isp->mant = idp->mant >> (52 - 23);
01095                 isp->sign = idp->sign;
01096         }
01097         else
01098         {
01099                 ieee_single_lo *isp = (ieee_single_lo*)xp;
01100                 if(idp->exp > (ieee_double_bias - ieee_single_bias))
01101                         isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
01102                 else
01103                         isp->exp = 0;
01104                 isp->mant = idp->mant >> (52 - 23);
01105                 isp->sign = idp->sign;
01106         }
01107 }
01108 #endif
01109 
01110 #elif _SX && _FLOAT2
01111 static void
01112 get_ix_float(const void *xp, float *ip)
01113 {
01114         const int ncnv = ie3_fl2(xp, ip, 4, 8, 1);
01115 }
01116 
01117 static void
01118 put_ix_float(void *xp, const float *ip)
01119 {
01120         const int ncnv = fl2_ie3(ip, xp, 8, 4, 1);
01121 }
01122 #else
01123 #error "ix_float implementation"
01124 #endif
01125 
01126 
01127 int
01128 ncx_get_float_schar(const void *xp, schar *ip)
01129 {
01130         float xx;
01131         get_ix_float(xp, &xx);
01132         *ip = (schar) xx;
01133         if(xx > SCHAR_MAX || xx < SCHAR_MIN)
01134                 return NC_ERANGE;
01135         return ENOERR;
01136 }
01137 
01138 int
01139 ncx_get_float_uchar(const void *xp, uchar *ip)
01140 {
01141         float xx;
01142         get_ix_float(xp, &xx);
01143         *ip = (uchar) xx;
01144         if(xx > UCHAR_MAX || xx < 0)
01145                 return NC_ERANGE;
01146         return ENOERR;
01147 }
01148 
01149 int
01150 ncx_get_float_short(const void *xp, short *ip)
01151 {
01152         float xx;
01153         get_ix_float(xp, &xx);
01154         *ip = (short) xx;
01155         if(xx > SHORT_MAX || xx < SHORT_MIN)
01156                 return NC_ERANGE;
01157         return ENOERR;
01158 }
01159 
01160 int
01161 ncx_get_float_int(const void *xp, int *ip)
01162 {
01163         float xx;
01164         get_ix_float(xp, &xx);
01165         *ip = (int) xx;
01166         if(xx > (double)INT_MAX || xx < (double)INT_MIN)
01167                 return NC_ERANGE;
01168         return ENOERR;
01169 }
01170 
01171 int
01172 ncx_get_float_long(const void *xp, long *ip)
01173 {
01174         float xx;
01175         get_ix_float(xp, &xx);
01176         *ip = (long) xx;
01177         if(xx > LONG_MAX || xx < LONG_MIN)
01178                 return NC_ERANGE;
01179         return ENOERR;
01180 }
01181 
01182 int
01183 ncx_get_float_float(const void *xp, float *ip)
01184 {
01185         /* TODO */
01186         get_ix_float(xp, ip);
01187         return ENOERR;
01188 }
01189 
01190 int
01191 ncx_get_float_double(const void *xp, double *ip)
01192 {
01193         /* TODO */
01194         float xx;
01195         get_ix_float(xp, &xx);
01196         *ip = xx;
01197         return ENOERR;
01198 }
01199 
01200 
01201 int
01202 ncx_put_float_schar(void *xp, const schar *ip)
01203 {
01204         float xx = (float) *ip;
01205         put_ix_float(xp, &xx);
01206         return ENOERR;
01207 }
01208 
01209 int
01210 ncx_put_float_uchar(void *xp, const uchar *ip)
01211 {
01212         float xx = (float) *ip;
01213         put_ix_float(xp, &xx);
01214         return ENOERR;
01215 }
01216 
01217 int
01218 ncx_put_float_short(void *xp, const short *ip)
01219 {
01220         float xx = (float) *ip;
01221         put_ix_float(xp, &xx);
01222 #if 0   /* TODO: figure this out */
01223         if((float)(*ip) > X_FLOAT_MAX || (float)(*ip) < X_FLOAT_MIN)
01224                 return NC_ERANGE;
01225 #endif
01226         return ENOERR;
01227 }
01228 
01229 int
01230 ncx_put_float_int(void *xp, const int *ip)
01231 {
01232         float xx = (float) *ip;
01233         put_ix_float(xp, &xx);
01234 #if 1   /* TODO: figure this out */
01235         if((float)(*ip) > X_FLOAT_MAX || (float)(*ip) < X_FLOAT_MIN)
01236                 return NC_ERANGE;
01237 #endif
01238         return ENOERR;
01239 }
01240 
01241 int
01242 ncx_put_float_long(void *xp, const long *ip)
01243 {
01244         float xx = (float) *ip;
01245         put_ix_float(xp, &xx);
01246 #if 1   /* TODO: figure this out */
01247         if((float)(*ip) > X_FLOAT_MAX || (float)(*ip) < X_FLOAT_MIN)
01248                 return NC_ERANGE;
01249 #endif
01250         return ENOERR;
01251 }
01252 
01253 int
01254 ncx_put_float_float(void *xp, const float *ip)
01255 {
01256         put_ix_float(xp, ip);
01257 #ifdef NO_IEEE_FLOAT
01258         if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
01259                 return NC_ERANGE;
01260 #endif
01261         return ENOERR;
01262 }
01263 
01264 int
01265 ncx_put_float_double(void *xp, const double *ip)
01266 {
01267         float xx = (float) *ip;
01268         put_ix_float(xp, &xx);
01269         if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
01270                 return NC_ERANGE;
01271         return ENOERR;
01272 }
01273 
01274 /* x_double */
01275 
01276 #if defined(INTEL_CC) || (X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT))
01277 
01278 static void
01279 get_ix_double(const void *xp, double *ip)
01280 {
01281 #ifdef WORDS_BIGENDIAN
01282         (void) memcpy(ip, xp, sizeof(double));
01283 #else
01284         swap8b(ip, xp);
01285 #endif
01286 }
01287 
01288 static void
01289 put_ix_double(void *xp, const double *ip)
01290 {
01291 #ifdef WORDS_BIGENDIAN
01292         (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
01293 #else
01294         swap8b(xp, ip);
01295 #endif
01296 }
01297 
01298 #elif vax
01299 
01300 /* What IEEE double precision floating point looks like on a Vax */
01301 struct  ieee_double {
01302         unsigned int    exp_hi   : 7;
01303         unsigned int    sign     : 1;
01304         unsigned int    mant_6   : 4;
01305         unsigned int    exp_lo   : 4;
01306         unsigned int    mant_5   : 8;
01307         unsigned int    mant_4   : 8;
01308 
01309         unsigned int    mant_lo  : 32;
01310 };
01311 
01312 /* Vax double precision floating point */
01313 struct  vax_double {
01314         unsigned int    mantissa1 : 7;
01315         unsigned int    exp       : 8;
01316         unsigned int    sign      : 1;
01317         unsigned int    mantissa2 : 16;
01318         unsigned int    mantissa3 : 16;
01319         unsigned int    mantissa4 : 16;
01320 };
01321 
01322 #define VAX_DBL_BIAS    0x81
01323 #define IEEE_DBL_BIAS   0x3ff
01324 #define MASK(nbits)     ((1 << nbits) - 1)
01325 
01326 static const struct dbl_limits {
01327         struct  vax_double d;
01328         struct  ieee_double ieee;
01329 } dbl_limits[2] = {
01330         {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },   /* Max Vax */
01331         { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
01332         {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},               /* Min Vax */
01333         { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
01334 };
01335 
01336 
01337 static void
01338 get_ix_double(const void *xp, double *ip)
01339 {
01340         struct vax_double *const vdp =
01341                          (struct vax_double *)ip;
01342         const struct ieee_double *const idp =
01343                          (const struct ieee_double *) xp;
01344         {
01345                 const struct dbl_limits *lim;
01346                 int ii;
01347                 for (ii = 0, lim = dbl_limits;
01348                         ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
01349                         ii++, lim++)
01350                 {
01351                         if ((idp->mant_lo == lim->ieee.mant_lo)
01352                                 && (idp->mant_4 == lim->ieee.mant_4)
01353                                 && (idp->mant_5 == lim->ieee.mant_5)
01354                                 && (idp->mant_6 == lim->ieee.mant_6)
01355                                 && (idp->exp_lo == lim->ieee.exp_lo)
01356                                 && (idp->exp_hi == lim->ieee.exp_hi)
01357                                 )
01358                         {
01359                                 *vdp = lim->d;
01360                                 goto doneit;
01361                         }
01362                 }
01363         }
01364         {
01365                 unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
01366                 vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
01367         }
01368         {
01369                 unsigned mant_hi = ((idp->mant_6 << 16)
01370                                  | (idp->mant_5 << 8)
01371                                  | idp->mant_4);
01372                 unsigned mant_lo = SWAP4(idp->mant_lo);
01373                 vdp->mantissa1 = (mant_hi >> 13);
01374                 vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
01375                                 | (mant_lo >> 29);
01376                 vdp->mantissa3 = (mant_lo >> 13);
01377                 vdp->mantissa4 = (mant_lo << 3);
01378         }
01379         doneit:
01380                 vdp->sign = idp->sign;
01381 
01382 }
01383 
01384 
01385 static void
01386 put_ix_double(void *xp, const double *ip)
01387 {
01388         const struct vax_double *const vdp = 
01389                         (const struct vax_double *)ip;
01390         struct ieee_double *const idp =
01391                          (struct ieee_double *) xp;
01392 
01393         if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
01394                 (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
01395                 (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
01396                 (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
01397                 (vdp->exp == dbl_limits[0].d.exp))
01398         {
01399                 *idp = dbl_limits[0].ieee;
01400                 goto shipit;
01401         }
01402         if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
01403                 (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
01404                 (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
01405                 (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
01406                 (vdp->exp == dbl_limits[1].d.exp))
01407         {
01408                 *idp = dbl_limits[1].ieee;
01409                 goto shipit;
01410         }
01411 
01412         {
01413                 unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
01414 
01415                 unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
01416                         (vdp->mantissa3 << 13) |
01417                         ((vdp->mantissa4 >> 3) & MASK(13));
01418 
01419                 unsigned mant_hi = (vdp->mantissa1 << 13)
01420                                  | (vdp->mantissa2 >> 3);
01421 
01422                 if((vdp->mantissa4 & 7) > 4)
01423                 {
01424                         /* round up */
01425                         mant_lo++;
01426                         if(mant_lo == 0)
01427                         {
01428                                 mant_hi++;
01429                                 if(mant_hi > 0xffffff)
01430                                 {
01431                                         mant_hi = 0;
01432                                         exp++;
01433                                 }
01434                         }
01435                 }
01436 
01437                 idp->mant_lo = SWAP4(mant_lo);
01438                 idp->mant_6 = mant_hi >> 16;
01439                 idp->mant_5 = (mant_hi & 0xff00) >> 8;
01440                 idp->mant_4 = mant_hi;
01441                 idp->exp_hi = exp >> 4;
01442                 idp->exp_lo = exp;
01443         }
01444                 
01445         shipit:
01446                 idp->sign = vdp->sign;
01447 
01448 }
01449 
01450         /* vax */
01451 #elif defined(_CRAY)
01452 
01453 static void
01454 get_ix_double(const void *xp, double *ip)
01455 {
01456         const ieee_double *idp = (const ieee_double *) xp;
01457         cray_single *csp = (cray_single *) ip;
01458 
01459         if(idp->exp == 0)
01460         {
01461                 /* ieee subnormal */
01462                 *ip = (double)idp->mant;
01463                 if(idp->mant != 0)
01464                 {
01465                         csp->exp -= (ieee_double_bias + 51);
01466                 }
01467         }
01468         else
01469         {
01470                 csp->exp  = idp->exp + cs_id_bias + 1;
01471                 csp->mant = idp->mant >> (52 - 48 + 1);
01472                 csp->mant |= (1 << (48 - 1));
01473         }
01474         csp->sign = idp->sign;
01475 }
01476 
01477 static void
01478 put_ix_double(void *xp, const double *ip)
01479 {
01480         ieee_double *idp = (ieee_double *) xp;
01481         const cray_single *csp = (const cray_single *) ip;
01482 
01483         int ieee_exp = csp->exp - cs_id_bias -1;
01484 
01485         idp->sign = csp->sign;
01486 
01487         if(ieee_exp >= 0x7ff)
01488         {
01489                 /* NC_ERANGE => ieee Inf */
01490                 idp->exp = 0x7ff;
01491                 idp->mant = 0x0;
01492         }
01493         else if(ieee_exp > 0)
01494         {
01495                 /* normal ieee representation */
01496                 idp->exp  = ieee_exp;
01497                 /* assumes cray rep is in normal form */
01498                 assert(csp->mant & 0x800000000000);
01499                 idp->mant = (((csp->mant << 1) &
01500                                 0xffffffffffff) << (52 - 48));
01501         }
01502         else if(ieee_exp >= (-(52 -48)))
01503         {
01504                 /* ieee subnormal, left  */
01505                 const int lshift = (52 - 48) + ieee_exp;
01506                 idp->mant = csp->mant << lshift;
01507                 idp->exp  = 0;
01508         }
01509         else if(ieee_exp >= -52)
01510         {
01511                 /* ieee subnormal, right  */
01512                 const int rshift = (- (52 - 48) - ieee_exp);
01513 
01514                 idp->mant = csp->mant >> rshift;
01515 
01516 #if 0
01517                 if(csp->mant & (1 << (rshift -1)))
01518                 {
01519                         /* round up */
01520                         idp->mant++;
01521                 }
01522 #endif
01523 
01524                 idp->exp  = 0;
01525         }
01526         else
01527         {
01528                 /* smaller than ieee can represent */
01529                 idp->exp = 0;
01530                 idp->mant = 0;
01531         }
01532 }
01533 #elif _SX && _FLOAT2
01534 static void
01535 get_ix_double(const void *xp, double *ip)
01536 {
01537         const int ncnv = ie3_fl2(xp, ip, 8, 8, 1);
01538 }
01539 
01540 static void
01541 put_ix_double(void *xp, const double *ip)
01542 {
01543         const int ncnv = fl2_ie3(ip, xp, 8, 8, 1);
01544 }
01545 #else
01546 #error "ix_double implementation"
01547 #endif
01548 
01549 int
01550 ncx_get_double_schar(const void *xp, schar *ip)
01551 {
01552         double xx;
01553         get_ix_double(xp, &xx);
01554         *ip = (schar) xx;
01555         if(xx > SCHAR_MAX || xx < SCHAR_MIN)
01556                 return NC_ERANGE;
01557         return ENOERR;
01558 }
01559 
01560 int
01561 ncx_get_double_uchar(const void *xp, uchar *ip)
01562 {
01563         double xx;
01564         get_ix_double(xp, &xx);
01565         *ip = (uchar) xx;
01566         if(xx > UCHAR_MAX || xx < 0)
01567                 return NC_ERANGE;
01568         return ENOERR;
01569 }
01570 
01571 int
01572 ncx_get_double_short(const void *xp, short *ip)
01573 {
01574         double xx;
01575         get_ix_double(xp, &xx);
01576         *ip = (short) xx;
01577         if(xx > SHORT_MAX || xx < SHORT_MIN)
01578                 return NC_ERANGE;
01579         return ENOERR;
01580 }
01581 
01582 int
01583 ncx_get_double_int(const void *xp, int *ip)
01584 {
01585         double xx;
01586         get_ix_double(xp, &xx);
01587         *ip = (int) xx;
01588         if(xx > INT_MAX || xx < INT_MIN)
01589                 return NC_ERANGE;
01590         return ENOERR;
01591 }
01592 
01593 int
01594 ncx_get_double_long(const void *xp, long *ip)
01595 {
01596         double xx;
01597         get_ix_double(xp, &xx);
01598         *ip = (long) xx;
01599         if(xx > LONG_MAX || xx < LONG_MIN)
01600                 return NC_ERANGE;
01601         return ENOERR;
01602 }
01603 
01604 int
01605 ncx_get_double_float(const void *xp, float *ip)
01606 {
01607         double xx;
01608         get_ix_double(xp, &xx);
01609         if(xx > FLT_MAX || xx < (-FLT_MAX))
01610         {
01611                 *ip = FLT_MAX;
01612                 return NC_ERANGE;
01613         }
01614         if(xx < (-FLT_MAX))
01615         {
01616                 *ip = (-FLT_MAX);
01617                 return NC_ERANGE;
01618         }
01619         *ip = (float) xx;
01620         return ENOERR;
01621 }
01622 
01623 int
01624 ncx_get_double_double(const void *xp, double *ip)
01625 {
01626         /* TODO */
01627         get_ix_double(xp, ip);
01628         return ENOERR;
01629 }
01630 
01631 
01632 int
01633 ncx_put_double_schar(void *xp, const schar *ip)
01634 {
01635         double xx = (double) *ip;
01636         put_ix_double(xp, &xx);
01637         return ENOERR;
01638 }
01639 
01640 int
01641 ncx_put_double_uchar(void *xp, const uchar *ip)
01642 {
01643         double xx = (double) *ip;
01644         put_ix_double(xp, &xx);
01645         return ENOERR;
01646 }
01647 
01648 int
01649 ncx_put_double_short(void *xp, const short *ip)
01650 {
01651         double xx = (double) *ip;
01652         put_ix_double(xp, &xx);
01653 #if 0   /* TODO: figure this out */
01654         if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
01655                 return NC_ERANGE;
01656 #endif
01657         return ENOERR;
01658 }
01659 
01660 int
01661 ncx_put_double_int(void *xp, const int *ip)
01662 {
01663         double xx = (double) *ip;
01664         put_ix_double(xp, &xx);
01665 #if 0   /* TODO: figure this out */
01666         if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
01667                 return NC_ERANGE;
01668 #endif
01669         return ENOERR;
01670 }
01671 
01672 int
01673 ncx_put_double_long(void *xp, const long *ip)
01674 {
01675         double xx = (double) *ip;
01676         put_ix_double(xp, &xx);
01677 #if 1   /* TODO: figure this out */
01678         if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
01679                 return NC_ERANGE;
01680 #endif
01681         return ENOERR;
01682 }
01683 
01684 int
01685 ncx_put_double_float(void *xp, const float *ip)
01686 {
01687         double xx = (double) *ip;
01688         put_ix_double(xp, &xx);
01689 #if 1   /* TODO: figure this out */
01690         if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
01691                 return NC_ERANGE;
01692 #endif
01693         return ENOERR;
01694 }
01695 
01696 int
01697 ncx_put_double_double(void *xp, const double *ip)
01698 {
01699         put_ix_double(xp, ip);
01700 #ifdef NO_IEEE_FLOAT
01701         if(*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN)
01702                 return NC_ERANGE;
01703 #endif
01704         return ENOERR;
01705 }
01706 
01707 
01708 /* x_size_t */
01709 
01710 #if 0
01711 #if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
01712 #error "x_size_t implementation"
01713 /* netcdf requires size_t which can hold a values from 0 to 2^31 -1 */
01714 #endif
01715 #endif
01716 
01717 int
01718 ncx_put_size_t(void **xpp, const size_t *ulp)
01719 {
01720         /* similar to put_ix_int() */
01721         uchar *cp = (uchar *) *xpp;
01722                 /* sizes limited to 2^31 -1 in netcdf */
01723         assert(*ulp <= X_SIZE_MAX && (long) (*ulp) >= 0);
01724 
01725         *cp++ = (uchar)((*ulp) >> 24);
01726         *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
01727         *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
01728         *cp   = (uchar)((*ulp) & 0x000000ff);
01729 
01730         *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
01731         return ENOERR;
01732 }
01733 
01734 int
01735 ncx_get_size_t(const void **xpp,  size_t *ulp)
01736 {
01737         /* similar to get_ix_int */
01738         const uchar *cp = (const uchar *) *xpp;
01739         assert((*cp & 0x80) == 0); /* sizes limited to 2^31 -1 in netcdf */
01740 
01741         *ulp = *cp++ << 24;
01742         *ulp |= (*cp++ << 16);
01743         *ulp |= (*cp++ << 8);
01744         *ulp |= *cp; 
01745 
01746         *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
01747         return ENOERR;
01748 }
01749 
01750 /* x_off_t */
01751 
01752 #if 0
01753 #if SIZEOF_OFF_T < X_SIZEOF_OFF_T
01754 #error "x_off_t implementation"
01755 /* netcdf requires size_t which can hold a values from 0 to 2^31 -1 */
01756 #endif
01757 #endif
01758 
01759 int
01760 ncx_put_off_t(void **xpp, const off_t *lp)
01761 {
01762         /* similar to put_ix_int() */
01763         uchar *cp = (uchar *) *xpp;
01764                 /* No negative offsets stored in netcdf */
01765         assert(*lp >= 0 && *lp <= X_OFF_MAX);
01766 
01767         *cp++ = (uchar)((*lp) >> 24);
01768         *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
01769         *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
01770         *cp   = (uchar)((*lp) & 0x000000ff);
01771 
01772         *xpp = (void *)((char *)(*xpp) + X_SIZEOF_OFF_T);
01773         return ENOERR;
01774 }
01775 
01776 int
01777 ncx_get_off_t(const void **xpp, off_t *lp)
01778 {
01779         /* similar to get_ix_int() */
01780         const uchar *cp = (const uchar *) *xpp;
01781         assert((*cp & 0x80) == 0); /* No negative offsets stored in netcdf */
01782 
01783         *lp = *cp++ << 24;
01784         *lp |= (*cp++ << 16);
01785         *lp |= (*cp++ << 8);
01786         *lp |= *cp; 
01787 
01788         *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_OFF_T);
01789         return ENOERR;
01790 }
01791 
01792 
01793 /*
01794  * Aggregate numeric conversion functions.
01795  */
01796 
01797 
01798 
01799 /* schar */
01800 
01801 int
01802 ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
01803 {
01804                 (void) memcpy(tp, *xpp, nelems);
01805         *xpp = (void *)((char *)(*xpp) + nelems);
01806         return ENOERR;
01807 
01808 }
01809 int
01810 ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
01811 {
01812                 (void) memcpy(tp, *xpp, nelems);
01813         *xpp = (void *)((char *)(*xpp) + nelems);
01814         return ENOERR;
01815 
01816 }
01817 int
01818 ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
01819 {
01820         schar *xp = (schar *)(*xpp);
01821 
01822         while(nelems-- != 0)
01823         {
01824                 *tp++ = *xp++;
01825         }
01826 
01827         *xpp = (const void *)xp;
01828         return ENOERR;
01829 }
01830 
01831 int
01832 ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
01833 {
01834         schar *xp = (schar *)(*xpp);
01835 
01836         while(nelems-- != 0)
01837         {
01838                 *tp++ = *xp++;
01839         }
01840 
01841         *xpp = (const void *)xp;
01842         return ENOERR;
01843 }
01844 
01845 int
01846 ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
01847 {
01848         schar *xp = (schar *)(*xpp);
01849 
01850         while(nelems-- != 0)
01851         {
01852                 *tp++ = *xp++;
01853         }
01854 
01855         *xpp = (const void *)xp;
01856         return ENOERR;
01857 }
01858 
01859 int
01860 ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
01861 {
01862         schar *xp = (schar *)(*xpp);
01863 
01864         while(nelems-- != 0)
01865         {
01866                 *tp++ = *xp++;
01867         }
01868 
01869         *xpp = (const void *)xp;
01870         return ENOERR;
01871 }
01872 
01873 int
01874 ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
01875 {
01876         schar *xp = (schar *)(*xpp);
01877 
01878         while(nelems-- != 0)
01879         {
01880                 *tp++ = *xp++;
01881         }
01882 
01883         *xpp = (const void *)xp;
01884         return ENOERR;
01885 }
01886 
01887 
01888 int
01889 ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
01890 {
01891                 size_t rndup = nelems % X_ALIGN;
01892 
01893         if(rndup)
01894                 rndup = X_ALIGN - rndup;
01895 
01896         (void) memcpy(tp, *xpp, nelems);
01897         *xpp = (void *)((char *)(*xpp) + nelems + rndup);
01898 
01899         return ENOERR;
01900 
01901 }
01902 int
01903 ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
01904 {
01905                 size_t rndup = nelems % X_ALIGN;
01906 
01907         if(rndup)
01908                 rndup = X_ALIGN - rndup;
01909 
01910         (void) memcpy(tp, *xpp, nelems);
01911         *xpp = (void *)((char *)(*xpp) + nelems + rndup);
01912 
01913         return ENOERR;
01914 
01915 }
01916 int
01917 ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
01918 {
01919         size_t rndup = nelems % X_ALIGN;
01920         schar *xp = (schar *) *xpp;
01921 
01922         if(rndup)
01923                 rndup = X_ALIGN - rndup;
01924 
01925         while(nelems-- != 0)
01926         {
01927                 *tp++ = *xp++;
01928         }
01929 
01930         *xpp = (void *)(xp + rndup);
01931         return ENOERR;
01932 }
01933 
01934 int
01935 ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
01936 {
01937         size_t rndup = nelems % X_ALIGN;
01938         schar *xp = (schar *) *xpp;
01939 
01940         if(rndup)
01941                 rndup = X_ALIGN - rndup;
01942 
01943         while(nelems-- != 0)
01944         {
01945                 *tp++ = *xp++;
01946         }
01947 
01948         *xpp = (void *)(xp + rndup);
01949         return ENOERR;
01950 }
01951 
01952 int
01953 ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
01954 {
01955         size_t rndup = nelems % X_ALIGN;
01956         schar *xp = (schar *) *xpp;
01957 
01958         if(rndup)
01959                 rndup = X_ALIGN - rndup;
01960 
01961         while(nelems-- != 0)
01962         {
01963                 *tp++ = *xp++;
01964         }
01965 
01966         *xpp = (void *)(xp + rndup);
01967         return ENOERR;
01968 }
01969 
01970 int
01971 ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
01972 {
01973         size_t rndup = nelems % X_ALIGN;
01974         schar *xp = (schar *) *xpp;
01975 
01976         if(rndup)
01977                 rndup = X_ALIGN - rndup;
01978 
01979         while(nelems-- != 0)
01980         {
01981                 *tp++ = *xp++;
01982         }
01983 
01984         *xpp = (void *)(xp + rndup);
01985         return ENOERR;
01986 }
01987 
01988 int
01989 ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
01990 {
01991         size_t rndup = nelems % X_ALIGN;
01992         schar *xp = (schar *) *xpp;
01993 
01994         if(rndup)
01995                 rndup = X_ALIGN - rndup;
01996 
01997         while(nelems-- != 0)
01998         {
01999                 *tp++ = *xp++;
02000         }
02001 
02002         *xpp = (void *)(xp + rndup);
02003         return ENOERR;
02004 }
02005 
02006 
02007 int
02008 ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
02009 {
02010                 (void) memcpy(*xpp, tp, nelems);
02011         *xpp = (void *)((char *)(*xpp) + nelems);
02012 
02013         return ENOERR;
02014 
02015 }
02016 int
02017 ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
02018 {
02019                 (void) memcpy(*xpp, tp, nelems);
02020         *xpp = (void *)((char *)(*xpp) + nelems);
02021 
02022         return ENOERR;
02023 
02024 }
02025 int
02026 ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp)
02027 {
02028         int status = ENOERR;
02029         schar *xp = (schar *) *xpp;
02030 
02031         while(nelems-- != 0)
02032         {
02033                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02034                         status = NC_ERANGE;
02035                 *xp++ = (schar) *tp++;
02036         }
02037 
02038         *xpp = (void *)xp;
02039         return status;
02040 }
02041 
02042 int
02043 ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp)
02044 {
02045         int status = ENOERR;
02046         schar *xp = (schar *) *xpp;
02047 
02048         while(nelems-- != 0)
02049         {
02050                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02051                         status = NC_ERANGE;
02052                 *xp++ = (schar) *tp++;
02053         }
02054 
02055         *xpp = (void *)xp;
02056         return status;
02057 }
02058 
02059 int
02060 ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp)
02061 {
02062         int status = ENOERR;
02063         schar *xp = (schar *) *xpp;
02064 
02065         while(nelems-- != 0)
02066         {
02067                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02068                         status = NC_ERANGE;
02069                 *xp++ = (schar) *tp++;
02070         }
02071 
02072         *xpp = (void *)xp;
02073         return status;
02074 }
02075 
02076 int
02077 ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp)
02078 {
02079         int status = ENOERR;
02080         schar *xp = (schar *) *xpp;
02081 
02082         while(nelems-- != 0)
02083         {
02084                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02085                         status = NC_ERANGE;
02086                 *xp++ = (schar) *tp++;
02087         }
02088 
02089         *xpp = (void *)xp;
02090         return status;
02091 }
02092 
02093 int
02094 ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp)
02095 {
02096         int status = ENOERR;
02097         schar *xp = (schar *) *xpp;
02098 
02099         while(nelems-- != 0)
02100         {
02101                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02102                         status = NC_ERANGE;
02103                 *xp++ = (schar) *tp++;
02104         }
02105 
02106         *xpp = (void *)xp;
02107         return status;
02108 }
02109 
02110 
02111 int
02112 ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
02113 {
02114                 size_t rndup = nelems % X_ALIGN;
02115 
02116         if(rndup)
02117                 rndup = X_ALIGN - rndup;
02118 
02119         (void) memcpy(*xpp, tp, nelems);
02120         *xpp = (void *)((char *)(*xpp) + nelems);
02121 
02122         if(rndup)
02123         {
02124                 (void) memcpy(*xpp, nada, rndup);
02125                 *xpp = (void *)((char *)(*xpp) + rndup);
02126         }
02127         
02128         return ENOERR;
02129 
02130 }
02131 int
02132 ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
02133 {
02134                 size_t rndup = nelems % X_ALIGN;
02135 
02136         if(rndup)
02137                 rndup = X_ALIGN - rndup;
02138 
02139         (void) memcpy(*xpp, tp, nelems);
02140         *xpp = (void *)((char *)(*xpp) + nelems);
02141 
02142         if(rndup)
02143         {
02144                 (void) memcpy(*xpp, nada, rndup);
02145                 *xpp = (void *)((char *)(*xpp) + rndup);
02146         }
02147         
02148         return ENOERR;
02149 
02150 }
02151 int
02152 ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp)
02153 {
02154         int status = ENOERR;
02155         size_t rndup = nelems % X_ALIGN;
02156         schar *xp = (schar *) *xpp;
02157 
02158         if(rndup)
02159                 rndup = X_ALIGN - rndup;
02160 
02161         while(nelems-- != 0)
02162         {
02163                 /* N.B. schar as signed */
02164                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02165                         status = NC_ERANGE;
02166                 *xp++ = (schar) *tp++;
02167         }
02168 
02169 
02170         if(rndup)
02171         {
02172                 (void) memcpy(xp, nada, rndup);
02173                 xp += rndup;
02174         }
02175 
02176         *xpp = (void *)xp;
02177         return status;
02178 }
02179 
02180 int
02181 ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp)
02182 {
02183         int status = ENOERR;
02184         size_t rndup = nelems % X_ALIGN;
02185         schar *xp = (schar *) *xpp;
02186 
02187         if(rndup)
02188                 rndup = X_ALIGN - rndup;
02189 
02190         while(nelems-- != 0)
02191         {
02192                 /* N.B. schar as signed */
02193                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02194                         status = NC_ERANGE;
02195                 *xp++ = (schar) *tp++;
02196         }
02197 
02198 
02199         if(rndup)
02200         {
02201                 (void) memcpy(xp, nada, rndup);
02202                 xp += rndup;
02203         }
02204 
02205         *xpp = (void *)xp;
02206         return status;
02207 }
02208 
02209 int
02210 ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp)
02211 {
02212         int status = ENOERR;
02213         size_t rndup = nelems % X_ALIGN;
02214         schar *xp = (schar *) *xpp;
02215 
02216         if(rndup)
02217                 rndup = X_ALIGN - rndup;
02218 
02219         while(nelems-- != 0)
02220         {
02221                 /* N.B. schar as signed */
02222                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02223                         status = NC_ERANGE;
02224                 *xp++ = (schar) *tp++;
02225         }
02226 
02227 
02228         if(rndup)
02229         {
02230                 (void) memcpy(xp, nada, rndup);
02231                 xp += rndup;
02232         }
02233 
02234         *xpp = (void *)xp;
02235         return status;
02236 }
02237 
02238 int
02239 ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp)
02240 {
02241         int status = ENOERR;
02242         size_t rndup = nelems % X_ALIGN;
02243         schar *xp = (schar *) *xpp;
02244 
02245         if(rndup)
02246                 rndup = X_ALIGN - rndup;
02247 
02248         while(nelems-- != 0)
02249         {
02250                 /* N.B. schar as signed */
02251                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02252                         status = NC_ERANGE;
02253                 *xp++ = (schar) *tp++;
02254         }
02255 
02256 
02257         if(rndup)
02258         {
02259                 (void) memcpy(xp, nada, rndup);
02260                 xp += rndup;
02261         }
02262 
02263         *xpp = (void *)xp;
02264         return status;
02265 }
02266 
02267 int
02268 ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp)
02269 {
02270         int status = ENOERR;
02271         size_t rndup = nelems % X_ALIGN;
02272         schar *xp = (schar *) *xpp;
02273 
02274         if(rndup)
02275                 rndup = X_ALIGN - rndup;
02276 
02277         while(nelems-- != 0)
02278         {
02279                 /* N.B. schar as signed */
02280                 if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
02281                         status = NC_ERANGE;
02282                 *xp++ = (schar) *tp++;
02283         }
02284 
02285 
02286         if(rndup)
02287         {
02288                 (void) memcpy(xp, nada, rndup);
02289                 xp += rndup;
02290         }
02291 
02292         *xpp = (void *)xp;
02293         return status;
02294 }
02295 
02296 
02297 
02298 /* short */
02299 
02300 int
02301 ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
02302 {
02303         const char *xp = (const char *) *xpp;
02304         int status = ENOERR;
02305 
02306         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02307         {
02308                 const int lstatus = ncx_get_short_schar(xp, tp);
02309                 if(lstatus != ENOERR)
02310                         status = lstatus;
02311         }
02312 
02313         *xpp = (const void *)xp;
02314         return status;
02315 }
02316 
02317 int
02318 ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
02319 {
02320         const char *xp = (const char *) *xpp;
02321         int status = ENOERR;
02322 
02323         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02324         {
02325                 const int lstatus = ncx_get_short_uchar(xp, tp);
02326                 if(lstatus != ENOERR)
02327                         status = lstatus;
02328         }
02329 
02330         *xpp = (const void *)xp;
02331         return status;
02332 }
02333 
02334 #if X_SIZEOF_SHORT == SIZEOF_SHORT
02335 /* optimized version */
02336 int
02337 ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
02338 {
02339 # if WORDS_BIGENDIAN
02340         (void) memcpy(tp, *xpp, nelems * sizeof(short));
02341 # else
02342         swapn2b(tp, *xpp, nelems);
02343 # endif
02344         *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
02345         return ENOERR;
02346 }
02347 #else
02348 int
02349 ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
02350 {
02351         const char *xp = (const char *) *xpp;
02352         int status = ENOERR;
02353 
02354         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02355         {
02356                 const int lstatus = ncx_get_short_short(xp, tp);
02357                 if(lstatus != ENOERR)
02358                         status = lstatus;
02359         }
02360 
02361         *xpp = (const void *)xp;
02362         return status;
02363 }
02364 
02365 #endif
02366 int
02367 ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
02368 {
02369         const char *xp = (const char *) *xpp;
02370         int status = ENOERR;
02371 
02372         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02373         {
02374                 const int lstatus = ncx_get_short_int(xp, tp);
02375                 if(lstatus != ENOERR)
02376                         status = lstatus;
02377         }
02378 
02379         *xpp = (const void *)xp;
02380         return status;
02381 }
02382 
02383 int
02384 ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
02385 {
02386         const char *xp = (const char *) *xpp;
02387         int status = ENOERR;
02388 
02389         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02390         {
02391                 const int lstatus = ncx_get_short_long(xp, tp);
02392                 if(lstatus != ENOERR)
02393                         status = lstatus;
02394         }
02395 
02396         *xpp = (const void *)xp;
02397         return status;
02398 }
02399 
02400 int
02401 ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
02402 {
02403         const char *xp = (const char *) *xpp;
02404         int status = ENOERR;
02405 
02406         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02407         {
02408                 const int lstatus = ncx_get_short_float(xp, tp);
02409                 if(lstatus != ENOERR)
02410                         status = lstatus;
02411         }
02412 
02413         *xpp = (const void *)xp;
02414         return status;
02415 }
02416 
02417 int
02418 ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
02419 {
02420         const char *xp = (const char *) *xpp;
02421         int status = ENOERR;
02422 
02423         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02424         {
02425                 const int lstatus = ncx_get_short_double(xp, tp);
02426                 if(lstatus != ENOERR)
02427                         status = lstatus;
02428         }
02429 
02430         *xpp = (const void *)xp;
02431         return status;
02432 }
02433 
02434 
02435 int
02436 ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
02437 {
02438         const size_t rndup = nelems % 2;
02439 
02440         const char *xp = (const char *) *xpp;
02441         int status = ENOERR;
02442 
02443         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02444         {
02445                 const int lstatus = ncx_get_short_schar(xp, tp);
02446                 if(lstatus != ENOERR)
02447                         status = lstatus;
02448         }
02449 
02450         if(rndup != 0)
02451                 xp += X_SIZEOF_SHORT;
02452                 
02453         *xpp = (void *)xp;
02454         return status;
02455 }
02456 
02457 int
02458 ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
02459 {
02460         const size_t rndup = nelems % 2;
02461 
02462         const char *xp = (const char *) *xpp;
02463         int status = ENOERR;
02464 
02465         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02466         {
02467                 const int lstatus = ncx_get_short_uchar(xp, tp);
02468                 if(lstatus != ENOERR)
02469                         status = lstatus;
02470         }
02471 
02472         if(rndup != 0)
02473                 xp += X_SIZEOF_SHORT;
02474                 
02475         *xpp = (void *)xp;
02476         return status;
02477 }
02478 
02479 int
02480 ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
02481 {
02482         const size_t rndup = nelems % 2;
02483 
02484         const char *xp = (const char *) *xpp;
02485         int status = ENOERR;
02486 
02487         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02488         {
02489                 const int lstatus = ncx_get_short_short(xp, tp);
02490                 if(lstatus != ENOERR)
02491                         status = lstatus;
02492         }
02493 
02494         if(rndup != 0)
02495                 xp += X_SIZEOF_SHORT;
02496                 
02497         *xpp = (void *)xp;
02498         return status;
02499 }
02500 
02501 int
02502 ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
02503 {
02504         const size_t rndup = nelems % 2;
02505 
02506         const char *xp = (const char *) *xpp;
02507         int status = ENOERR;
02508 
02509         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02510         {
02511                 const int lstatus = ncx_get_short_int(xp, tp);
02512                 if(lstatus != ENOERR)
02513                         status = lstatus;
02514         }
02515 
02516         if(rndup != 0)
02517                 xp += X_SIZEOF_SHORT;
02518                 
02519         *xpp = (void *)xp;
02520         return status;
02521 }
02522 
02523 int
02524 ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
02525 {
02526         const size_t rndup = nelems % 2;
02527 
02528         const char *xp = (const char *) *xpp;
02529         int status = ENOERR;
02530 
02531         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02532         {
02533                 const int lstatus = ncx_get_short_long(xp, tp);
02534                 if(lstatus != ENOERR)
02535                         status = lstatus;
02536         }
02537 
02538         if(rndup != 0)
02539                 xp += X_SIZEOF_SHORT;
02540                 
02541         *xpp = (void *)xp;
02542         return status;
02543 }
02544 
02545 int
02546 ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
02547 {
02548         const size_t rndup = nelems % 2;
02549 
02550         const char *xp = (const char *) *xpp;
02551         int status = ENOERR;
02552 
02553         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02554         {
02555                 const int lstatus = ncx_get_short_float(xp, tp);
02556                 if(lstatus != ENOERR)
02557                         status = lstatus;
02558         }
02559 
02560         if(rndup != 0)
02561                 xp += X_SIZEOF_SHORT;
02562                 
02563         *xpp = (void *)xp;
02564         return status;
02565 }
02566 
02567 int
02568 ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
02569 {
02570         const size_t rndup = nelems % 2;
02571 
02572         const char *xp = (const char *) *xpp;
02573         int status = ENOERR;
02574 
02575         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02576         {
02577                 const int lstatus = ncx_get_short_double(xp, tp);
02578                 if(lstatus != ENOERR)
02579                         status = lstatus;
02580         }
02581 
02582         if(rndup != 0)
02583                 xp += X_SIZEOF_SHORT;
02584                 
02585         *xpp = (void *)xp;
02586         return status;
02587 }
02588 
02589 
02590 int
02591 ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp)
02592 {
02593         char *xp = (char *) *xpp;
02594         int status = ENOERR;
02595 
02596         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02597         {
02598                 int lstatus = ncx_put_short_schar(xp, tp);
02599                 if(lstatus != ENOERR)
02600                         status = lstatus;
02601         }
02602 
02603         *xpp = (void *)xp;
02604         return status;
02605 }
02606 
02607 int
02608 ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp)
02609 {
02610         char *xp = (char *) *xpp;
02611         int status = ENOERR;
02612 
02613         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02614         {
02615                 int lstatus = ncx_put_short_uchar(xp, tp);
02616                 if(lstatus != ENOERR)
02617                         status = lstatus;
02618         }
02619 
02620         *xpp = (void *)xp;
02621         return status;
02622 }
02623 
02624 #if X_SIZEOF_SHORT == SIZEOF_SHORT
02625 /* optimized version */
02626 int
02627 ncx_putn_short_short(void **xpp, size_t nelems, const short *tp)
02628 {
02629 # if WORDS_BIGENDIAN
02630         (void) memcpy(*xpp, tp, nelems * X_SIZEOF_SHORT);
02631 # else
02632         swapn2b(*xpp, tp, nelems);
02633 # endif
02634         *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
02635         return ENOERR;
02636 }
02637 #else
02638 int
02639 ncx_putn_short_short(void **xpp, size_t nelems, const short *tp)
02640 {
02641         char *xp = (char *) *xpp;
02642         int status = ENOERR;
02643 
02644         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02645         {
02646                 int lstatus = ncx_put_short_short(xp, tp);
02647                 if(lstatus != ENOERR)
02648                         status = lstatus;
02649         }
02650 
02651         *xpp = (void *)xp;
02652         return status;
02653 }
02654 
02655 #endif
02656 int
02657 ncx_putn_short_int(void **xpp, size_t nelems, const int *tp)
02658 {
02659         char *xp = (char *) *xpp;
02660         int status = ENOERR;
02661 
02662         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02663         {
02664                 int lstatus = ncx_put_short_int(xp, tp);
02665                 if(lstatus != ENOERR)
02666                         status = lstatus;
02667         }
02668 
02669         *xpp = (void *)xp;
02670         return status;
02671 }
02672 
02673 int
02674 ncx_putn_short_long(void **xpp, size_t nelems, const long *tp)
02675 {
02676         char *xp = (char *) *xpp;
02677         int status = ENOERR;
02678 
02679         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02680         {
02681                 int lstatus = ncx_put_short_long(xp, tp);
02682                 if(lstatus != ENOERR)
02683                         status = lstatus;
02684         }
02685 
02686         *xpp = (void *)xp;
02687         return status;
02688 }
02689 
02690 int
02691 ncx_putn_short_float(void **xpp, size_t nelems, const float *tp)
02692 {
02693         char *xp = (char *) *xpp;
02694         int status = ENOERR;
02695 
02696         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02697         {
02698                 int lstatus = ncx_put_short_float(xp, tp);
02699                 if(lstatus != ENOERR)
02700                         status = lstatus;
02701         }
02702 
02703         *xpp = (void *)xp;
02704         return status;
02705 }
02706 
02707 int
02708 ncx_putn_short_double(void **xpp, size_t nelems, const double *tp)
02709 {
02710         char *xp = (char *) *xpp;
02711         int status = ENOERR;
02712 
02713         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02714         {
02715                 int lstatus = ncx_put_short_double(xp, tp);
02716                 if(lstatus != ENOERR)
02717                         status = lstatus;
02718         }
02719 
02720         *xpp = (void *)xp;
02721         return status;
02722 }
02723 
02724 
02725 int
02726 ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp)
02727 {
02728         const size_t rndup = nelems % 2;
02729 
02730         char *xp = (char *) *xpp;
02731         int status = ENOERR;
02732 
02733         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02734         {
02735                 int lstatus = ncx_put_short_schar(xp, tp);
02736                 if(lstatus != ENOERR)
02737                         status = lstatus;
02738         }
02739 
02740         if(rndup != 0)
02741         {
02742                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02743                 xp += X_SIZEOF_SHORT;   
02744         }
02745                 
02746         *xpp = (void *)xp;
02747         return status;
02748 }
02749 
02750 int
02751 ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp)
02752 {
02753         const size_t rndup = nelems % 2;
02754 
02755         char *xp = (char *) *xpp;
02756         int status = ENOERR;
02757 
02758         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02759         {
02760                 int lstatus = ncx_put_short_uchar(xp, tp);
02761                 if(lstatus != ENOERR)
02762                         status = lstatus;
02763         }
02764 
02765         if(rndup != 0)
02766         {
02767                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02768                 xp += X_SIZEOF_SHORT;   
02769         }
02770                 
02771         *xpp = (void *)xp;
02772         return status;
02773 }
02774 
02775 int
02776 ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp)
02777 {
02778         const size_t rndup = nelems % 2;
02779 
02780         char *xp = (char *) *xpp;
02781         int status = ENOERR;
02782 
02783         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02784         {
02785                 int lstatus = ncx_put_short_short(xp, tp);
02786                 if(lstatus != ENOERR)
02787                         status = lstatus;
02788         }
02789 
02790         if(rndup != 0)
02791         {
02792                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02793                 xp += X_SIZEOF_SHORT;   
02794         }
02795                 
02796         *xpp = (void *)xp;
02797         return status;
02798 }
02799 
02800 int
02801 ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp)
02802 {
02803         const size_t rndup = nelems % 2;
02804 
02805         char *xp = (char *) *xpp;
02806         int status = ENOERR;
02807 
02808         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02809         {
02810                 int lstatus = ncx_put_short_int(xp, tp);
02811                 if(lstatus != ENOERR)
02812                         status = lstatus;
02813         }
02814 
02815         if(rndup != 0)
02816         {
02817                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02818                 xp += X_SIZEOF_SHORT;   
02819         }
02820                 
02821         *xpp = (void *)xp;
02822         return status;
02823 }
02824 
02825 int
02826 ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp)
02827 {
02828         const size_t rndup = nelems % 2;
02829 
02830         char *xp = (char *) *xpp;
02831         int status = ENOERR;
02832 
02833         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02834         {
02835                 int lstatus = ncx_put_short_long(xp, tp);
02836                 if(lstatus != ENOERR)
02837                         status = lstatus;
02838         }
02839 
02840         if(rndup != 0)
02841         {
02842                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02843                 xp += X_SIZEOF_SHORT;   
02844         }
02845                 
02846         *xpp = (void *)xp;
02847         return status;
02848 }
02849 
02850 int
02851 ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp)
02852 {
02853         const size_t rndup = nelems % 2;
02854 
02855         char *xp = (char *) *xpp;
02856         int status = ENOERR;
02857 
02858         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02859         {
02860                 int lstatus = ncx_put_short_float(xp, tp);
02861                 if(lstatus != ENOERR)
02862                         status = lstatus;
02863         }
02864 
02865         if(rndup != 0)
02866         {
02867                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02868                 xp += X_SIZEOF_SHORT;   
02869         }
02870                 
02871         *xpp = (void *)xp;
02872         return status;
02873 }
02874 
02875 int
02876 ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp)
02877 {
02878         const size_t rndup = nelems % 2;
02879 
02880         char *xp = (char *) *xpp;
02881         int status = ENOERR;
02882 
02883         for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
02884         {
02885                 int lstatus = ncx_put_short_double(xp, tp);
02886                 if(lstatus != ENOERR)
02887                         status = lstatus;
02888         }
02889 
02890         if(rndup != 0)
02891         {
02892                 (void) memcpy(xp, nada, X_SIZEOF_SHORT);
02893                 xp += X_SIZEOF_SHORT;   
02894         }
02895                 
02896         *xpp = (void *)xp;
02897         return status;
02898 }
02899 
02900 
02901 
02902 /* int */
02903 
02904 int
02905 ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
02906 {
02907         const char *xp = (const char *) *xpp;
02908         int status = ENOERR;
02909 
02910         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
02911         {
02912                 const int lstatus = ncx_get_int_schar(xp, tp);
02913                 if(lstatus != ENOERR)
02914                         status = lstatus;
02915         }
02916 
02917         *xpp = (const void *)xp;
02918         return status;
02919 }
02920 
02921 int
02922 ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
02923 {
02924         const char *xp = (const char *) *xpp;
02925         int status = ENOERR;
02926 
02927         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
02928         {
02929                 const int lstatus = ncx_get_int_uchar(xp, tp);
02930                 if(lstatus != ENOERR)
02931                         status = lstatus;
02932         }
02933 
02934         *xpp = (const void *)xp;
02935         return status;
02936 }
02937 
02938 int
02939 ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
02940 {
02941         const char *xp = (const char *) *xpp;
02942         int status = ENOERR;
02943 
02944         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
02945         {
02946                 const int lstatus = ncx_get_int_short(xp, tp);
02947                 if(lstatus != ENOERR)
02948                         status = lstatus;
02949         }
02950 
02951         *xpp = (const void *)xp;
02952         return status;
02953 }
02954 
02955 #if X_SIZEOF_INT == SIZEOF_INT
02956 /* optimized version */
02957 int
02958 ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
02959 {
02960 # if WORDS_BIGENDIAN
02961         (void) memcpy(tp, *xpp, nelems * sizeof(int));
02962 # else
02963         swapn4b(tp, *xpp, nelems);
02964 # endif
02965         *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
02966         return ENOERR;
02967 }
02968 #else
02969 int
02970 ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
02971 {
02972         const char *xp = (const char *) *xpp;
02973         int status = ENOERR;
02974 
02975         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
02976         {
02977                 const int lstatus = ncx_get_int_int(xp, tp);
02978                 if(lstatus != ENOERR)
02979                         status = lstatus;
02980         }
02981 
02982         *xpp = (const void *)xp;
02983         return status;
02984 }
02985 
02986 #endif
02987 #if X_SIZEOF_INT == SIZEOF_LONG
02988 /* optimized version */
02989 int
02990 ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
02991 {
02992 # if WORDS_BIGENDIAN
02993         (void) memcpy(tp, *xpp, nelems * sizeof(long));
02994 # else
02995         swapn4b(tp, *xpp, nelems);
02996 # endif
02997         *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
02998         return ENOERR;
02999 }
03000 #else
03001 int
03002 ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
03003 {
03004         const char *xp = (const char *) *xpp;
03005         int status = ENOERR;
03006 
03007         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03008         {
03009                 const int lstatus = ncx_get_int_long(xp, tp);
03010                 if(lstatus != ENOERR)
03011                         status = lstatus;
03012         }
03013 
03014         *xpp = (const void *)xp;
03015         return status;
03016 }
03017 
03018 #endif
03019 int
03020 ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
03021 {
03022         const char *xp = (const char *) *xpp;
03023         int status = ENOERR;
03024 
03025         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03026         {
03027                 const int lstatus = ncx_get_int_float(xp, tp);
03028                 if(lstatus != ENOERR)
03029                         status = lstatus;
03030         }
03031 
03032         *xpp = (const void *)xp;
03033         return status;
03034 }
03035 
03036 int
03037 ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
03038 {
03039         const char *xp = (const char *) *xpp;
03040         int status = ENOERR;
03041 
03042         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03043         {
03044                 const int lstatus = ncx_get_int_double(xp, tp);
03045                 if(lstatus != ENOERR)
03046                         status = lstatus;
03047         }
03048 
03049         *xpp = (const void *)xp;
03050         return status;
03051 }
03052 
03053 
03054 int
03055 ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp)
03056 {
03057         char *xp = (char *) *xpp;
03058         int status = ENOERR;
03059 
03060         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03061         {
03062                 int lstatus = ncx_put_int_schar(xp, tp);
03063                 if(lstatus != ENOERR)
03064                         status = lstatus;
03065         }
03066 
03067         *xpp = (void *)xp;
03068         return status;
03069 }
03070 
03071 int
03072 ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp)
03073 {
03074         char *xp = (char *) *xpp;
03075         int status = ENOERR;
03076 
03077         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03078         {
03079                 int lstatus = ncx_put_int_uchar(xp, tp);
03080                 if(lstatus != ENOERR)
03081                         status = lstatus;
03082         }
03083 
03084         *xpp = (void *)xp;
03085         return status;
03086 }
03087 
03088 int
03089 ncx_putn_int_short(void **xpp, size_t nelems, const short *tp)
03090 {
03091         char *xp = (char *) *xpp;
03092         int status = ENOERR;
03093 
03094         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03095         {
03096                 int lstatus = ncx_put_int_short(xp, tp);
03097                 if(lstatus != ENOERR)
03098                         status = lstatus;
03099         }
03100 
03101         *xpp = (void *)xp;
03102         return status;
03103 }
03104 
03105 #if X_SIZEOF_INT == SIZEOF_INT
03106 /* optimized version */
03107 int
03108 ncx_putn_int_int(void **xpp, size_t nelems, const int *tp)
03109 {
03110 # if WORDS_BIGENDIAN
03111         (void) memcpy(*xpp, tp, nelems * X_SIZEOF_INT);
03112 # else
03113         swapn4b(*xpp, tp, nelems);
03114 # endif
03115         *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
03116         return ENOERR;
03117 }
03118 #else
03119 int
03120 ncx_putn_int_int(void **xpp, size_t nelems, const int *tp)
03121 {
03122         char *xp = (char *) *xpp;
03123         int status = ENOERR;
03124 
03125         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03126         {
03127                 int lstatus = ncx_put_int_int(xp, tp);
03128                 if(lstatus != ENOERR)
03129                         status = lstatus;
03130         }
03131 
03132         *xpp = (void *)xp;
03133         return status;
03134 }
03135 
03136 #endif
03137 #if X_SIZEOF_INT == SIZEOF_LONG
03138 /* optimized version */
03139 int
03140 ncx_putn_int_long(void **xpp, size_t nelems, const long *tp)
03141 {
03142 # if WORDS_BIGENDIAN
03143         (void) memcpy(*xpp, tp, nelems * X_SIZEOF_INT);
03144 # else
03145         swapn4b(*xpp, tp, nelems);
03146 # endif
03147         *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
03148         return ENOERR;
03149 }
03150 #else
03151 int
03152 ncx_putn_int_long(void **xpp, size_t nelems, const long *tp)
03153 {
03154         char *xp = (char *) *xpp;
03155         int status = ENOERR;
03156 
03157         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03158         {
03159                 int lstatus = ncx_put_int_long(xp, tp);
03160                 if(lstatus != ENOERR)
03161                         status = lstatus;
03162         }
03163 
03164         *xpp = (void *)xp;
03165         return status;
03166 }
03167 
03168 #endif
03169 int
03170 ncx_putn_int_float(void **xpp, size_t nelems, const float *tp)
03171 {
03172         char *xp = (char *) *xpp;
03173         int status = ENOERR;
03174 
03175         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03176         {
03177                 int lstatus = ncx_put_int_float(xp, tp);
03178                 if(lstatus != ENOERR)
03179                         status = lstatus;
03180         }
03181 
03182         *xpp = (void *)xp;
03183         return status;
03184 }
03185 
03186 int
03187 ncx_putn_int_double(void **xpp, size_t nelems, const double *tp)
03188 {
03189         char *xp = (char *) *xpp;
03190         int status = ENOERR;
03191 
03192         for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
03193         {
03194                 int lstatus = ncx_put_int_double(xp, tp);
03195                 if(lstatus != ENOERR)
03196                         status = lstatus;
03197         }
03198 
03199         *xpp = (void *)xp;
03200         return status;
03201 }
03202 
03203 
03204 
03205 /* float */
03206 
03207 int
03208 ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
03209 {
03210         const char *xp = (const char *) *xpp;
03211         int status = ENOERR;
03212 
03213         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03214         {
03215                 const int lstatus = ncx_get_float_schar(xp, tp);
03216                 if(lstatus != ENOERR)
03217                         status = lstatus;
03218         }
03219 
03220         *xpp = (const void *)xp;
03221         return status;
03222 }
03223 
03224 int
03225 ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
03226 {
03227         const char *xp = (const char *) *xpp;
03228         int status = ENOERR;
03229 
03230         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03231         {
03232                 const int lstatus = ncx_get_float_uchar(xp, tp);
03233                 if(lstatus != ENOERR)
03234                         status = lstatus;
03235         }
03236 
03237         *xpp = (const void *)xp;
03238         return status;
03239 }
03240 
03241 int
03242 ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
03243 {
03244         const char *xp = (const char *) *xpp;
03245         int status = ENOERR;
03246 
03247         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03248         {
03249                 const int lstatus = ncx_get_float_short(xp, tp);
03250                 if(lstatus != ENOERR)
03251                         status = lstatus;
03252         }
03253 
03254         *xpp = (const void *)xp;
03255         return status;
03256 }
03257 
03258 int
03259 ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
03260 {
03261         const char *xp = (const char *) *xpp;
03262         int status = ENOERR;
03263 
03264         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03265         {
03266                 const int lstatus = ncx_get_float_int(xp, tp);
03267                 if(lstatus != ENOERR)
03268                         status = lstatus;
03269         }
03270 
03271         *xpp = (const void *)xp;
03272         return status;
03273 }
03274 
03275 int
03276 ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
03277 {
03278         const char *xp = (const char *) *xpp;
03279         int status = ENOERR;
03280 
03281         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03282         {
03283                 const int lstatus = ncx_get_float_long(xp, tp);
03284                 if(lstatus != ENOERR)
03285                         status = lstatus;
03286         }
03287 
03288         *xpp = (const void *)xp;
03289         return status;
03290 }
03291 
03292 #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
03293 /* optimized version */
03294 int
03295 ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
03296 {
03297 # if WORDS_BIGENDIAN
03298         (void) memcpy(tp, *xpp, nelems * sizeof(float));
03299 # else
03300         swapn4b(tp, *xpp, nelems);
03301 # endif
03302         *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
03303         return ENOERR;
03304 }
03305 #elif vax
03306 int
03307 ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
03308 {
03309         float *const end = ip + nfloats;
03310 
03311         while(ip < end)
03312         {
03313                 struct vax_single *const vsp = (struct vax_single *) ip;
03314                 const struct ieee_single *const isp =
03315                          (const struct ieee_single *) (*xpp);
03316                 unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
03317 
03318                 switch(exp) {
03319                 case 0 :
03320                         /* ieee subnormal */
03321                         if(isp->mant_hi == min.ieee.mant_hi
03322                                 && isp->mant_lo_hi == min.ieee.mant_lo_hi
03323                                 && isp->mant_lo_lo == min.ieee.mant_lo_lo)
03324                         {
03325                                 *vsp = min.s;
03326                         }
03327                         else
03328                         {
03329                                 unsigned mantissa = (isp->mant_hi << 16)
03330                                          | isp->mant_lo_hi << 8
03331                                          | isp->mant_lo_lo;
03332                                 unsigned tmp = mantissa >> 20;
03333                                 if(tmp >= 4) {
03334                                         vsp->exp = 2;
03335                                 } else if (tmp >= 2) {
03336                                         vsp->exp = 1;
03337                                 } else {
03338                                         *vsp = min.s;
03339                                         break;
03340                                 } /* else */
03341                                 tmp = mantissa - (1 << (20 + vsp->exp ));
03342                                 tmp <<= 3 - vsp->exp;
03343                                 vsp->mantissa2 = tmp;
03344                                 vsp->mantissa1 = (tmp >> 16);
03345                         }
03346                         break;
03347                 case 0xfe :
03348                 case 0xff :
03349                         *vsp = max.s;
03350                         break;
03351                 default :
03352                         vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
03353                         vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
03354                         vsp->mantissa1 = isp->mant_hi;
03355                 }
03356 
03357                 vsp->sign = isp->sign;
03358 
03359 
03360                 ip++;
03361                 *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
03362         }
03363         return ENOERR;
03364 }
03365 #elif _SX && _FLOAT2
03366 int
03367 ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
03368 {
03369         const char *const xp = *xpp;
03370 
03371         const int ncnv = ie3_fl2(xp, tp, 4, 8, nelems);
03372 
03373         *xpp = xp + nelems * X_SIZEOF_FLOAT;
03374         return (nelems == ncnv ? ENOERR : NC_ERANGE);
03375 }
03376 #else
03377 int
03378 ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
03379 {
03380         const char *xp = *xpp;
03381         int status = ENOERR;
03382 
03383         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03384         {
03385                 const int lstatus = ncx_get_float_float(xp, tp);
03386                 if(lstatus != ENOERR)
03387                         status = lstatus;
03388         }
03389 
03390         *xpp = (const void *)xp;
03391         return status;
03392 }
03393 
03394 #endif
03395 int
03396 ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
03397 {
03398         const char *xp = (const char *) *xpp;
03399         int status = ENOERR;
03400 
03401         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03402         {
03403                 const int lstatus = ncx_get_float_double(xp, tp);
03404                 if(lstatus != ENOERR)
03405                         status = lstatus;
03406         }
03407 
03408         *xpp = (const void *)xp;
03409         return status;
03410 }
03411 
03412 
03413 int
03414 ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp)
03415 {
03416         char *xp = (char *) *xpp;
03417         int status = ENOERR;
03418 
03419         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03420         {
03421                 int lstatus = ncx_put_float_schar(xp, tp);
03422                 if(lstatus != ENOERR)
03423                         status = lstatus;
03424         }
03425 
03426         *xpp = (void *)xp;
03427         return status;
03428 }
03429 
03430 int
03431 ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp)
03432 {
03433         char *xp = (char *) *xpp;
03434         int status = ENOERR;
03435 
03436         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03437         {
03438                 int lstatus = ncx_put_float_uchar(xp, tp);
03439                 if(lstatus != ENOERR)
03440                         status = lstatus;
03441         }
03442 
03443         *xpp = (void *)xp;
03444         return status;
03445 }
03446 
03447 int
03448 ncx_putn_float_short(void **xpp, size_t nelems, const short *tp)
03449 {
03450         char *xp = (char *) *xpp;
03451         int status = ENOERR;
03452 
03453         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03454         {
03455                 int lstatus = ncx_put_float_short(xp, tp);
03456                 if(lstatus != ENOERR)
03457                         status = lstatus;
03458         }
03459 
03460         *xpp = (void *)xp;
03461         return status;
03462 }
03463 
03464 int
03465 ncx_putn_float_int(void **xpp, size_t nelems, const int *tp)
03466 {
03467         char *xp = (char *) *xpp;
03468         int status = ENOERR;
03469 
03470         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03471         {
03472                 int lstatus = ncx_put_float_int(xp, tp);
03473                 if(lstatus != ENOERR)
03474                         status = lstatus;
03475         }
03476 
03477         *xpp = (void *)xp;
03478         return status;
03479 }
03480 
03481 int
03482 ncx_putn_float_long(void **xpp, size_t nelems, const long *tp)
03483 {
03484         char *xp = (char *) *xpp;
03485         int status = ENOERR;
03486 
03487         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03488         {
03489                 int lstatus = ncx_put_float_long(xp, tp);
03490                 if(lstatus != ENOERR)
03491                         status = lstatus;
03492         }
03493 
03494         *xpp = (void *)xp;
03495         return status;
03496 }
03497 
03498 #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
03499 /* optimized version */
03500 int
03501 ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
03502 {
03503 # if WORDS_BIGENDIAN
03504         (void) memcpy(*xpp, tp, nelems * X_SIZEOF_FLOAT);
03505 # else
03506         swapn4b(*xpp, tp, nelems);
03507 # endif
03508         *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
03509         return ENOERR;
03510 }
03511 #elif vax
03512 int
03513 ncx_putn_float_float(void **xpp, size_t nfloats, const float *ip)
03514 {
03515         const float *const end = ip + nfloats;
03516 
03517         while(ip < end)
03518         {
03519                 const struct vax_single *const vsp =
03520                          (const struct vax_single *)ip;
03521                 struct ieee_single *const isp = (struct ieee_single *) (*xpp);
03522 
03523                 switch(vsp->exp){
03524                 case 0 :
03525                         /* all vax float with zero exponent map to zero */
03526                         *isp = min.ieee;
03527                         break;
03528                 case 2 :
03529                 case 1 :
03530                 {
03531                         /* These will map to subnormals */
03532                         unsigned mantissa = (vsp->mantissa1 << 16)
03533                                          | vsp->mantissa2;
03534                         mantissa >>= 3 - vsp->exp;
03535                         mantissa += (1 << (20 + vsp->exp));
03536                         isp->mant_lo_lo = mantissa;
03537                         isp->mant_lo_hi = mantissa >> 8;
03538                         isp->mant_hi = mantissa >> 16;
03539                         isp->exp_lo = 0;
03540                         isp->exp_hi = 0;
03541                 }
03542                         break;
03543                 case 0xff : /* max.s.exp */
03544                         if( vsp->mantissa2 == max.s.mantissa2
03545                                 && vsp->mantissa1 == max.s.mantissa1)
03546                         {
03547                                 /* map largest vax float to ieee infinity */
03548                                 *isp = max.ieee;
03549                                 break;
03550                         } /* else, fall thru */
03551                 default :
03552                 {
03553                         unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
03554                         isp->exp_hi = exp >> 1;
03555                         isp->exp_lo = exp;
03556                         isp->mant_lo_lo = vsp->mantissa2;
03557                         isp->mant_lo_hi = vsp->mantissa2 >> 8;
03558                         isp->mant_hi = vsp->mantissa1;
03559                 }
03560                 }
03561 
03562                 isp->sign = vsp->sign;
03563 
03564         
03565                 ip++;
03566                 *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
03567         }
03568         return ENOERR;
03569 }
03570 #elif _SX && _FLOAT2
03571 int
03572 ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
03573 {
03574         char *const xp = *xpp;
03575 
03576         const int ncnv = fl2_ie3(tp, xp, 8, 4, nelems);
03577 
03578         *xpp = xp + nelems * X_SIZEOF_FLOAT;
03579         return (nelems == ncnv ? ENOERR : NC_ERANGE);
03580 }
03581 #else
03582 int
03583 ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
03584 {
03585         char *xp = *xpp;
03586         int status = ENOERR;
03587 
03588         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03589         {
03590                 int lstatus = ncx_put_float_float(xp, tp);
03591                 if(lstatus != ENOERR)
03592                         status = lstatus;
03593         }
03594 
03595         *xpp = (void *)xp;
03596         return status;
03597 }
03598 
03599 #endif
03600 int
03601 ncx_putn_float_double(void **xpp, size_t nelems, const double *tp)
03602 {
03603         char *xp = (char *) *xpp;
03604         int status = ENOERR;
03605 
03606         for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
03607         {
03608                 int lstatus = ncx_put_float_double(xp, tp);
03609                 if(lstatus != ENOERR)
03610                         status = lstatus;
03611         }
03612 
03613         *xpp = (void *)xp;
03614         return status;
03615 }
03616 
03617 
03618 
03619 /* double */
03620 
03621 int
03622 ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
03623 {
03624         const char *xp = (const char *) *xpp;
03625         int status = ENOERR;
03626 
03627         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03628         {
03629                 const int lstatus = ncx_get_double_schar(xp, tp);
03630                 if(lstatus != ENOERR)
03631                         status = lstatus;
03632         }
03633 
03634         *xpp = (const void *)xp;
03635         return status;
03636 }
03637 
03638 int
03639 ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
03640 {
03641         const char *xp = (const char *) *xpp;
03642         int status = ENOERR;
03643 
03644         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03645         {
03646                 const int lstatus = ncx_get_double_uchar(xp, tp);
03647                 if(lstatus != ENOERR)
03648                         status = lstatus;
03649         }
03650 
03651         *xpp = (const void *)xp;
03652         return status;
03653 }
03654 
03655 int
03656 ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
03657 {
03658         const char *xp = (const char *) *xpp;
03659         int status = ENOERR;
03660 
03661         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03662         {
03663                 const int lstatus = ncx_get_double_short(xp, tp);
03664                 if(lstatus != ENOERR)
03665                         status = lstatus;
03666         }
03667 
03668         *xpp = (const void *)xp;
03669         return status;
03670 }
03671 
03672 int
03673 ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
03674 {
03675         const char *xp = (const char *) *xpp;
03676         int status = ENOERR;
03677 
03678         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03679         {
03680                 const int lstatus = ncx_get_double_int(xp, tp);
03681                 if(lstatus != ENOERR)
03682                         status = lstatus;
03683         }
03684 
03685         *xpp = (const void *)xp;
03686         return status;
03687 }
03688 
03689 int
03690 ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
03691 {
03692         const char *xp = (const char *) *xpp;
03693         int status = ENOERR;
03694 
03695         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03696         {
03697                 const int lstatus = ncx_get_double_long(xp, tp);
03698                 if(lstatus != ENOERR)
03699                         status = lstatus;
03700         }
03701 
03702         *xpp = (const void *)xp;
03703         return status;
03704 }
03705 
03706 int
03707 ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
03708 {
03709         const char *xp = (const char *) *xpp;
03710         int status = ENOERR;
03711 
03712         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03713         {
03714                 const int lstatus = ncx_get_double_float(xp, tp);
03715                 if(lstatus != ENOERR)
03716                         status = lstatus;
03717         }
03718 
03719         *xpp = (const void *)xp;
03720         return status;
03721 }
03722 
03723 #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
03724 /* optimized version */
03725 int
03726 ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
03727 {
03728 # if WORDS_BIGENDIAN
03729         (void) memcpy(tp, *xpp, nelems * sizeof(double));
03730 # else
03731         swapn8b(tp, *xpp, nelems);
03732 # endif
03733         *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
03734         return ENOERR;
03735 }
03736 #elif vax
03737 int
03738 ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
03739 {
03740         double *const end = ip + ndoubles;
03741 
03742         while(ip < end)
03743         {
03744         struct vax_double *const vdp =
03745                          (struct vax_double *)ip;
03746         const struct ieee_double *const idp =
03747                          (const struct ieee_double *) (*xpp);
03748         {
03749                 const struct dbl_limits *lim;
03750                 int ii;
03751                 for (ii = 0, lim = dbl_limits;
03752                         ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
03753                         ii++, lim++)
03754                 {
03755                         if ((idp->mant_lo == lim->ieee.mant_lo)
03756                                 && (idp->mant_4 == lim->ieee.mant_4)
03757                                 && (idp->mant_5 == lim->ieee.mant_5)
03758                                 && (idp->mant_6 == lim->ieee.mant_6)
03759                                 && (idp->exp_lo == lim->ieee.exp_lo)
03760                                 && (idp->exp_hi == lim->ieee.exp_hi)
03761                                 )
03762                         {
03763                                 *vdp = lim->d;
03764                                 goto doneit;
03765                         }
03766                 }
03767         }
03768         {
03769                 unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
03770                 vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
03771         }
03772         {
03773                 unsigned mant_hi = ((idp->mant_6 << 16)
03774                                  | (idp->mant_5 << 8)
03775                                  | idp->mant_4);
03776                 unsigned mant_lo = SWAP4(idp->mant_lo);
03777                 vdp->mantissa1 = (mant_hi >> 13);
03778                 vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
03779                                 | (mant_lo >> 29);
03780                 vdp->mantissa3 = (mant_lo >> 13);
03781                 vdp->mantissa4 = (mant_lo << 3);
03782         }
03783         doneit:
03784                 vdp->sign = idp->sign;
03785 
03786                 ip++;
03787                 *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
03788         }
03789         return ENOERR;
03790 }
03791         /* vax */
03792 #elif _SX && _FLOAT2
03793 int
03794 ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
03795 {
03796         const char *const xp = *xpp;
03797 
03798         const int ncnv = ie3_fl2(xp, tp, 8, 8, nelems);
03799 
03800         *xpp = xp + nelems * X_SIZEOF_DOUBLE;
03801         return (nelems == ncnv ? ENOERR : NC_ERANGE);
03802 }
03803 #else
03804 int
03805 ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
03806 {
03807         const char *xp = *xpp;
03808         int status = ENOERR;
03809 
03810         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03811         {
03812                 const int lstatus = ncx_get_double_double(xp, tp);
03813                 if(lstatus != ENOERR)
03814                         status = lstatus;
03815         }
03816 
03817         *xpp = (const void *)xp;
03818         return status;
03819 }
03820 
03821 #endif
03822 
03823 int
03824 ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp)
03825 {
03826         char *xp = (char *) *xpp;
03827         int status = ENOERR;
03828 
03829         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03830         {
03831                 int lstatus = ncx_put_double_schar(xp, tp);
03832                 if(lstatus != ENOERR)
03833                         status = lstatus;
03834         }
03835 
03836         *xpp = (void *)xp;
03837         return status;
03838 }
03839 
03840 int
03841 ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp)
03842 {
03843         char *xp = (char *) *xpp;
03844         int status = ENOERR;
03845 
03846         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03847         {
03848                 int lstatus = ncx_put_double_uchar(xp, tp);
03849                 if(lstatus != ENOERR)
03850                         status = lstatus;
03851         }
03852 
03853         *xpp = (void *)xp;
03854         return status;
03855 }
03856 
03857 int
03858 ncx_putn_double_short(void **xpp, size_t nelems, const short *tp)
03859 {
03860         char *xp = (char *) *xpp;
03861         int status = ENOERR;
03862 
03863         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03864         {
03865                 int lstatus = ncx_put_double_short(xp, tp);
03866                 if(lstatus != ENOERR)
03867                         status = lstatus;
03868         }
03869 
03870         *xpp = (void *)xp;
03871         return status;
03872 }
03873 
03874 int
03875 ncx_putn_double_int(void **xpp, size_t nelems, const int *tp)
03876 {
03877         char *xp = (char *) *xpp;
03878         int status = ENOERR;
03879 
03880         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03881         {
03882                 int lstatus = ncx_put_double_int(xp, tp);
03883                 if(lstatus != ENOERR)
03884                         status = lstatus;
03885         }
03886 
03887         *xpp = (void *)xp;
03888         return status;
03889 }
03890 
03891 int
03892 ncx_putn_double_long(void **xpp, size_t nelems, const long *tp)
03893 {
03894         char *xp = (char *) *xpp;
03895         int status = ENOERR;
03896 
03897         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03898         {
03899                 int lstatus = ncx_put_double_long(xp, tp);
03900                 if(lstatus != ENOERR)
03901                         status = lstatus;
03902         }
03903 
03904         *xpp = (void *)xp;
03905         return status;
03906 }
03907 
03908 int
03909 ncx_putn_double_float(void **xpp, size_t nelems, const float *tp)
03910 {
03911         char *xp = (char *) *xpp;
03912         int status = ENOERR;
03913 
03914         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
03915         {
03916                 int lstatus = ncx_put_double_float(xp, tp);
03917                 if(lstatus != ENOERR)
03918                         status = lstatus;
03919         }
03920 
03921         *xpp = (void *)xp;
03922         return status;
03923 }
03924 
03925 #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
03926 /* optimized version */
03927 int
03928 ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
03929 {
03930 # if WORDS_BIGENDIAN
03931         (void) memcpy(*xpp, tp, nelems * X_SIZEOF_DOUBLE);
03932 # else
03933         swapn8b(*xpp, tp, nelems);
03934 # endif
03935         *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
03936         return ENOERR;
03937 }
03938 #elif vax
03939 int
03940 ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip)
03941 {
03942         const double *const end = ip + ndoubles;
03943 
03944         while(ip < end)
03945         {
03946         const struct vax_double *const vdp = 
03947                         (const struct vax_double *)ip;
03948         struct ieee_double *const idp =
03949                          (struct ieee_double *) (*xpp);
03950 
03951         if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
03952                 (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
03953                 (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
03954                 (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
03955                 (vdp->exp == dbl_limits[0].d.exp))
03956         {
03957                 *idp = dbl_limits[0].ieee;
03958                 goto shipit;
03959         }
03960         if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
03961                 (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
03962                 (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
03963                 (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
03964                 (vdp->exp == dbl_limits[1].d.exp))
03965         {
03966                 *idp = dbl_limits[1].ieee;
03967                 goto shipit;
03968         }
03969 
03970         {
03971                 unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
03972 
03973                 unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
03974                         (vdp->mantissa3 << 13) |
03975                         ((vdp->mantissa4 >> 3) & MASK(13));
03976 
03977                 unsigned mant_hi = (vdp->mantissa1 << 13)
03978                                  | (vdp->mantissa2 >> 3);
03979 
03980                 if((vdp->mantissa4 & 7) > 4)
03981                 {
03982                         /* round up */
03983                         mant_lo++;
03984                         if(mant_lo == 0)
03985                         {
03986                                 mant_hi++;
03987                                 if(mant_hi > 0xffffff)
03988                                 {
03989                                         mant_hi = 0;
03990                                         exp++;
03991                                 }
03992                         }
03993                 }
03994 
03995                 idp->mant_lo = SWAP4(mant_lo);
03996                 idp->mant_6 = mant_hi >> 16;
03997                 idp->mant_5 = (mant_hi & 0xff00) >> 8;
03998                 idp->mant_4 = mant_hi;
03999                 idp->exp_hi = exp >> 4;
04000                 idp->exp_lo = exp;
04001         }
04002                 
04003         shipit:
04004                 idp->sign = vdp->sign;
04005 
04006                 ip++;
04007                 *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
04008         }
04009         return ENOERR;
04010 }
04011         /* vax */
04012 #elif _SX && _FLOAT2
04013 int
04014 ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
04015 {
04016         char *const xp = *xpp;
04017 
04018         const int ncnv = fl2_ie3(tp, xp, 8, 8, nelems);
04019 
04020         *xpp = xp + nelems * X_SIZEOF_DOUBLE;
04021         return (nelems == ncnv ? ENOERR : NC_ERANGE);
04022 }
04023 #else
04024 int
04025 ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
04026 {
04027         char *xp = *xpp;
04028         int status = ENOERR;
04029 
04030         for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
04031         {
04032                 int lstatus = ncx_put_double_double(xp, tp);
04033                 if(lstatus != ENOERR)
04034                         status = lstatus;
04035         }
04036 
04037         *xpp = (void *)xp;
04038         return status;
04039 }
04040 
04041 #endif
04042 
04043 
04044 /*
04045  * Other aggregate conversion functions.
04046  */
04047 
04048 /* text */
04049 
04050 int
04051 ncx_getn_text(const void **xpp, size_t nelems, char *tp)
04052 {
04053         (void) memcpy(tp, *xpp, nelems);
04054         *xpp = (void *)((char *)(*xpp) + nelems);
04055         return ENOERR;
04056 
04057 }
04058 
04059 int
04060 ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
04061 {
04062         size_t rndup = nelems % X_ALIGN;
04063 
04064         if(rndup)
04065                 rndup = X_ALIGN - rndup;
04066 
04067         (void) memcpy(tp, *xpp, nelems);
04068         *xpp = (void *)((char *)(*xpp) + nelems + rndup);
04069 
04070         return ENOERR;
04071 
04072 }
04073 
04074 int
04075 ncx_putn_text(void **xpp, size_t nelems, const char *tp)
04076 {
04077         (void) memcpy(*xpp, tp, nelems);
04078         *xpp = (void *)((char *)(*xpp) + nelems);
04079 
04080         return ENOERR;
04081 
04082 }
04083 
04084 int
04085 ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
04086 {
04087         size_t rndup = nelems % X_ALIGN;
04088 
04089         if(rndup)
04090                 rndup = X_ALIGN - rndup;
04091 
04092         (void) memcpy(*xpp, tp, nelems);
04093         *xpp = (void *)((char *)(*xpp) + nelems);
04094 
04095         if(rndup)
04096         {
04097                 (void) memcpy(*xpp, nada, rndup);
04098                 *xpp = (void *)((char *)(*xpp) + rndup);
04099         }
04100         
04101         return ENOERR;
04102 
04103 }
04104 
04105 
04106 /* opaque */
04107 
04108 int
04109 ncx_getn_void(const void **xpp, size_t nelems, void *tp)
04110 {
04111         (void) memcpy(tp, *xpp, nelems);
04112         *xpp = (void *)((char *)(*xpp) + nelems);
04113         return ENOERR;
04114 
04115 }
04116 
04117 int
04118 ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
04119 {
04120         size_t rndup = nelems % X_ALIGN;
04121 
04122         if(rndup)
04123                 rndup = X_ALIGN - rndup;
04124 
04125         (void) memcpy(tp, *xpp, nelems);
04126         *xpp = (void *)((char *)(*xpp) + nelems + rndup);
04127 
04128         return ENOERR;
04129 
04130 }
04131 
04132 int
04133 ncx_putn_void(void **xpp, size_t nelems, const void *tp)
04134 {
04135         (void) memcpy(*xpp, tp, nelems);
04136         *xpp = (void *)((char *)(*xpp) + nelems);
04137 
04138         return ENOERR;
04139 
04140 }
04141 
04142 int
04143 ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
04144 {
04145         size_t rndup = nelems % X_ALIGN;
04146 
04147         if(rndup)
04148                 rndup = X_ALIGN - rndup;
04149 
04150         (void) memcpy(*xpp, tp, nelems);
04151         *xpp = (void *)((char *)(*xpp) + nelems);
04152 
04153         if(rndup)
04154         {
04155                 (void) memcpy(*xpp, nada, rndup);
04156                 *xpp = (void *)((char *)(*xpp) + rndup);
04157         }
04158         
04159         return ENOERR;
04160 
04161 }
 

Powered by Plone

This site conforms to the following standards: