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

Generated on Thu Mar 16 18:10:09 2006 for nco by  doxygen 1.4.4