dnl Process this m4 file to produce 'C' language file. dnl dnl This file is supposed to be the same as PnetCDF's ncx.m4 dnl dnl If you see this line, you can ignore the next one. /* Do not edit this file. It is produced from the corresponding .m4 source */ dnl /* * Copyright (C) 2014, Northwestern University and Argonne National Laboratory * See COPYRIGHT notice in top-level directory. */ /* $Id: ncx.m4 2601 2016-11-07 04:54:42Z wkliao $ */ #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wunused-parameter" #endif dnl dnl If "ERANGE_FILL" is defined, the data elements that cause NC_ERANGE will dnl be filled with the NC default fill values. dnl define(`SKIP_LOOP', ` #ifdef ERANGE_FILL $1++; $2++; continue; #endif') dnl dnl The command-line m4 macro "PNETCDF" is to differentiate PnetCDF and netCDF dnl in terms of function prefix names (ncmpi_ vs. nc_), integer data types dnl (MPI_Offset vs. size_t), and function name substrings for external data dnl types. dnl ifdef(`PNETCDF',` `#'if HAVE_CONFIG_H `#'include `#'endif',` `#'if HAVE_CONFIG_H `#'include `#'endif') #include #include #include #include ifdef(`PNETCDF',` `#'include "ncx.h" `#'include "macro.h"',` `#'pragma GCC diagnostic ignored "-Wdeprecated" `#'include "ncx.h" `#'include "nc3dispatch.h"') define(`IntType', `ifdef(`PNETCDF', `MPI_Offset', `size_t')')dnl define(`APIPrefix',`ifdef(`PNETCDF', `ncmpi', `nc')')dnl define(`NC_TYPE', `ifdef(`PNETCDF', `ifelse( `$1', `schar', `NC_BYTE',dnl `$1', `uchar', `NC_UBYTE',dnl `$1', `short', `NC_SHORT',dnl `$1', `ushort', `NC_USHORT',dnl `$1', `int', `NC_INT',dnl `$1', `uint', `NC_UINT',dnl `$1', `float', `NC_FLOAT',dnl `$1', `double', `NC_DOUBLE',dnl `$1', `int64', `NC_INT64',dnl `$1', `uint64', `NC_UINT64')',dnl `ifelse( `$1', `int64', `longlong',dnl `$1', `uint64', `ulonglong',dnl `$1')')')dnl ifdef(`PNETCDF',,`define(`DEBUG_RETURN_ERROR',`return $1;')') ifdef(`PNETCDF',,`define(`DEBUG_ASSIGN_ERROR',`$1 = $2;')') #ifdef HAVE_INTTYPES_H #include /* uint16_t, uint32_t, uint64_t */ #elif defined(HAVE_STDINT_H) #include /* uint16_t, uint32_t, uint64_t */ #endif dnl dnl *fillp is the fill value in internal representation dnl define(`FillValue', ` #ifdef ERANGE_FILL ifelse( `$1', `schar', `if (fillp != NULL) memcpy($2, fillp, 1);',dnl `$1', `uchar', `if (fillp != NULL) memcpy($2, fillp, 1);',dnl `$1', `short', `if (fillp != NULL) memcpy($2, fillp, 2);',dnl `$1', `ushort', `if (fillp != NULL) memcpy($2, fillp, 2);',dnl `$1', `int', `if (fillp != NULL) memcpy($2, fillp, 4);',dnl `$1', `uint', `if (fillp != NULL) memcpy($2, fillp, 4);',dnl `$1', `long', `if (fillp != NULL) memcpy($2, fillp, SIZEOF_LONG);', dnl `$1', `ulong', `if (fillp != NULL) memcpy($2, fillp, SIZEOF_ULONG);',dnl `$1', `float', `if (fillp != NULL) memcpy($2, fillp, 4);',dnl `$1', `double', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl `$1', `longlong', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl `$1', `int64', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl `$1', `ulonglong', `if (fillp != NULL) memcpy($2, fillp, 8);',dnl `$1', `uint64', `if (fillp != NULL) memcpy($2, fillp, 8);') #endif')dnl dnl dnl define(`FillDefaultValue', `ifelse( `$1', `schar', `NC_FILL_BYTE', `$1', `uchar', `NC_FILL_UBYTE', `$1', `short', `NC_FILL_SHORT', `$1', `ushort', `NC_FILL_USHORT', `$1', `int', `NC_FILL_INT', `$1', `uint', `NC_FILL_UINT', `$1', `long', `NC_FILL_INT', `$1', `ulong', `NC_FILL_UINT', `$1', `float', `NC_FILL_FLOAT', `$1', `double', `NC_FILL_DOUBLE', `$1', `longlong', `NC_FILL_INT64', `$1', `int64', `NC_FILL_INT64', `$1', `ulonglong', `NC_FILL_UINT64', `$1', `uint64', `NC_FILL_UINT64')')dnl /* * The only error code returned from subroutines in this file is NC_ERANGE, * if errors are detected. */ /* * An external data representation interface. */ /* alias poorly named limits.h macros */ #define SHORT_MAX SHRT_MAX #define SHORT_MIN SHRT_MIN #define USHORT_MAX USHRT_MAX #ifndef LLONG_MAX # define LLONG_MAX 9223372036854775807LL # define LLONG_MIN (-LLONG_MAX - 1LL) # define ULLONG_MAX 18446744073709551615ULL #endif #ifndef LONG_LONG_MAX #define LONG_LONG_MAX LLONG_MAX #endif #ifndef LONGLONG_MAX #define LONGLONG_MAX LONG_LONG_MAX #endif #ifndef LONG_LONG_MIN #define LONG_LONG_MIN LLONG_MIN #endif #ifndef LONGLONG_MIN #define LONGLONG_MIN LONG_LONG_MIN #endif #ifndef ULONG_LONG_MAX #define ULONG_LONG_MAX ULLONG_MAX #endif #ifndef ULONGLONG_MAX #define ULONGLONG_MAX ULONG_LONG_MAX #endif #include #ifndef FLT_MAX /* This POSIX macro missing on some systems */ # ifndef NO_IEEE_FLOAT # define FLT_MAX 3.40282347e+38f # else # error "You will need to define FLT_MAX" # endif #endif /* alias poorly named float.h macros */ #define FLOAT_MAX FLT_MAX #define FLOAT_MIN (-FLT_MAX) #define DOUBLE_MAX DBL_MAX #define DOUBLE_MIN (-DBL_MAX) #define FLOAT_MAX_EXP FLT_MAX_EXP #define DOUBLE_MAX_EXP DBL_MAX_EXP #include #define UCHAR_MIN 0 #define Min(a,b) ((a) < (b) ? (a) : (b)) #define Max(a,b) ((a) > (b) ? (a) : (b)) #ifndef SIZEOF_UCHAR #ifdef SIZEOF_UNSIGNED_CHAR #define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR #else #error "unknown SIZEOF_UCHAR" #endif #endif #ifndef SIZEOF_USHORT #ifdef SIZEOF_UNSIGNED_SHORT_INT #define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT #elif defined(SIZEOF_UNSIGNED_SHORT) #define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT #else #error "unknown SIZEOF_USHORT" #endif #endif #ifndef SIZEOF_UINT #ifdef SIZEOF_UNSIGNED_INT #define SIZEOF_UINT SIZEOF_UNSIGNED_INT #else #error "unknown SIZEOF_UINT" #endif #endif #ifndef SIZEOF_LONGLONG #ifdef SIZEOF_LONG_LONG #define SIZEOF_LONGLONG SIZEOF_LONG_LONG #else #error "unknown SIZEOF_LONGLONG" #endif #endif #ifndef SIZEOF_INT64 #ifdef SIZEOF_LONG_LONG #define SIZEOF_INT64 SIZEOF_LONG_LONG #elif defined(SIZEOF_LONGLONG) #define SIZEOF_INT64 SIZEOF_LONGLONG #else #error "unknown SIZEOF_INT64" #endif #endif #ifndef SIZEOF_ULONGLONG #ifdef SIZEOF_UNSIGNED_LONG_LONG #define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG #else #error "unknown SIZEOF_ULONGLONG" #endif #endif #ifndef SIZEOF_UINT64 #ifdef SIZEOF_UNSIGNED_LONG_LONG #define SIZEOF_UINT64 SIZEOF_UNSIGNED_LONG_LONG #elif defined(SIZEOF_ULONGLONG) #define SIZEOF_UINT64 SIZEOF_ULONGLONG #else #error "unknown SIZEOF_UINT64" #endif #endif /* * If the machine's float domain is "smaller" than the external one * use the machine domain */ #if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */ #undef X_FLOAT_MAX # define X_FLOAT_MAX FLT_MAX #undef X_FLOAT_MIN # define X_FLOAT_MIN (-X_FLOAT_MAX) #endif #if defined(_SX) && _SX != 0 /* NEC SUPER UX */ #define LOOPCNT 256 /* must be no longer than hardware vector length */ #if _INT64 #undef INT_MAX /* workaround cpp bug */ #define INT_MAX X_INT_MAX #undef INT_MIN /* workaround cpp bug */ #define INT_MIN X_INT_MIN #undef LONG_MAX /* workaround cpp bug */ #define LONG_MAX X_INT_MAX #undef LONG_MIN /* workaround cpp bug */ #define LONG_MIN X_INT_MIN #elif _LONG64 #undef LONG_MAX /* workaround cpp bug */ #define LONG_MAX 4294967295L #undef LONG_MIN /* workaround cpp bug */ #define LONG_MIN -4294967295L #endif #if !_FLOAT0 #error "FLOAT1 and FLOAT2 not supported" #endif #endif /* _SX */ static const char nada[X_ALIGN] = {0, 0, 0, 0}; #ifndef WORDS_BIGENDIAN /* LITTLE_ENDIAN: DEC and intel */ /* * Routines to convert to BIG ENDIAN. * Optimize the swapn?b() and swap?b() routines aggressively. */ #define SWAP2(a) ( (((a) & 0xff) << 8) | \ (((a) >> 8) & 0xff) ) #define SWAP4(a) ( ((a) << 24) | \ (((a) << 8) & 0x00ff0000) | \ (((a) >> 8) & 0x0000ff00) | \ (((a) >> 24) & 0x000000ff) ) #define SWAP8(a) ( (((a) & 0x00000000000000FFULL) << 56) | \ (((a) & 0x000000000000FF00ULL) << 40) | \ (((a) & 0x0000000000FF0000ULL) << 24) | \ (((a) & 0x00000000FF000000ULL) << 8) | \ (((a) & 0x000000FF00000000ULL) >> 8) | \ (((a) & 0x0000FF0000000000ULL) >> 24) | \ (((a) & 0x00FF000000000000ULL) >> 40) | \ (((a) & 0xFF00000000000000ULL) >> 56) ) #if defined(_MSC_VER) && _MSC_VER < 1900 #define inline __inline #endif inline static void swapn2b(void *dst, const void *src, IntType nn) { /* it is OK if dst == src */ int i; uint16_t *op = (uint16_t*) dst; uint16_t *ip = (uint16_t*) src; for (i=0; i 0) * { * *op++ = *(++ip); * *op++ = *(ip++ -1); * } */ while (nn > 3) { *op++ = *(++ip); *op++ = *(ip++ -1); *op++ = *(++ip); *op++ = *(ip++ -1); *op++ = *(++ip); *op++ = *(ip++ -1); *op++ = *(++ip); *op++ = *(ip++ -1); nn -= 4; } while (nn-- > 0) { *op++ = *(++ip); *op++ = *(ip++ -1); } #endif } # ifndef vax inline static void swap4b(void *dst, const void *src) { /* copy over, make the below swap in-place */ uint32_t tmp = *(uint32_t*)src; tmp = SWAP4(tmp); memcpy(dst, &tmp, 4); /* Codes below will cause "break strict-aliasing rules" in gcc uint32_t *op = (uint32_t*)dst; *op = *(uint32_t*)src; *op = SWAP4(*op); */ /* Below are copied from netCDF-4. * See https://bugtracking.unidata.ucar.edu/browse/NCF-338 * Quote "One issue we are wrestling with is how compilers optimize this * code. For some reason, we are actually needing to add an artificial * move to a 4 byte space to get it to work. I think what is happening is * that the optimizer is bit shifting within a double, which is incorrect. * The following code actually does work correctly. * This is in Linux land, gcc. * * However, the above in-place byte-swap does not appear affected by this. */ #if 0 uint32_t *ip = (uint32_t*)src; uint32_t tempOut; /* cannot use pointer when gcc O2 optimizer is used */ tempOut = SWAP4(*ip); *(float *)dst = *(float *)(&tempOut); #endif /* OLD implementation that results in four load and four store CPU instructions char *op = dst; const char *ip = src; op[0] = ip[3]; op[1] = ip[2]; op[2] = ip[1]; op[3] = ip[0]; */ } # endif /* !vax */ inline static void swapn4b(void *dst, const void *src, IntType nn) { int i; uint32_t *op = (uint32_t*) dst; uint32_t *ip = (uint32_t*) src; for (i=0; i 0) * { * op[0] = ip[3]; * op[1] = ip[2]; * op[2] = ip[1]; * op[3] = ip[0]; * op += 4; * ip += 4; * } */ while (nn > 3) { op[0] = ip[3]; op[1] = ip[2]; op[2] = ip[1]; op[3] = ip[0]; op[4] = ip[7]; op[5] = ip[6]; op[6] = ip[5]; op[7] = ip[4]; op[8] = ip[11]; op[9] = ip[10]; op[10] = ip[9]; op[11] = ip[8]; op[12] = ip[15]; op[13] = ip[14]; op[14] = ip[13]; op[15] = ip[12]; op += 16; ip += 16; nn -= 4; } while (nn-- > 0) { op[0] = ip[3]; op[1] = ip[2]; op[2] = ip[1]; op[3] = ip[0]; op += 4; ip += 4; } #endif } # ifndef vax inline static void swap8b(void *dst, const void *src) { #ifdef FLOAT_WORDS_BIGENDIAN /* copy over, make the below swap in-place */ *(uint64_t*)dst = *(uint64_t*)src; uint32_t *op = (uint32_t*)dst; *op = SWAP4(*op); op = (uint32_t*)((char*)dst+4); *op = SWAP4(*op); #else uint64_t tmp = *(uint64_t*)src; tmp = SWAP8(tmp); memcpy(dst, &tmp, 8); /* Codes below will cause "break strict-aliasing rules" in gcc uint64_t *op = (uint64_t*)dst; *op = *(uint64_t*)src; *op = SWAP8(*op); */ #endif #if 0 char *op = dst; const char *ip = src; # ifndef FLOAT_WORDS_BIGENDIAN op[0] = ip[7]; op[1] = ip[6]; op[2] = ip[5]; op[3] = ip[4]; op[4] = ip[3]; op[5] = ip[2]; op[6] = ip[1]; op[7] = ip[0]; # else op[0] = ip[3]; op[1] = ip[2]; op[2] = ip[1]; op[3] = ip[0]; op[4] = ip[7]; op[5] = ip[6]; op[6] = ip[5]; op[7] = ip[4]; #endif #endif } # endif /* !vax */ # ifndef vax inline static void swapn8b(void *dst, const void *src, IntType nn) { #ifdef FLOAT_WORDS_BIGENDIAN int i; uint64_t *dst_p = (uint64_t*) dst; uint64_t *src_p = (uint64_t*) src; for (i=0; i 0) * { * op[0] = ip[7]; * op[1] = ip[6]; * op[2] = ip[5]; * op[3] = ip[4]; * op[4] = ip[3]; * op[5] = ip[2]; * op[6] = ip[1]; * op[7] = ip[0]; * op += 8; * ip += 8; * } */ # ifndef FLOAT_WORDS_BIGENDIAN while (nn > 1) { op[0] = ip[7]; op[1] = ip[6]; op[2] = ip[5]; op[3] = ip[4]; op[4] = ip[3]; op[5] = ip[2]; op[6] = ip[1]; op[7] = ip[0]; op[8] = ip[15]; op[9] = ip[14]; op[10] = ip[13]; op[11] = ip[12]; op[12] = ip[11]; op[13] = ip[10]; op[14] = ip[9]; op[15] = ip[8]; op += 16; ip += 16; nn -= 2; } while (nn-- > 0) { op[0] = ip[7]; op[1] = ip[6]; op[2] = ip[5]; op[3] = ip[4]; op[4] = ip[3]; op[5] = ip[2]; op[6] = ip[1]; op[7] = ip[0]; op += 8; ip += 8; } # else while (nn-- > 0) { op[0] = ip[3]; op[1] = ip[2]; op[2] = ip[1]; op[3] = ip[0]; op[4] = ip[7]; op[5] = ip[6]; op[6] = ip[5]; op[7] = ip[4]; op += 8; ip += 8; } #endif #endif } # endif /* !vax */ #endif /* LITTLE_ENDIAN */ dnl dnl dnl dnl dnl Upcase(str) dnl define(`Upcase',dnl `dnl translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl dnl dnl dnl dnl dnl define(`Isizeof', ``SIZEOF_'Upcase($1)')dnl define(`Xsizeof', ``X_SIZEOF_'Upcase($1)')dnl define(`IXsizeof', ``SIZEOF_IX_'Upcase($1)')dnl define(`Imax', `Upcase($1)`_MAX'')dnl define(`Imin', `Upcase($1)`_MIN'')dnl define(`Xmax', ``X_'Upcase($1)`_MAX'')dnl define(`Xmin', ``X_'Upcase($1)`_MIN'')dnl define(`IXmax', ``IX_'Upcase($1)`_MAX'')dnl dnl define(`Fmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl define(`Dmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl define(`FXmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Xmin($1)')')dnl define(`DXmin', `ifelse(index(`$1',`u'), 0, `0', `Xmin($1)')')dnl define(`Cast_Signed2Unsigned', `ifelse(index(`$1',`u'), 0, `ifelse(index(`$2',`u'), 0, , `(signed)')')')dnl dnl dnl For GET APIs boundary check dnl define(`GETF_CheckBND', `if (xx > (double)Upcase($1)_MAX || xx < Dmin($1)) { #ifdef ERANGE_FILL *ip = FillDefaultValue($1); #endif DEBUG_RETURN_ERROR(NC_ERANGE) } *ip = ($1)xx;')dnl dnl dnl For GET APIs boudnary check for when $1 is either 'longlong' or 'ulonglong' dnl define(`GETF_CheckBND2', `ifelse(index(`$1',`u'), 0, `if (xx == Upcase($1)_MAX) *ip = Upcase($1)_MAX;',dnl for unsigned type `if (xx == Upcase($1)_MAX) *ip = Upcase($1)_MAX; else if (xx == Upcase($1)_MIN) *ip = Upcase($1)_MIN;') else if (xx > (double)Upcase($1)_MAX || xx < Dmin($1)) { #ifdef ERANGE_FILL *ip = FillDefaultValue($1); #endif DEBUG_RETURN_ERROR(NC_ERANGE) } else *ip = ($1)xx;') /* * Primitive numeric conversion functions. */ dnl dnl dnl dnl dnl NCX_GET1F(xtype, itype) for floating-point types dnl define(`NCX_GET1F',dnl `dnl static int APIPrefix`x_get_'NC_TYPE($1)_$2(const void *xp, $2 *ip) { ix_$1 xx = 0; get_ix_$1(xp, &xx); ifelse(`$1', `float', `ifelse(`$2', `longlong', GETF_CheckBND2($2), `$2', `ulonglong', GETF_CheckBND2($2), `$2', `double', `*ip = ($2)xx;', GETF_CheckBND($2))', `$1', `double', `ifelse(`$2', `longlong', GETF_CheckBND2($2), `$2', `ulonglong', GETF_CheckBND2($2), GETF_CheckBND($2))', `*ip = ($2)xx;') return NC_NOERR; } ')dnl dnl dnl dnl dnl dnl NCX_GET1I(xtype, itype, isComptable) for integral types dnl define(`NCX_GET1I',dnl `dnl static int APIPrefix`x_get_'NC_TYPE($1)_$2(const void *xp, $2 *ip) { int err=NC_NOERR; ifelse(`$3', `1', ``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX get_ix_$1(xp, (ix_$1 *)ip); `#'else ')dnl ix_$1 xx = 0; get_ix_$1(xp, &xx); `#'if IXmax($1) > Imax($2) if (xx > Imax($2)'`ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, , ` || xx < Imin($2)')'`) { #ifdef ERANGE_FILL *ip = FillDefaultValue($2); DEBUG_RETURN_ERROR(NC_ERANGE) #else DEBUG_ASSIGN_ERROR(err, NC_ERANGE) #endif }' `#'endif `ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0,`dnl if (xx < 0) { #ifdef ERANGE_FILL *ip = FillDefaultValue($2); DEBUG_RETURN_ERROR(NC_ERANGE) #else DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because ip is unsigned */ #endif }')'dnl *ip = ($2) xx; `ifelse(`$3', `1', ``#'endif ')dnl return err; } ')dnl dnl dnl dnl dnl dnl NCX_PUT1F(xtype, itype) for floating-point types dnl define(`NCX_PUT1F',dnl `dnl static int APIPrefix`x_put_'NC_TYPE($1)_$2(void *xp, const $2 *ip, void *fillp) { int err=NC_NOERR; ix_$1 xx = FillDefaultValue($1); ifelse(`$2', `double', `if (*ip > Xmax($1) || *ip < DXmin($1)) { FillValue($1, &xx) DEBUG_ASSIGN_ERROR(err, NC_ERANGE) } #ifdef ERANGE_FILL else #endif', `$2', `float', `if (*ip > (double)Xmax($1) || *ip < FXmin($1)) { FillValue($1, &xx) DEBUG_ASSIGN_ERROR(err, NC_ERANGE) } #ifdef ERANGE_FILL else #endif') xx = (ix_$1)*ip; put_ix_$1(xp, &xx); return err; } ')dnl dnl dnl dnl dnl dnl NCX_PUT1I(xtype, itype, isComptable) for integral types dnl define(`NCX_PUT1I',dnl `dnl static int APIPrefix`x_put_'NC_TYPE($1)_$2(void *xp, const $2 *ip, void *fillp) { int err=NC_NOERR; ifelse(`$3', `1', ``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX put_ix_$1(xp, (const ix_$1 *)ip); `#'else ')dnl ix_$1 xx = FillDefaultValue($1); `#'if IXmax($1) < Imax($2) if (*ip > IXmax($1)'`ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, , ` || *ip < Xmin($1)')'`) { FillValue($1, &xx) DEBUG_ASSIGN_ERROR(err, NC_ERANGE) } #ifdef ERANGE_FILL else #endif `#'endif ifelse(index(`$1',`u'), 0, `ifelse(index(`$2',`u'), 0, ,`dnl if (*ip < 0) { FillValue($1, &xx) DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */ } #ifdef ERANGE_FILL else #endif ')')dnl xx = (ix_$1)*ip; put_ix_$1(xp, &xx); ifelse(`$3', `1', ``#'endif ')dnl return err; } ')dnl /* x_schar */ /* x_uchar */ /* We don't implement any x_schar and x_uchar primitives. */ /* external NC_SHORT --------------------------------------------------------*/ #if SHORT_MAX == X_SHORT_MAX typedef short ix_short; #define SIZEOF_IX_SHORT SIZEOF_SHORT #define IX_SHORT_MAX SHORT_MAX #elif INT_MAX >= X_SHORT_MAX typedef int ix_short; #define SIZEOF_IX_SHORT SIZEOF_INT #define IX_SHORT_MAX INT_MAX #elif LONG_MAX >= X_SHORT_MAX typedef long ix_short; #define SIZEOF_IX_SHORT SIZEOF_LONG #define IX_SHORT_MAX LONG_MAX #elif LLONG_MAX >= X_SHORT_MAX typedef long long ix_short; #define SIZEOF_IX_SHORT SIZEOF_LONGLONG #define IX_SHORT_MAX LLONG_MAX #else #error "ix_short implementation" #endif static void get_ix_short(const void *xp, ix_short *ip) { const uchar *cp = (const uchar *) xp; *ip = (ix_short)(*cp++ << 8); #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT if (*ip & 0x8000) { /* extern is negative */ *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */ } #endif *ip = (ix_short)(*ip | *cp); } static void put_ix_short(void *xp, const ix_short *ip) { uchar *cp = (uchar *) xp; *cp++ = (uchar)((*ip) >> 8); *cp = (uchar)((*ip) & 0xff); } NCX_GET1I(short, schar, 0) NCX_GET1I(short, short, 1) NCX_GET1I(short, int, 1) NCX_GET1I(short, long, 1) NCX_GET1I(short, longlong, 1) NCX_GET1I(short, ushort, 0) NCX_GET1I(short, uchar, 0) NCX_GET1I(short, uint, 0) NCX_GET1I(short, ulonglong, 0) NCX_GET1F(short, float) NCX_GET1F(short, double) static int APIPrefix`x_put_'NC_TYPE(short)_schar(void *xp, const schar *ip, void *fillp) { uchar *cp = (uchar *) xp; if (*ip & 0x80) *cp++ = 0xff; else *cp++ = 0; *cp = (uchar)*ip; return NC_NOERR; } static int APIPrefix`x_put_'NC_TYPE(short)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0; *cp = *ip; return NC_NOERR; } NCX_PUT1I(short, short, 1) NCX_PUT1I(short, int, 1) NCX_PUT1I(short, long, 1) NCX_PUT1I(short, longlong, 1) NCX_PUT1I(short, ushort, 0) NCX_PUT1I(short, uint, 0) NCX_PUT1I(short, ulonglong, 0) NCX_PUT1F(short, float) NCX_PUT1F(short, double) /* external NC_USHORT -------------------------------------------------------*/ #if USHORT_MAX == X_USHORT_MAX typedef unsigned short ix_ushort; #define SIZEOF_IX_USHORT SIZEOF_USHORT #define IX_USHORT_MAX USHORT_MAX #elif UINT_MAX >= X_USHORT_MAX typedef unsigned int ix_ushort; #define SIZEOF_IX_USHORT SIZEOF_UINT #define IX_USHORT_MAX UINT_MAX #elif ULONG_MAX >= X_USHORT_MAX typedef unsigned long ix_ushort; #define SIZEOF_IX_USHORT SIZEOF_ULONG #define IX_USHORT_MAX ULONG_MAX #elif ULLONG_MAX >= X_USHORT_MAX typedef unsigned long long ix_ushort; #define SIZEOF_IX_USHORT SIZEOF_ULONGLONG #define IX_USHORT_MAX ULLONG_MAX #else #error "ix_ushort implementation" #endif static void get_ix_ushort(const void *xp, ix_ushort *ip) { const uchar *cp = (const uchar *) xp; *ip = (ix_ushort)(*cp++ << 8); #if SIZEOF_IX_SHORT > X_SIZEOF_SHORT if (*ip & 0x8000) { /* extern is negative */ *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */ } #endif *ip = (ix_ushort)(*ip | *cp); } static void put_ix_ushort(void *xp, const ix_ushort *ip) { uchar *cp = (uchar *) xp; *cp++ = (uchar)((*ip) >> 8); *cp = (uchar)((*ip) & 0xff); } NCX_GET1I(ushort, schar, 0) NCX_GET1I(ushort, short, 0) NCX_GET1I(ushort, int, 0) NCX_GET1I(ushort, long, 0) NCX_GET1I(ushort, longlong, 0) NCX_GET1I(ushort, ushort, 1) NCX_GET1I(ushort, uchar, 1) NCX_GET1I(ushort, uint, 1) NCX_GET1I(ushort, ulonglong, 1) NCX_GET1F(ushort, float) NCX_GET1F(ushort, double) static int APIPrefix`x_put_'NC_TYPE(ushort)_schar(void *xp, const schar *ip, void *fillp) { int err=NC_NOERR; uchar *cp; if (*ip < 0) { #ifdef ERANGE_FILL if (fillp != NULL) memcpy(xp, fillp, 2); #ifndef WORDS_BIGENDIAN swapn2b(xp, xp, 1); #endif DEBUG_RETURN_ERROR(NC_ERANGE) #else DEBUG_ASSIGN_ERROR(err, NC_ERANGE) #endif } cp = (uchar *) xp; if (*ip & 0x80) *cp++ = 0xff; else *cp++ = 0; *cp = (uchar)*ip; return err; } static int APIPrefix`x_put_'NC_TYPE(ushort)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0; *cp = *ip; return NC_NOERR; } NCX_PUT1I(ushort, short, 0) NCX_PUT1I(ushort, int, 0) NCX_PUT1I(ushort, long, 0) NCX_PUT1I(ushort, longlong, 0) NCX_PUT1I(ushort, ushort, 1) NCX_PUT1I(ushort, uint, 1) NCX_PUT1I(ushort, ulonglong, 1) NCX_PUT1F(ushort, float) NCX_PUT1F(ushort, double) /* external NC_INT ----------------------------------------------------------*/ #if SHORT_MAX == X_INT_MAX typedef short ix_int; #define SIZEOF_IX_INT SIZEOF_SHORT #define IX_INT_MAX SHORT_MAX #elif INT_MAX >= X_INT_MAX typedef int ix_int; #define SIZEOF_IX_INT SIZEOF_INT #define IX_INT_MAX INT_MAX #elif LONG_MAX >= X_INT_MAX typedef long ix_int; #define SIZEOF_IX_INT SIZEOF_LONG #define IX_INT_MAX LONG_MAX #else #error "ix_int implementation" #endif static void get_ix_int(const void *xp, ix_int *ip) { const uchar *cp = (const uchar *) xp; #if INT_MAX >= X_INT_MAX *ip = (ix_int)((unsigned)(*cp++) << 24); #else *ip = *cp++ << 24; #endif #if SIZEOF_IX_INT > X_SIZEOF_INT if (*ip & 0x80000000) { /* extern is negative */ *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */ } #endif *ip |= (*cp++ << 16); *ip |= (*cp++ << 8); *ip |= *cp; } static void put_ix_int(void *xp, const ix_int *ip) { uchar *cp = (uchar *) xp; *cp++ = (uchar)( (*ip) >> 24); *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*ip) & 0x0000ff00) >> 8); *cp = (uchar)( (*ip) & 0x000000ff); } #if X_SIZEOF_INT != SIZEOF_INT NCX_GET1I(int, int, 1) #endif NCX_GET1I(int, schar, 0) NCX_GET1I(int, short, 1) NCX_GET1I(int, long, 1) NCX_GET1I(int, longlong, 1) NCX_GET1I(int, ushort, 0) NCX_GET1I(int, uchar, 0) NCX_GET1I(int, uint, 0) NCX_GET1I(int, ulonglong, 0) NCX_GET1F(int, float) NCX_GET1F(int, double) static int APIPrefix`x_put_'NC_TYPE(int)_schar(void *xp, const schar *ip, void *fillp) { uchar *cp = (uchar *) xp; if (*ip & 0x80) { *cp++ = 0xff; *cp++ = 0xff; *cp++ = 0xff; } else { *cp++ = 0x00; *cp++ = 0x00; *cp++ = 0x00; } *cp = (uchar)*ip; return NC_NOERR; } static int APIPrefix`x_put_'NC_TYPE(int)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0x00; *cp++ = 0x00; *cp++ = 0x00; *cp = *ip; return NC_NOERR; } #if X_SIZEOF_INT != SIZEOF_INT NCX_PUT1I(int, int, 1) #endif NCX_PUT1I(int, short, 1) NCX_PUT1I(int, long, 1) NCX_PUT1I(int, longlong, 1) NCX_PUT1I(int, ushort, 0) NCX_PUT1I(int, uint, 0) NCX_PUT1I(int, ulonglong, 0) NCX_PUT1F(int, float) NCX_PUT1F(int, double) /* external NC_UINT ---------------------------------------------------------*/ #if USHORT_MAX == X_UINT_MAX typedef ushort ix_uint; #define SIZEOF_IX_UINT SIZEOF_USHORT #define IX_UINT_MAX USHORT_MAX #elif UINT_MAX >= X_UINT_MAX typedef uint ix_uint; #define SIZEOF_IX_UINT SIZEOF_UINT #define IX_UINT_MAX UINT_MAX #elif ULONG_MAX >= X_UINT_MAX typedef ulong ix_uint; #define SIZEOF_IX_UINT SIZEOF_ULONG #define IX_UINT_MAX ULONG_MAX #else #error "ix_uint implementation" #endif static void get_ix_uint(const void *xp, ix_uint *ip) { const uchar *cp = (const uchar *) xp; *ip = (ix_uint)(*cp++ << 24); *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 16)); *ip = (ix_uint)(*ip | (ix_uint)(*cp++ << 8)); *ip = (ix_uint)(*ip | *cp); } static void put_ix_uint(void *xp, const ix_uint *ip) { uchar *cp = (uchar *) xp; *cp++ = (uchar)((*ip) >> 24); *cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*ip) & 0x0000ff00) >> 8); *cp = (uchar)( (*ip) & 0x000000ff); } #if X_SIZEOF_UINT != SIZEOF_UINT NCX_GET1I(uint, uint, 1) #endif NCX_GET1I(uint, schar, 0) NCX_GET1I(uint, short, 0) NCX_GET1I(uint, int, 0) NCX_GET1I(uint, long, 0) NCX_GET1I(uint, longlong, 0) NCX_GET1I(uint, ushort, 1) NCX_GET1I(uint, uchar, 1) NCX_GET1I(uint, ulonglong, 1) NCX_GET1F(uint, float) NCX_GET1F(uint, double) static int APIPrefix`x_put_'NC_TYPE(uint)_schar(void *xp, const schar *ip, void *fillp) { uchar *cp; if (*ip < 0) { #ifdef ERANGE_FILL if (fillp != NULL) memcpy(xp, fillp, 4); #ifndef WORDS_BIGENDIAN swapn4b(xp, xp, 1); #endif #endif DEBUG_RETURN_ERROR(NC_ERANGE) } cp = (uchar *) xp; *cp++ = 0x00; *cp++ = 0x00; *cp++ = 0x00; *cp = (uchar)*ip; return NC_NOERR; } static int APIPrefix`x_put_'NC_TYPE(uint)_uchar(void *xp, const uchar *ip, void *fillp) { uchar *cp = (uchar *) xp; *cp++ = 0x00; *cp++ = 0x00; *cp++ = 0x00; *cp = *ip; return NC_NOERR; } #if X_SIZEOF_UINT != SIZEOF_UINT NCX_PUT1I(uint, uint, 1) #endif NCX_PUT1I(uint, short, 0) NCX_PUT1I(uint, int, 0) NCX_PUT1I(uint, long, 0) NCX_PUT1I(uint, longlong, 0) NCX_PUT1I(uint, ushort, 1) NCX_PUT1I(uint, ulonglong, 1) NCX_PUT1F(uint, float) NCX_PUT1F(uint, double) /* external NC_FLOAT --------------------------------------------------------*/ #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) inline static void get_ix_float(const void *xp, float *ip) { #ifdef WORDS_BIGENDIAN (void) memcpy(ip, xp, SIZEOF_FLOAT); #else swap4b(ip, xp); #endif } inline static void put_ix_float(void *xp, const float *ip) { #ifdef WORDS_BIGENDIAN (void) memcpy(xp, ip, X_SIZEOF_FLOAT); #else swap4b(xp, ip); #endif } #elif defined(vax) && vax != 0 /* What IEEE single precision floating point looks like on a Vax */ struct ieee_single { unsigned int exp_hi : 7; unsigned int sign : 1; unsigned int mant_hi : 7; unsigned int exp_lo : 1; unsigned int mant_lo_hi : 8; unsigned int mant_lo_lo : 8; }; /* Vax single precision floating point */ struct vax_single { unsigned int mantissa1 : 7; unsigned int exp : 8; unsigned int sign : 1; unsigned int mantissa2 : 16; }; #define VAX_SNG_BIAS 0x81 #define IEEE_SNG_BIAS 0x7f static struct sgl_limits { struct vax_single s; struct ieee_single ieee; } max = { { 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 } /* Max IEEE */ }; static struct sgl_limits min = { { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } /* Min IEEE */ }; dnl dnl dnl dnl dnl GET_VAX_DFLOAT_Body(xp) (body for get_ix_float) dnl define(`GET_VAX_DFLOAT_Body',dnl `dnl struct vax_single *const vsp = (struct vax_single *) ip; const struct ieee_single *const isp = (const struct ieee_single *) $1; unsigned exp = isp->exp_hi << 1 | isp->exp_lo; switch(exp) { case 0 : /* ieee subnormal */ if (isp->mant_hi == min.ieee.mant_hi && isp->mant_lo_hi == min.ieee.mant_lo_hi && isp->mant_lo_lo == min.ieee.mant_lo_lo) { *vsp = min.s; } else { unsigned mantissa = (isp->mant_hi << 16) | isp->mant_lo_hi << 8 | isp->mant_lo_lo; unsigned tmp = mantissa >> 20; if (tmp >= 4) { vsp->exp = 2; } else if (tmp >= 2) { vsp->exp = 1; } else { *vsp = min.s; break; } /* else */ tmp = mantissa - (1 << (20 + vsp->exp )); tmp <<= 3 - vsp->exp; vsp->mantissa2 = tmp; vsp->mantissa1 = (tmp >> 16); } break; case 0xfe : case 0xff : *vsp = max.s; break; default : vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo; vsp->mantissa1 = isp->mant_hi; } vsp->sign = isp->sign; ')dnl static void get_ix_float(const void *xp, float *ip) { GET_VAX_DFLOAT_Body(xp) } dnl dnl dnl dnl dnl PUT_VAX_DFLOAT_Body(xp) (body for get_ix_float) dnl define(`PUT_VAX_DFLOAT_Body',dnl `dnl const struct vax_single *const vsp = (const struct vax_single *)ip; struct ieee_single *const isp = (struct ieee_single *) $1; switch(vsp->exp){ case 0 : /* all vax float with zero exponent map to zero */ *isp = min.ieee; break; case 2 : case 1 : { /* These will map to subnormals */ unsigned mantissa = (vsp->mantissa1 << 16) | vsp->mantissa2; mantissa >>= 3 - vsp->exp; mantissa += (1 << (20 + vsp->exp)); isp->mant_lo_lo = mantissa; isp->mant_lo_hi = mantissa >> 8; isp->mant_hi = mantissa >> 16; isp->exp_lo = 0; isp->exp_hi = 0; } break; case 0xff : /* max.s.exp */ if (vsp->mantissa2 == max.s.mantissa2 && vsp->mantissa1 == max.s.mantissa1) { /* map largest vax float to ieee infinity */ *isp = max.ieee; break; } /* else, fall thru */ default : { unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; isp->exp_hi = exp >> 1; isp->exp_lo = exp; isp->mant_lo_lo = vsp->mantissa2; isp->mant_lo_hi = vsp->mantissa2 >> 8; isp->mant_hi = vsp->mantissa1; } } isp->sign = vsp->sign; ')dnl static void put_ix_float(void *xp, const float *ip) { PUT_VAX_DFLOAT_Body(xp) } /* vax */ #elif defined(_CRAY) && !defined(__crayx1) /* * Return the number of bytes until the next "word" boundary * N.B. This is based on the very weird YMP address structure, * which puts the address within a word in the leftmost 3 bits * of the address. */ static size_t word_align(const void *vp) { const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7; return (rem != 0); } struct ieee_single_hi { unsigned int sign : 1; unsigned int exp : 8; unsigned int mant :23; unsigned int pad :32; }; typedef struct ieee_single_hi ieee_single_hi; struct ieee_single_lo { unsigned int pad :32; unsigned int sign : 1; unsigned int exp : 8; unsigned int mant :23; }; typedef struct ieee_single_lo ieee_single_lo; static const int ieee_single_bias = 0x7f; struct ieee_double { unsigned int sign : 1; unsigned int exp :11; unsigned int mant :52; }; typedef struct ieee_double ieee_double; static const int ieee_double_bias = 0x3ff; #if defined(NO_IEEE_FLOAT) struct cray_single { unsigned int sign : 1; unsigned int exp :15; unsigned int mant :48; }; typedef struct cray_single cray_single; static const int cs_ieis_bias = 0x4000 - 0x7f; static const int cs_id_bias = 0x4000 - 0x3ff; dnl dnl dnl dnl dnl GET_IX_FLOAT_Body (body for get_ix_float) dnl define(`GET_IX_FLOAT_Body',dnl `dnl cray_single *csp = (cray_single *) ip; if (isp->exp == 0) { /* ieee subnormal */ *ip = (double)isp->mant; if (isp->mant != 0) { csp->exp -= (ieee_single_bias + 22); } } else { csp->exp = isp->exp + cs_ieis_bias + 1; csp->mant = isp->mant << (48 - 1 - 23); csp->mant |= (1 << (48 - 1)); } csp->sign = isp->sign; ')dnl dnl dnl dnl dnl dnl PUT_IX_FLOAT_Body (body for put_ix_float) dnl define(`PUT_IX_FLOAT_Body',dnl `dnl const cray_single *csp = (const cray_single *) ip; int ieee_exp = csp->exp - cs_ieis_bias -1; isp->sign = csp->sign; if (ieee_exp >= 0xff) { /* NC_ERANGE => ieee Inf */ isp->exp = 0xff; isp->mant = 0x0; } else if (ieee_exp > 0) { /* normal ieee representation */ isp->exp = ieee_exp; /* assumes cray rep is in normal form */ assert(csp->mant & 0x800000000000); isp->mant = (((csp->mant << 1) & 0xffffffffffff) >> (48 - 23)); } else if (ieee_exp > -23) { /* ieee subnormal, right shift */ const int rshift = (48 - 23 - ieee_exp); isp->mant = csp->mant >> rshift; #if 0 if (csp->mant & (1 << (rshift -1))) { /* round up */ isp->mant++; } #endif isp->exp = 0; } else { /* smaller than ieee can represent */ isp->exp = 0; isp->mant = 0; } ')dnl static void get_ix_float(const void *xp, float *ip) { if (word_align(xp) == 0) { const ieee_single_hi *isp = (const ieee_single_hi *) xp; GET_IX_FLOAT_Body } else { const ieee_single_lo *isp = (const ieee_single_lo *) xp; GET_IX_FLOAT_Body } } static void put_ix_float(void *xp, const float *ip) { if (word_align(xp) == 0) { ieee_single_hi *isp = (ieee_single_hi*)xp; PUT_IX_FLOAT_Body } else { ieee_single_lo *isp = (ieee_single_lo*)xp; PUT_IX_FLOAT_Body } } #else /* IEEE Cray with only doubles */ static void get_ix_float(const void *xp, float *ip) { ieee_double *idp = (ieee_double *) ip; if (word_align(xp) == 0) { const ieee_single_hi *isp = (const ieee_single_hi *) xp; if (isp->exp == 0 && isp->mant == 0) { idp->exp = 0; idp->mant = 0; } else { idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias); idp->mant = isp->mant << (52 - 23); } idp->sign = isp->sign; } else { const ieee_single_lo *isp = (const ieee_single_lo *) xp; if (isp->exp == 0 && isp->mant == 0) { idp->exp = 0; idp->mant = 0; } else { idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias); idp->mant = isp->mant << (52 - 23); } idp->sign = isp->sign; } } static void put_ix_float(void *xp, const float *ip) { const ieee_double *idp = (const ieee_double *) ip; if (word_align(xp) == 0) { ieee_single_hi *isp = (ieee_single_hi*)xp; if (idp->exp > (ieee_double_bias - ieee_single_bias)) isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); else isp->exp = 0; isp->mant = idp->mant >> (52 - 23); isp->sign = idp->sign; } else { ieee_single_lo *isp = (ieee_single_lo*)xp; if (idp->exp > (ieee_double_bias - ieee_single_bias)) isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); else isp->exp = 0; isp->mant = idp->mant >> (52 - 23); isp->sign = idp->sign; } } #endif #else #error "ix_float implementation" #endif #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT) static int APIPrefix`x_get_'NC_TYPE(float)_float(const void *xp, float *ip, void *fillp) { /* TODO */ get_ix_float(xp, ip); return NC_NOERR; } #endif #define ix_float float NCX_GET1F(float, schar) NCX_GET1F(float, short) NCX_GET1F(float, int) NCX_GET1F(float, long) NCX_GET1F(float, double) NCX_GET1F(float, longlong) NCX_GET1F(float, uchar) NCX_GET1F(float, ushort) NCX_GET1F(float, uint) NCX_GET1F(float, ulonglong) #if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT) static int APIPrefix`x_put_'NC_TYPE(float)_float(void *xp, const float *ip, void *fillp) { int err=NC_NOERR; float *_ip=ip; #ifdef NO_IEEE_FLOAT #ifdef ERANGE_FILL float tmp; #endif if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) { FillValue(float, &tmp) #ifdef ERANGE_FILL _ip = &tmp; #endif DEBUG_ASSIGN_ERROR(err, NC_ERANGE) } #endif put_ix_float(xp, _ip); return err; } #endif NCX_PUT1F(float, schar) NCX_PUT1F(float, short) NCX_PUT1F(float, int) NCX_PUT1F(float, long) NCX_PUT1F(float, double) NCX_PUT1F(float, longlong) NCX_PUT1F(float, uchar) NCX_PUT1F(float, ushort) NCX_PUT1F(float, uint) NCX_PUT1F(float, ulonglong) /* external NC_DOUBLE -------------------------------------------------------*/ #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) static void get_ix_double(const void *xp, double *ip) { #ifdef WORDS_BIGENDIAN (void) memcpy(ip, xp, SIZEOF_DOUBLE); #else swap8b(ip, xp); #endif } static void put_ix_double(void *xp, const double *ip) { #ifdef WORDS_BIGENDIAN (void) memcpy(xp, ip, X_SIZEOF_DOUBLE); #else swap8b(xp, ip); #endif } #elif defined(vax) && vax != 0 /* What IEEE double precision floating point looks like on a Vax */ struct ieee_double { unsigned int exp_hi : 7; unsigned int sign : 1; unsigned int mant_6 : 4; unsigned int exp_lo : 4; unsigned int mant_5 : 8; unsigned int mant_4 : 8; unsigned int mant_lo : 32; }; /* Vax double precision floating point */ struct vax_double { unsigned int mantissa1 : 7; unsigned int exp : 8; unsigned int sign : 1; unsigned int mantissa2 : 16; unsigned int mantissa3 : 16; unsigned int mantissa4 : 16; }; #define VAX_DBL_BIAS 0x81 #define IEEE_DBL_BIAS 0x3ff #define MASK(nbits) ((1 << nbits) - 1) static const struct dbl_limits { struct vax_double d; struct ieee_double ieee; } dbl_limits[2] = { {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */ {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */ }; dnl dnl dnl dnl dnl GET_VAX_DDOUBLE_Body(xp) (body for get_ix_double) dnl define(`GET_VAX_DDOUBLE_Body',dnl `dnl struct vax_double *const vdp = (struct vax_double *)ip; const struct ieee_double *const idp = (const struct ieee_double *) $1; { const struct dbl_limits *lim; int ii; for (ii = 0, lim = dbl_limits; ii < sizeof(dbl_limits)/sizeof(struct dbl_limits); ii++, lim++) { if ((idp->mant_lo == lim->ieee.mant_lo) && (idp->mant_4 == lim->ieee.mant_4) && (idp->mant_5 == lim->ieee.mant_5) && (idp->mant_6 == lim->ieee.mant_6) && (idp->exp_lo == lim->ieee.exp_lo) && (idp->exp_hi == lim->ieee.exp_hi) ) { *vdp = lim->d; goto doneit; } } } { unsigned exp = idp->exp_hi << 4 | idp->exp_lo; vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; } { unsigned mant_hi = ((idp->mant_6 << 16) | (idp->mant_5 << 8) | idp->mant_4); unsigned mant_lo = SWAP4(idp->mant_lo); vdp->mantissa1 = (mant_hi >> 13); vdp->mantissa2 = ((mant_hi & MASK(13)) << 3) | (mant_lo >> 29); vdp->mantissa3 = (mant_lo >> 13); vdp->mantissa4 = (mant_lo << 3); } doneit: vdp->sign = idp->sign; ')dnl static void get_ix_double(const void *xp, double *ip) { GET_VAX_DDOUBLE_Body(xp) } dnl dnl dnl dnl dnl PUT_VAX_DDOUBLE_Body(xp) (body for put_ix_double) dnl define(`PUT_VAX_DDOUBLE_Body',dnl `dnl const struct vax_double *const vdp = (const struct vax_double *)ip; struct ieee_double *const idp = (struct ieee_double *) $1; if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) && (vdp->mantissa3 == dbl_limits[0].d.mantissa3) && (vdp->mantissa2 == dbl_limits[0].d.mantissa2) && (vdp->mantissa1 == dbl_limits[0].d.mantissa1) && (vdp->exp == dbl_limits[0].d.exp)) { *idp = dbl_limits[0].ieee; goto shipit; } if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) && (vdp->mantissa3 == dbl_limits[1].d.mantissa3) && (vdp->mantissa2 == dbl_limits[1].d.mantissa2) && (vdp->mantissa1 == dbl_limits[1].d.mantissa1) && (vdp->exp == dbl_limits[1].d.exp)) { *idp = dbl_limits[1].ieee; goto shipit; } { unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) | (vdp->mantissa3 << 13) | ((vdp->mantissa4 >> 3) & MASK(13)); unsigned mant_hi = (vdp->mantissa1 << 13) | (vdp->mantissa2 >> 3); if ((vdp->mantissa4 & 7) > 4) { /* round up */ mant_lo++; if (mant_lo == 0) { mant_hi++; if (mant_hi > 0xffffff) { mant_hi = 0; exp++; } } } idp->mant_lo = SWAP4(mant_lo); idp->mant_6 = mant_hi >> 16; idp->mant_5 = (mant_hi & 0xff00) >> 8; idp->mant_4 = mant_hi; idp->exp_hi = exp >> 4; idp->exp_lo = exp; } shipit: idp->sign = vdp->sign; ')dnl static void put_ix_double(void *xp, const double *ip) { PUT_VAX_DDOUBLE_Body(xp) } /* vax */ #elif defined(_CRAY) && !defined(__crayx1) static void get_ix_double(const void *xp, double *ip) { const ieee_double *idp = (const ieee_double *) xp; cray_single *csp = (cray_single *) ip; if (idp->exp == 0) { /* ieee subnormal */ *ip = (double)idp->mant; if (idp->mant != 0) { csp->exp -= (ieee_double_bias + 51); } } else { csp->exp = idp->exp + cs_id_bias + 1; csp->mant = idp->mant >> (52 - 48 + 1); csp->mant |= (1 << (48 - 1)); } csp->sign = idp->sign; } static void put_ix_double(void *xp, const double *ip) { ieee_double *idp = (ieee_double *) xp; const cray_single *csp = (const cray_single *) ip; int ieee_exp = csp->exp - cs_id_bias -1; idp->sign = csp->sign; if (ieee_exp >= 0x7ff) { /* NC_ERANGE => ieee Inf */ idp->exp = 0x7ff; idp->mant = 0x0; } else if (ieee_exp > 0) { /* normal ieee representation */ idp->exp = ieee_exp; /* assumes cray rep is in normal form */ assert(csp->mant & 0x800000000000); idp->mant = (((csp->mant << 1) & 0xffffffffffff) << (52 - 48)); } else if (ieee_exp >= (-(52 -48))) { /* ieee subnormal, left shift */ const int lshift = (52 - 48) + ieee_exp; idp->mant = csp->mant << lshift; idp->exp = 0; } else if (ieee_exp >= -52) { /* ieee subnormal, right shift */ const int rshift = (- (52 - 48) - ieee_exp); idp->mant = csp->mant >> rshift; #if 0 if (csp->mant & (1 << (rshift -1))) { /* round up */ idp->mant++; } #endif idp->exp = 0; } else { /* smaller than ieee can represent */ idp->exp = 0; idp->mant = 0; } } #else #error "ix_double implementation" #endif #define ix_double double NCX_GET1F(double, schar) NCX_GET1F(double, short) NCX_GET1F(double, int) NCX_GET1F(double, long) NCX_GET1F(double, longlong) NCX_GET1F(double, uchar) NCX_GET1F(double, ushort) NCX_GET1F(double, uint) NCX_GET1F(double, ulonglong) static int APIPrefix`x_get_'NC_TYPE(double)_float(const void *xp, float *ip) { double xx = 0.0; get_ix_double(xp, &xx); if (xx > FLT_MAX) { #ifdef ERANGE_FILL *ip = NC_FILL_FLOAT; #else *ip = FLT_MAX; #endif DEBUG_RETURN_ERROR(NC_ERANGE) } if (xx < (-FLT_MAX)) { #ifdef ERANGE_FILL *ip = NC_FILL_FLOAT; #else *ip = (-FLT_MAX); #endif DEBUG_RETURN_ERROR(NC_ERANGE) } *ip = (float) xx; return NC_NOERR; } #if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT) static int APIPrefix`x_get_'NC_TYPE(double)_double(const void *xp, double *ip, void *fillp) { /* TODO */ get_ix_double(xp, ip); return NC_NOERR; } #endif NCX_PUT1F(double, schar) NCX_PUT1F(double, uchar) NCX_PUT1F(double, short) NCX_PUT1F(double, ushort) NCX_PUT1F(double, int) NCX_PUT1F(double, long) NCX_PUT1F(double, uint) NCX_PUT1F(double, longlong) NCX_PUT1F(double, ulonglong) static int APIPrefix`x_put_'NC_TYPE(double)_float(void *xp, const float *ip, void *fillp) { int err=NC_NOERR; double xx = FillDefaultValue(double); #if 1 /* TODO: figure this out (if condition below will never be true)*/ if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) { FillValue(double, &xx) DEBUG_ASSIGN_ERROR(err, NC_ERANGE) } #ifdef ERANGE_FILL else #endif #endif xx = (double) *ip; put_ix_double(xp, &xx); return err; } #if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT) static int APIPrefix`x_put_'NC_TYPE(double)_double(void *xp, const double *ip, void *fillp) { int err=NC_NOERR; double *_ip = ip; #ifdef NO_IEEE_FLOAT #ifdef ERANGE_FILL double tmp=NC_FILL_DOUBLE; #endif if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) { FillValue(double, &tmp) #ifdef ERANGE_FILL _ip = &tmp; #endif DEBUG_ASSIGN_ERROR(err, NC_ERANGE) } #endif put_ix_double(xp, _ip); return err; } #endif /* external NC_INT64 --------------------------------------------------------*/ #if SHORT_MAX == X_INT64_MAX typedef short ix_int64; #define SIZEOF_IX_INT64 SIZEOF_SHORT #define IX_INT64_MAX SHORT_MAX #elif LONG_LONG_MAX >= X_INT64_MAX typedef longlong ix_int64; #define SIZEOF_IX_INT64 SIZEOF_LONGLONG #define IX_INT64_MAX LONG_LONG_MAX #elif LONG_MAX >= X_INT64_MAX typedef long ix_int64; #define SIZEOF_IX_INT64 SIZEOF_LONG #define IX_INT64_MAX LONG_MAX #else #error "ix_int64 implementation" #endif static void get_ix_int64(const void *xp, ix_int64 *ip) { const uchar *cp = (const uchar *) xp; *ip = ((ix_int64)(*cp++) << 56); *ip |= ((ix_int64)(*cp++) << 48); *ip |= ((ix_int64)(*cp++) << 40); *ip |= ((ix_int64)(*cp++) << 32); *ip |= ((ix_int64)(*cp++) << 24); *ip |= ((ix_int64)(*cp++) << 16); *ip |= ((ix_int64)(*cp++) << 8); *ip |= (ix_int64)*cp; } static void put_ix_int64(void *xp, const ix_int64 *ip) { uchar *cp = (uchar *) xp; *cp++ = (uchar)((*ip) >> 56); *cp++ = (uchar)(((*ip) & 0x00ff000000000000LL) >> 48); *cp++ = (uchar)(((*ip) & 0x0000ff0000000000LL) >> 40); *cp++ = (uchar)(((*ip) & 0x000000ff00000000LL) >> 32); *cp++ = (uchar)(((*ip) & 0x00000000ff000000LL) >> 24); *cp++ = (uchar)(((*ip) & 0x0000000000ff0000LL) >> 16); *cp++ = (uchar)(((*ip) & 0x000000000000ff00LL) >> 8); *cp = (uchar)( (*ip) & 0x00000000000000ffLL); } #if X_SIZEOF_INT64 != SIZEOF_LONGLONG NCX_GET1I(int64, longlong, 1) #endif NCX_GET1I(int64, schar, 0) NCX_GET1I(int64, short, 1) NCX_GET1I(int64, int, 1) NCX_GET1I(int64, long, 1) NCX_GET1I(int64, ushort, 0) NCX_GET1I(int64, uchar, 0) NCX_GET1I(int64, uint, 0) NCX_GET1I(int64, ulonglong, 0) NCX_GET1F(int64, float) NCX_GET1F(int64, double) #if X_SIZEOF_INT64 != SIZEOF_LONGLONG NCX_PUT1I(int64, longlong, 1) #endif NCX_PUT1I(int64, schar, 0) NCX_PUT1I(int64, short, 1) NCX_PUT1I(int64, int, 1) NCX_PUT1I(int64, long, 1) NCX_PUT1I(int64, ushort, 0) NCX_PUT1I(int64, uchar, 0) NCX_PUT1I(int64, uint, 0) NCX_PUT1I(int64, ulonglong, 0) NCX_PUT1F(int64, float) NCX_PUT1F(int64, double) /* external NC_UINT64 -------------------------------------------------------*/ #if USHORT_MAX == X_UINT64_MAX typedef ushort ix_uint64; #define SIZEOF_IX_UINT64 SIZEOF_USHORT #define IX_UINT64_MAX USHORT_MAX #elif ULONG_LONG_MAX >= X_UINT64_MAX typedef ulonglong ix_uint64; #define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG #define IX_UINT64_MAX ULONG_LONG_MAX #elif ULONG_MAX >= X_UINT64_MAX typedef ulong ix_uint64; #define SIZEOF_IX_UINT64 SIZEOF_ULONG #define IX_UINT64_MAX ULONG_MAX #else #error "ix_uint64 implementation" #endif static void get_ix_uint64(const void *xp, ix_uint64 *ip) { const uchar *cp = (const uchar *) xp; *ip = ((ix_uint64)(*cp++) << 56); *ip |= ((ix_uint64)(*cp++) << 48); *ip |= ((ix_uint64)(*cp++) << 40); *ip |= ((ix_uint64)(*cp++) << 32); *ip |= ((ix_uint64)(*cp++) << 24); *ip |= ((ix_uint64)(*cp++) << 16); *ip |= ((ix_uint64)(*cp++) << 8); *ip |= (ix_uint64)*cp; } static void put_ix_uint64(void *xp, const ix_uint64 *ip) { uchar *cp = (uchar *) xp; *cp++ = (uchar)((*ip) >> 56); *cp++ = (uchar)(((*ip) & 0x00ff000000000000ULL) >> 48); *cp++ = (uchar)(((*ip) & 0x0000ff0000000000ULL) >> 40); *cp++ = (uchar)(((*ip) & 0x000000ff00000000ULL) >> 32); *cp++ = (uchar)(((*ip) & 0x00000000ff000000ULL) >> 24); *cp++ = (uchar)(((*ip) & 0x0000000000ff0000ULL) >> 16); *cp++ = (uchar)(((*ip) & 0x000000000000ff00ULL) >> 8); *cp = (uchar)( (*ip) & 0x00000000000000ffULL); } #if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG NCX_GET1I(uint64, ulonglong, 1) #endif NCX_GET1I(uint64, schar, 0) NCX_GET1I(uint64, short, 0) NCX_GET1I(uint64, int, 0) NCX_GET1I(uint64, long, 0) NCX_GET1I(uint64, longlong, 0) NCX_GET1I(uint64, ushort, 1) NCX_GET1I(uint64, uchar, 1) NCX_GET1I(uint64, uint, 1) NCX_GET1F(uint64, float) NCX_GET1F(uint64, double) #if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG NCX_PUT1I(uint64, ulonglong, 1) #endif NCX_PUT1I(uint64, schar, 0) NCX_PUT1I(uint64, short, 0) NCX_PUT1I(uint64, int, 0) NCX_PUT1I(uint64, long, 0) NCX_PUT1I(uint64, longlong, 0) NCX_PUT1I(uint64, uchar, 1) NCX_PUT1I(uint64, ushort, 1) NCX_PUT1I(uint64, uint, 1) NCX_PUT1F(uint64, float) NCX_PUT1F(uint64, double) /* x_size_t */ #if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T #error "x_size_t implementation" /* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */ #endif int APIPrefix`x_put_size_t'(void **xpp, const size_t *ulp) { /* similar to put_ix_int() */ uchar *cp = (uchar *) *xpp; assert(*ulp <= X_SIZE_MAX); *cp++ = (uchar)((*ulp) >> 24); *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*ulp) & 0x0000ff00) >> 8); *cp = (uchar)((*ulp) & 0x000000ff); *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T); return NC_NOERR; } int APIPrefix`x_get_size_t'(const void **xpp, size_t *ulp) { /* similar to get_ix_int */ const uchar *cp = (const uchar *) *xpp; *ulp = (unsigned)(*cp++) << 24; *ulp |= (*cp++ << 16); *ulp |= (*cp++ << 8); *ulp |= *cp; *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T); return NC_NOERR; } /* x_off_t */ int APIPrefix`x_put_off_t'(void **xpp, const off_t *lp, size_t sizeof_off_t) { /* similar to put_ix_int() */ uchar *cp = (uchar *) *xpp; /* No negative offsets stored in netcdf */ if (*lp < 0) { /* Assume this is an overflow of a 32-bit int... */ DEBUG_RETURN_ERROR(NC_ERANGE) } assert(sizeof_off_t == 4 || sizeof_off_t == 8); if (sizeof_off_t == 4) { *cp++ = (uchar) ((*lp) >> 24); *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8); *cp = (uchar)( (*lp) & 0x000000ff); } else { #if SIZEOF_OFF_T == 4 /* Write a 64-bit offset on a system with only a 32-bit offset */ *cp++ = (uchar)0; *cp++ = (uchar)0; *cp++ = (uchar)0; *cp++ = (uchar)0; *cp++ = (uchar)(((*lp) & 0xff000000) >> 24); *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8); *cp = (uchar)( (*lp) & 0x000000ff); #else *cp++ = (uchar) ((*lp) >> 56); *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48); *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40); *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32); *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24); *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16); *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >> 8); *cp = (uchar)( (*lp) & 0x00000000000000ffLL); #endif } *xpp = (void *)((char *)(*xpp) + sizeof_off_t); return NC_NOERR; } int APIPrefix`x_get_off_t'(const void **xpp, off_t *lp, size_t sizeof_off_t) { /* similar to get_ix_int() */ const uchar *cp = (const uchar *) *xpp; assert(sizeof_off_t == 4 || sizeof_off_t == 8); if (sizeof_off_t == 4) { *lp = (off_t)(*cp++ << 24); *lp |= (off_t)(*cp++ << 16); *lp |= (off_t)(*cp++ << 8); *lp |= (off_t)*cp; } else { #if SIZEOF_OFF_T == 4 /* Read a 64-bit offset on a system with only a 32-bit offset */ /* If the offset overflows, set an error code and return */ *lp = ((off_t)(*cp++) << 24); *lp |= ((off_t)(*cp++) << 16); *lp |= ((off_t)(*cp++) << 8); *lp |= ((off_t)(*cp++)); /* * lp now contains the upper 32-bits of the 64-bit offset. if lp is * not zero, then the dataset is larger than can be represented * on this system. Set an error code and return. */ if (*lp != 0) { DEBUG_RETURN_ERROR(NC_ERANGE) } *lp = ((off_t)(*cp++) << 24); *lp |= ((off_t)(*cp++) << 16); *lp |= ((off_t)(*cp++) << 8); *lp |= (off_t)*cp; if (*lp < 0) { /* * If this fails, then the offset is >2^31, but less * than 2^32 which is not allowed, but is not caught * by the previous check */ DEBUG_RETURN_ERROR(NC_ERANGE) } #else *lp = ((off_t)(*cp++) << 56); *lp |= ((off_t)(*cp++) << 48); *lp |= ((off_t)(*cp++) << 40); *lp |= ((off_t)(*cp++) << 32); *lp |= ((off_t)(*cp++) << 24); *lp |= ((off_t)(*cp++) << 16); *lp |= ((off_t)(*cp++) << 8); *lp |= (off_t)*cp; #endif } *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t); return NC_NOERR; } /*----< APIPrefix`x_get_uint32'() >------------------------------------------*/ int APIPrefix`x_get_uint32'(const void **xpp, uint *ip) { #ifdef WORDS_BIGENDIAN /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on * some system, such as HPUX */ (void) memcpy(ip, *xpp, SIZEOF_UINT); #else const uchar *cp = (const uchar *) *xpp; *ip = (uint)(*cp++ << 24); *ip = (uint)(*ip | (uint)(*cp++ << 16)); *ip = (uint)(*ip | (uint)(*cp++ << 8)); *ip = (uint)(*ip | *cp); #endif /* advance *xpp 4 bytes */ *xpp = (void *)((const char *)(*xpp) + 4); return NC_NOERR; } /*----< APIPrefix`x_get_uint64'() >------------------------------------------*/ int APIPrefix`x_get_uint64'(const void **xpp, unsigned long long *ullp) { #ifdef WORDS_BIGENDIAN /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on * some system, such as HPUX */ (void) memcpy(ullp, *xpp, SIZEOF_UINT64); #else const uchar *cp = (const uchar *) *xpp; /* below is the same as calling swap8b(ullp, *xpp) */ *ullp = (unsigned long long)(*cp++) << 56; *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 48); *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 40); *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 32); *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 24); *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 16); *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp++) << 8); *ullp = (unsigned long long)(*ullp | (unsigned long long)(*cp)); #endif /* advance *xpp 8 bytes */ *xpp = (void *)((const char *)(*xpp) + 8); return NC_NOERR; } /*---< APIPrefix`x_put_uint32'() >-------------------------------------------*/ /* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian * form and advance *xpp 4 bytes */ int APIPrefix`x_put_uint32'(void **xpp, const unsigned int ip) { #ifdef WORDS_BIGENDIAN /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on * some system, such as HPUX */ (void) memcpy(*xpp, &ip, X_SIZEOF_UINT); #else /* bitwise shifts below are to produce an integer in Big Endian */ uchar *cp = (uchar *) *xpp; *cp++ = (uchar)((ip & 0xff000000) >> 24); *cp++ = (uchar)((ip & 0x00ff0000) >> 16); *cp++ = (uchar)((ip & 0x0000ff00) >> 8); *cp = (uchar)( ip & 0x000000ff); #endif /* advance *xpp 4 bytes */ *xpp = (void *)((char *)(*xpp) + 4); return NC_NOERR; } /*---< APIPrefix`x_put_uint64'() >-------------------------------------------*/ /* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian * form and advance *xpp 8 bytes */ int APIPrefix`x_put_uint64'(void **xpp, const unsigned long long ip) { #ifdef WORDS_BIGENDIAN /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on * some system, such as HPUX */ (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64); #else uchar *cp = (uchar *) *xpp; /* below is the same as calling swap8b(*xpp, &ip) */ *cp++ = (uchar) (ip >> 56); *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48); *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40); *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32); *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24); *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16); *cp++ = (uchar)((ip & 0x000000000000ff00LL) >> 8); *cp = (uchar) (ip & 0x00000000000000ffLL); #endif /* advance *xpp 8 bytes */ *xpp = (void *)((char *)(*xpp) + 8); return NC_NOERR; } /* * Aggregate numeric conversion functions. */ dnl define(`GETN_CheckBND', `ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, `|| xp[i] < 0', `|| xp[i] < Imin($2)')')dnl define(`PUTN_CheckBND', `ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| tp[i] < 0', `|| tp[i] < Xmin($1)')')dnl dnl dnl dnl dnl dnl dnl NCX_GETN_Byte_Body (body for one byte types on diagonal) dnl define(`NCX_GETN_Byte_Body',dnl `dnl (void) memcpy(tp, *xpp, (size_t)nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; ')dnl dnl dnl dnl dnl dnl NCX_PAD_GETN_Byte_body (body for one byte types on diagonal) dnl define(`NCX_PAD_GETN_Byte_Body',dnl `dnl IntType rndup = nelems % X_ALIGN; if (rndup) rndup = X_ALIGN - rndup; (void) memcpy(tp, *xpp, (size_t)nelems); *xpp = (void *)((char *)(*xpp) + nelems + rndup); return NC_NOERR; ')dnl dnl dnl dnl dnl dnl NCX_GETN_BYTE(xtype, itype) dnl define(`NCX_GETN_BYTE',dnl `dnl int APIPrefix`x_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { int status = NC_NOERR; $1 *xp = ($1 *)(*xpp); while (nelems-- != 0) { ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, ` if (*xp < 0) { #ifdef ERANGE_FILL *tp = FillDefaultValue($2); #endif DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */ SKIP_LOOP(xp, tp) }')dnl *tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */ } *xpp = (const void *)xp; return status; } ')dnl dnl dnl dnl dnl dnl NCX_PAD_GETN_BYTE(xtype, itype) dnl define(`NCX_PAD_GETN_BYTE',dnl `dnl int APIPrefix`x_pad_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { int status = NC_NOERR; IntType rndup = nelems % X_ALIGN; $1 *xp = ($1 *) *xpp; if (rndup) rndup = X_ALIGN - rndup; while (nelems-- != 0) { ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, ` if (*xp < 0) { #ifdef ERANGE_FILL *tp = FillDefaultValue($2); #endif DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */ SKIP_LOOP(xp, tp) }')dnl *tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */ } *xpp = (void *)(xp + rndup); return status; } ')dnl dnl dnl dnl dnl dnl NCX_GETN(xtype, itype) dnl define(`NCX_GETN',dnl `dnl int APIPrefix`x_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { `#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1) /* basic algorithm is: * - ensure sane alignment of input data * - copy (conversion happens automatically) input data * to output * - update xpp to point at next unconverted input, and tp to point * at next location for converted output */ long i, j, ni; $1 tmp[LOOPCNT]; /* in case input is misaligned */ $1 *xp; int nrange = 0; /* number of range errors */ int realign = 0; /* "do we need to fix input data alignment?" */ long cxp = (long) *((char**)xpp); realign = (cxp & 7) % Isizeof($1); /* sjl: manually stripmine so we can limit amount of * vector work space reserved to LOOPCNT elements. Also * makes vectorisation easy */ for (j=0; j= 0 */ nrange += xp[i] > Imax($2) GETN_CheckBND($1, $2); } /* update xpp and tp */ if (realign) xp = ($1 *) *xpp; xp += ni; tp += ni; *xpp = (void*)xp; } return nrange == 0 ? NC_NOERR : NC_ERANGE; #else /* not SX */ const char *xp = (const char *) *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) { const int lstatus = APIPrefix`x_get_'NC_TYPE($1)_$2(xp, tp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } *xpp = (const void *)xp; return status; #endif } ')dnl dnl dnl dnl dnl dnl NCX_PAD_GETN_SHORT(xtype ttype) dnl define(`NCX_PAD_GETN_SHORT',dnl `dnl int APIPrefix`x_pad_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp) { const IntType rndup = nelems % X_SIZEOF_SHORT; const char *xp = (const char *) *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) { const int lstatus = APIPrefix`x_get_'NC_TYPE($1)_$2(xp, tp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } if (rndup != 0) xp += Xsizeof($1); *xpp = (void *)xp; return status; } ')dnl dnl dnl dnl dnl dnl NCX_PUTN_Byte_Body(Type) (body for one byte types) dnl define(`NCX_PUTN_Byte_Body',dnl `dnl (void) memcpy(*xpp, tp, (size_t)nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; ')dnl dnl dnl dnl dnl dnl NCX_PAD_PUTN_Byte_Body(Type) (body for one byte types) dnl define(`NCX_PAD_PUTN_Byte_Body',dnl IntType rndup = nelems % X_ALIGN; if (rndup) rndup = X_ALIGN - rndup; (void) memcpy(*xpp, tp, (size_t)nelems); *xpp = (void *)((char *)(*xpp) + nelems); if (rndup) { (void) memcpy(*xpp, nada, (size_t)rndup); *xpp = (void *)((char *)(*xpp) + rndup); } return NC_NOERR; `dnl ')dnl dnl dnl dnl dnl dnl NCX_PUTN_BYTE(xtype, itype) dnl define(`NCX_PUTN_BYTE',dnl `dnl int APIPrefix`x_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { int status = NC_NOERR; $1 *xp = ($1 *) *xpp; while (nelems-- != 0) { if (*tp > ($2)Xmax($1) ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')) { FillValue($1, xp) DEBUG_ASSIGN_ERROR(status, NC_ERANGE) SKIP_LOOP(xp, tp) } *xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */ } *xpp = (void *)xp; return status; } ')dnl dnl dnl dnl dnl dnl NCX_PAD_PUTN_BYTE(xtype, ttype) dnl define(`NCX_PAD_PUTN_BYTE',dnl `dnl int APIPrefix`x_pad_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { int status = NC_NOERR; IntType rndup = nelems % X_ALIGN; $1 *xp = ($1 *) *xpp; if (rndup) rndup = X_ALIGN - rndup; while (nelems-- != 0) { if (*tp > ($2)Xmax($1) ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')) { FillValue($1, xp) DEBUG_ASSIGN_ERROR(status, NC_ERANGE) SKIP_LOOP(xp, tp) } *xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */ } if (rndup) { (void) memcpy(xp, nada, (size_t)rndup); xp += rndup; } *xpp = (void *)xp; return status; } ')dnl dnl dnl dnl dnl dnl NCX_PUTN(xtype, itype) dnl define(`NCX_PUTN',dnl `dnl int APIPrefix`x_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { `#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1) /* basic algorithm is: * - ensure sane alignment of output data * - copy (conversion happens automatically) input data * to output * - update tp to point at next unconverted input, and xpp to point * at next location for converted output */ long i, j, ni; $1 tmp[LOOPCNT]; /* in case input is misaligned */ $1 *xp; ifelse( $1$2, intfloat,dnl `dnl double d; /* special case for APIPrefix`x_putn_int_float' */ ')dnl int nrange = 0; /* number of range errors */ int realign = 0; /* "do we need to fix input data alignment?" */ long cxp = (long) *((char**)xpp); realign = (cxp & 7) % Isizeof($1); /* sjl: manually stripmine so we can limit amount of * vector work space reserved to LOOPCNT elements. Also * makes vectorisation easy */ for (j=0; j Xmax($1) PUTN_CheckBND($1, $2); ',dnl `dnl /* the normal case: */ xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) tp[i])); /* test for range errors (not always needed but do it anyway) */ /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */ /* if tp is unsigned, we need not check if tp[i] < Xmin */ nrange += tp[i] > Xmax($1) PUTN_CheckBND($1, $2); ')dnl } /* copy workspace back if necessary */ if (realign) { memcpy(*xpp, tmp, (size_t)*ni*Xsizeof($1)); xp = ($1 *) *xpp; } /* update xpp and tp */ xp += ni; tp += ni; *xpp = (void*)xp; } return nrange == 0 ? NC_NOERR : NC_ERANGE; #else /* not SX */ char *xp = (char *) *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) { int lstatus = APIPrefix`x_put_'NC_TYPE($1)_$2(xp, tp, fillp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } *xpp = (void *)xp; return status; #endif } ')dnl dnl dnl dnl dnl dnl NCX_PAD_PUTN_SHORT(xtype, ttype) dnl define(`NCX_PAD_PUTN_SHORT',dnl `dnl int APIPrefix`x_pad_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp) { const IntType rndup = nelems % X_SIZEOF_SHORT; char *xp = (char *) *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++) { int lstatus = APIPrefix`x_put_'NC_TYPE($1)_$2(xp, tp, fillp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } if (rndup != 0) { (void) memcpy(xp, nada, (size_t)(Xsizeof($1))); xp += Xsizeof($1); } *xpp = (void *)xp; return status; } ')dnl dnl dnl dnl dnl dnl Declare & define routines dnl dnl dnl dnl /* schar ---------------------------------------------------------------------*/ dnl NCX_GETN_BYTE(schar, schar) int APIPrefix`x_getn_'NC_TYPE(schar)_schar(const void **xpp, IntType nelems, schar *tp) { NCX_GETN_Byte_Body } NCX_GETN_BYTE(schar, uchar) NCX_GETN_BYTE(schar, short) NCX_GETN_BYTE(schar, int) NCX_GETN_BYTE(schar, long) NCX_GETN_BYTE(schar, float) NCX_GETN_BYTE(schar, double) NCX_GETN_BYTE(schar, longlong) NCX_GETN_BYTE(schar, ushort) NCX_GETN_BYTE(schar, uint) NCX_GETN_BYTE(schar, ulonglong) dnl NCX_PAD_GETN_BYTE(schar, schar) int APIPrefix`x_pad_getn_'NC_TYPE(schar)_schar(const void **xpp, IntType nelems, schar *tp) { NCX_PAD_GETN_Byte_Body } NCX_PAD_GETN_BYTE(schar, uchar) NCX_PAD_GETN_BYTE(schar, short) NCX_PAD_GETN_BYTE(schar, int) NCX_PAD_GETN_BYTE(schar, long) NCX_PAD_GETN_BYTE(schar, float) NCX_PAD_GETN_BYTE(schar, double) NCX_PAD_GETN_BYTE(schar, longlong) NCX_PAD_GETN_BYTE(schar, ushort) NCX_PAD_GETN_BYTE(schar, uint) NCX_PAD_GETN_BYTE(schar, ulonglong) dnl NCX_PUTN_BYTE(schar, schar) int APIPrefix`x_putn_'NC_TYPE(schar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) { NCX_PUTN_Byte_Body } NCX_PUTN_BYTE(schar, uchar) NCX_PUTN_BYTE(schar, short) NCX_PUTN_BYTE(schar, int) NCX_PUTN_BYTE(schar, long) NCX_PUTN_BYTE(schar, float) NCX_PUTN_BYTE(schar, double) NCX_PUTN_BYTE(schar, longlong) NCX_PUTN_BYTE(schar, ushort) NCX_PUTN_BYTE(schar, uint) NCX_PUTN_BYTE(schar, ulonglong) dnl NCX_PAD_PUTN_BYTE(schar, schar) int APIPrefix`x_pad_putn_'NC_TYPE(schar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) { NCX_PAD_PUTN_Byte_Body } NCX_PAD_PUTN_BYTE(schar, uchar) NCX_PAD_PUTN_BYTE(schar, short) NCX_PAD_PUTN_BYTE(schar, int) NCX_PAD_PUTN_BYTE(schar, long) NCX_PAD_PUTN_BYTE(schar, float) NCX_PAD_PUTN_BYTE(schar, double) NCX_PAD_PUTN_BYTE(schar, longlong) NCX_PAD_PUTN_BYTE(schar, ushort) NCX_PAD_PUTN_BYTE(schar, uint) NCX_PAD_PUTN_BYTE(schar, ulonglong) /* uchar ---------------------------------------------------------------------*/ dnl dnl NCX_GETN_BYTE(uchar, schar) int APIPrefix`x_getn_'NC_TYPE(uchar)_schar(const void **xpp, IntType nelems, schar *tp) { int status = NC_NOERR; uchar *xp = (uchar *)(*xpp); while (nelems-- != 0) { if (*xp > SCHAR_MAX) { *tp = NC_FILL_BYTE; DEBUG_ASSIGN_ERROR(status, NC_ERANGE) SKIP_LOOP(xp, tp) } *tp++ = (schar) *xp++; /* type cast from uchar to schar */ } *xpp = (const void *)xp; return status; } dnl NCX_GETN_BYTE(uchar, uchar) int APIPrefix`x_getn_'NC_TYPE(uchar)_uchar(const void **xpp, IntType nelems, uchar *tp) { NCX_GETN_Byte_Body } NCX_GETN_BYTE(uchar, short) NCX_GETN_BYTE(uchar, int) NCX_GETN_BYTE(uchar, long) NCX_GETN_BYTE(uchar, float) NCX_GETN_BYTE(uchar, double) NCX_GETN_BYTE(uchar, longlong) NCX_GETN_BYTE(uchar, ushort) NCX_GETN_BYTE(uchar, uint) NCX_GETN_BYTE(uchar, ulonglong) dnl NCX_PAD_GETN_BYTE(uchar, schar) int APIPrefix`x_pad_getn_'NC_TYPE(uchar)_schar(const void **xpp, IntType nelems, schar *tp) { int status = NC_NOERR; IntType rndup = nelems % X_ALIGN; uchar *xp = (uchar *) *xpp; if (rndup) rndup = X_ALIGN - rndup; while (nelems-- != 0) { if (*xp > SCHAR_MAX) { *tp = NC_FILL_BYTE; DEBUG_ASSIGN_ERROR(status, NC_ERANGE) SKIP_LOOP(xp, tp) } *tp++ = (schar) *xp++; /* type cast from uchar to schar */ } *xpp = (void *)(xp + rndup); return status; } dnl NCX_PAD_GETN_BYTE(uchar, uchar) int APIPrefix`x_pad_getn_'NC_TYPE(uchar)_uchar(const void **xpp, IntType nelems, uchar *tp) { NCX_PAD_GETN_Byte_Body } NCX_PAD_GETN_BYTE(uchar, short) NCX_PAD_GETN_BYTE(uchar, int) NCX_PAD_GETN_BYTE(uchar, long) NCX_PAD_GETN_BYTE(uchar, float) NCX_PAD_GETN_BYTE(uchar, double) NCX_PAD_GETN_BYTE(uchar, longlong) NCX_PAD_GETN_BYTE(uchar, ushort) NCX_PAD_GETN_BYTE(uchar, uint) NCX_PAD_GETN_BYTE(uchar, ulonglong) dnl NCX_PUTN_BYTE(uchar, schar) int APIPrefix`x_putn_'NC_TYPE(uchar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) { int status = NC_NOERR; uchar *xp = (uchar *) *xpp; while (nelems-- != 0) { if (*tp < 0) { FillValue(uchar, xp) DEBUG_ASSIGN_ERROR(status, NC_ERANGE) SKIP_LOOP(xp, tp) } *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */ } *xpp = (void *)xp; return status; } dnl NCX_PUTN_BYTE(uchar, uchar) int APIPrefix`x_putn_'NC_TYPE(uchar)_uchar(void **xpp, IntType nelems, const uchar *tp, void *fillp) { NCX_PUTN_Byte_Body } NCX_PUTN_BYTE(uchar, short) NCX_PUTN_BYTE(uchar, int) NCX_PUTN_BYTE(uchar, long) NCX_PUTN_BYTE(uchar, float) NCX_PUTN_BYTE(uchar, double) NCX_PUTN_BYTE(uchar, longlong) NCX_PUTN_BYTE(uchar, ushort) NCX_PUTN_BYTE(uchar, uint) NCX_PUTN_BYTE(uchar, ulonglong) dnl NCX_PAD_PUTN_BYTE(uchar, schar) int APIPrefix`x_pad_putn_'NC_TYPE(uchar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp) { int status = NC_NOERR; IntType rndup = nelems % X_ALIGN; uchar *xp = (uchar *) *xpp; if (rndup) rndup = X_ALIGN - rndup; while (nelems-- != 0) { if (*tp < 0) { FillValue(uchar, xp) DEBUG_ASSIGN_ERROR(status, NC_ERANGE) SKIP_LOOP(xp, tp) } *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */ } if (rndup) { (void) memcpy(xp, nada, (size_t)rndup); xp += rndup; } *xpp = (void *)xp; return status; } dnl NCX_PAD_PUTN_UCHAR(uchar, uchar) int APIPrefix`x_pad_putn_'NC_TYPE(uchar)_uchar(void **xpp, IntType nelems, const uchar *tp, void *fillp) { NCX_PAD_PUTN_Byte_Body } NCX_PAD_PUTN_BYTE(uchar, short) NCX_PAD_PUTN_BYTE(uchar, int) NCX_PAD_PUTN_BYTE(uchar, long) NCX_PAD_PUTN_BYTE(uchar, float) NCX_PAD_PUTN_BYTE(uchar, double) NCX_PAD_PUTN_BYTE(uchar, longlong) NCX_PAD_PUTN_BYTE(uchar, ushort) NCX_PAD_PUTN_BYTE(uchar, uint) NCX_PAD_PUTN_BYTE(uchar, ulonglong) /* short ---------------------------------------------------------------------*/ #if X_SIZEOF_SHORT == SIZEOF_SHORT /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(short)_short(const void **xpp, IntType nelems, short *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT); # else swapn2b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT); return NC_NOERR; } #else NCX_GETN(short, short) #endif NCX_GETN(short, schar) NCX_GETN(short, int) NCX_GETN(short, long) NCX_GETN(short, float) NCX_GETN(short, double) NCX_GETN(short, longlong) NCX_GETN(short, uchar) NCX_GETN(short, ushort) NCX_GETN(short, uint) NCX_GETN(short, ulonglong) NCX_PAD_GETN_SHORT(short, schar) NCX_PAD_GETN_SHORT(short, uchar) NCX_PAD_GETN_SHORT(short, short) NCX_PAD_GETN_SHORT(short, int) NCX_PAD_GETN_SHORT(short, long) NCX_PAD_GETN_SHORT(short, float) NCX_PAD_GETN_SHORT(short, double) NCX_PAD_GETN_SHORT(short, uint) NCX_PAD_GETN_SHORT(short, longlong) NCX_PAD_GETN_SHORT(short, ulonglong) NCX_PAD_GETN_SHORT(short, ushort) #if X_SIZEOF_SHORT == SIZEOF_SHORT /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(short)_short(void **xpp, IntType nelems, const short *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT); # else swapn2b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT); return NC_NOERR; } #else NCX_PUTN(short, short) #endif NCX_PUTN(short, schar) NCX_PUTN(short, int) NCX_PUTN(short, long) NCX_PUTN(short, float) NCX_PUTN(short, double) NCX_PUTN(short, longlong) NCX_PUTN(short, uchar) NCX_PUTN(short, uint) NCX_PUTN(short, ulonglong) NCX_PUTN(short, ushort) NCX_PAD_PUTN_SHORT(short, schar) NCX_PAD_PUTN_SHORT(short, uchar) NCX_PAD_PUTN_SHORT(short, short) NCX_PAD_PUTN_SHORT(short, int) NCX_PAD_PUTN_SHORT(short, long) NCX_PAD_PUTN_SHORT(short, float) NCX_PAD_PUTN_SHORT(short, double) NCX_PAD_PUTN_SHORT(short, uint) NCX_PAD_PUTN_SHORT(short, longlong) NCX_PAD_PUTN_SHORT(short, ulonglong) NCX_PAD_PUTN_SHORT(short, ushort) /* ushort --------------------------------------------------------------------*/ #if X_SIZEOF_USHORT == SIZEOF_USHORT /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(ushort)_ushort(const void **xpp, IntType nelems, unsigned short *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT); # else swapn2b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT); return NC_NOERR; } #else NCX_GETN(ushort, ushort) #endif NCX_GETN(ushort, schar) NCX_GETN(ushort, short) NCX_GETN(ushort, int) NCX_GETN(ushort, long) NCX_GETN(ushort, float) NCX_GETN(ushort, double) NCX_GETN(ushort, longlong) NCX_GETN(ushort, uchar) NCX_GETN(ushort, uint) NCX_GETN(ushort, ulonglong) NCX_PAD_GETN_SHORT(ushort, schar) NCX_PAD_GETN_SHORT(ushort, short) NCX_PAD_GETN_SHORT(ushort, int) NCX_PAD_GETN_SHORT(ushort, long) NCX_PAD_GETN_SHORT(ushort, float) NCX_PAD_GETN_SHORT(ushort, double) NCX_PAD_GETN_SHORT(ushort, uchar) NCX_PAD_GETN_SHORT(ushort, ushort) NCX_PAD_GETN_SHORT(ushort, uint) NCX_PAD_GETN_SHORT(ushort, longlong) NCX_PAD_GETN_SHORT(ushort, ulonglong) #if X_SIZEOF_USHORT == SIZEOF_USHORT /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(ushort)_ushort(void **xpp, IntType nelems, const unsigned short *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT); # else swapn2b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT); return NC_NOERR; } #else NCX_PUTN(ushort, ushort) #endif NCX_PUTN(ushort, schar) NCX_PUTN(ushort, short) NCX_PUTN(ushort, int) NCX_PUTN(ushort, long) NCX_PUTN(ushort, float) NCX_PUTN(ushort, double) NCX_PUTN(ushort, longlong) NCX_PUTN(ushort, uchar) NCX_PUTN(ushort, uint) NCX_PUTN(ushort, ulonglong) NCX_PAD_PUTN_SHORT(ushort, schar) NCX_PAD_PUTN_SHORT(ushort, uchar) NCX_PAD_PUTN_SHORT(ushort, short) NCX_PAD_PUTN_SHORT(ushort, int) NCX_PAD_PUTN_SHORT(ushort, long) NCX_PAD_PUTN_SHORT(ushort, float) NCX_PAD_PUTN_SHORT(ushort, double) NCX_PAD_PUTN_SHORT(ushort, uint) NCX_PAD_PUTN_SHORT(ushort, longlong) NCX_PAD_PUTN_SHORT(ushort, ulonglong) NCX_PAD_PUTN_SHORT(ushort, ushort) /* int -----------------------------------------------------------------------*/ #if X_SIZEOF_INT == SIZEOF_INT /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(int)_int(const void **xpp, IntType nelems, int *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT); # else swapn4b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT); return NC_NOERR; } #else NCX_GETN(int, int) #endif NCX_GETN(int, schar) NCX_GETN(int, short) NCX_GETN(int, long) NCX_GETN(int, float) NCX_GETN(int, double) NCX_GETN(int, longlong) NCX_GETN(int, uchar) NCX_GETN(int, ushort) NCX_GETN(int, uint) NCX_GETN(int, ulonglong) #if X_SIZEOF_INT == SIZEOF_INT /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(int)_int(void **xpp, IntType nelems, const int *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT); # else swapn4b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT); return NC_NOERR; } #else NCX_PUTN(int, int) #endif NCX_PUTN(int, schar) NCX_PUTN(int, short) NCX_PUTN(int, long) NCX_PUTN(int, float) NCX_PUTN(int, double) NCX_PUTN(int, longlong) NCX_PUTN(int, uchar) NCX_PUTN(int, ushort) NCX_PUTN(int, uint) NCX_PUTN(int, ulonglong) /* uint ----------------------------------------------------------------------*/ #if X_SIZEOF_UINT == SIZEOF_UINT /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(uint)_uint(const void **xpp, IntType nelems, unsigned int *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT); # else swapn4b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT); return NC_NOERR; } #else NCX_GETN(uint, uint) #endif NCX_GETN(uint, schar) NCX_GETN(uint, short) NCX_GETN(uint, int) NCX_GETN(uint, long) NCX_GETN(uint, float) NCX_GETN(uint, double) NCX_GETN(uint, longlong) NCX_GETN(uint, uchar) NCX_GETN(uint, ushort) NCX_GETN(uint, ulonglong) #if X_SIZEOF_UINT == SIZEOF_UINT /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(uint)_uint(void **xpp, IntType nelems, const unsigned int *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT); # else swapn4b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT); return NC_NOERR; } #else NCX_PUTN(uint, uint) #endif NCX_PUTN(uint, schar) NCX_PUTN(uint, short) NCX_PUTN(uint, int) NCX_PUTN(uint, long) NCX_PUTN(uint, float) NCX_PUTN(uint, double) NCX_PUTN(uint, longlong) NCX_PUTN(uint, uchar) NCX_PUTN(uint, ushort) NCX_PUTN(uint, ulonglong) /* float ---------------------------------------------------------------------*/ #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nelems, float *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT); # else swapn4b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT); return NC_NOERR; } #elif defined(vax) && vax != 0 int APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nfloats, float *ip) { float *const end = ip + nfloats; while (ip < end) { GET_VAX_DFLOAT_Body(`(*xpp)') ip++; *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT; } return NC_NOERR; } #else int APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nelems, float *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = APIPrefix`x_get_'NC_TYPE(float)_float(xp, tp, fillp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } *xpp = (const void *)xp; return status; } #endif NCX_GETN(float, schar) NCX_GETN(float, short) NCX_GETN(float, int) NCX_GETN(float, long) NCX_GETN(float, double) NCX_GETN(float, longlong) NCX_GETN(float, ushort) NCX_GETN(float, uchar) NCX_GETN(float, uint) NCX_GETN(float, ulonglong) int APIPrefix`x_putn_'NC_TYPE(float)_float(void **xpp, IntType nelems, const float *tp, void *fillp) #if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) /* optimized version */ { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT); # else swapn4b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT); return NC_NOERR; } #elif defined(vax) && vax != 0 { const float *const end = tp + nelems; while (tp < end) { PUT_VAX_DFLOAT_Body(`(*xpp)') tp++; *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT; } return NC_NOERR; } #else { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { int lstatus = APIPrefix`x_put_'NC_TYPE(float)_float(xp, tp, fillp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } *xpp = (void *)xp; return status; } #endif NCX_PUTN(float, schar) NCX_PUTN(float, short) NCX_PUTN(float, int) NCX_PUTN(float, long) NCX_PUTN(float, double) NCX_PUTN(float, longlong) NCX_PUTN(float, uchar) NCX_PUTN(float, ushort) NCX_PUTN(float, uint) NCX_PUTN(float, ulonglong) /* double --------------------------------------------------------------------*/ #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType nelems, double *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE); # else swapn8b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } #elif defined(vax) && vax != 0 int APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType ndoubles, double *ip) { double *const end = ip + ndoubles; while (ip < end) { GET_VAX_DDOUBLE_Body(`(*xpp)') ip++; *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE; } return NC_NOERR; } /* vax */ #else int APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType nelems, double *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = APIPrefix`x_get_'NC_TYPE(double)_double(xp, tp, fillp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } *xpp = (const void *)xp; return status; } #endif NCX_GETN(double, schar) NCX_GETN(double, short) NCX_GETN(double, int) NCX_GETN(double, long) NCX_GETN(double, float) NCX_GETN(double, longlong) NCX_GETN(double, uchar) NCX_GETN(double, ushort) NCX_GETN(double, uint) NCX_GETN(double, ulonglong) #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType nelems, const double *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE); # else swapn8b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } #elif defined(vax) && vax != 0 int APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType ndoubles, const double *ip, void *fillp) { const double *const end = ip + ndoubles; while (ip < end) { PUT_VAX_DDOUBLE_Body(`(*xpp)') ip++; *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE; } return NC_NOERR; } /* vax */ #else int APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType nelems, const double *tp, void *fillp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { int lstatus = APIPrefix`x_put_'NC_TYPE(double)_double(xp, tp, fillp); if (status == NC_NOERR) /* report the first encountered error */ status = lstatus; } *xpp = (void *)xp; return status; } #endif NCX_PUTN(double, schar) NCX_PUTN(double, short) NCX_PUTN(double, int) NCX_PUTN(double, long) NCX_PUTN(double, float) NCX_PUTN(double, longlong) NCX_PUTN(double, uchar) NCX_PUTN(double, ushort) NCX_PUTN(double, uint) NCX_PUTN(double, ulonglong) /* longlong ------------------------------------------------------------------*/ #if X_SIZEOF_INT64 == SIZEOF_LONGLONG /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(int64)_longlong(const void **xpp, IntType nelems, long long *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG); # else swapn8b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64); return NC_NOERR; } #else NCX_GETN(int64, longlong) #endif NCX_GETN(int64, schar) NCX_GETN(int64, short) NCX_GETN(int64, int) NCX_GETN(int64, long) NCX_GETN(int64, float) NCX_GETN(int64, double) NCX_GETN(int64, uchar) NCX_GETN(int64, ushort) NCX_GETN(int64, uint) NCX_GETN(int64, ulonglong) #if X_SIZEOF_INT64 == SIZEOF_LONGLONG /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(int64)_longlong(void **xpp, IntType nelems, const long long *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64); # else swapn8b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64); return NC_NOERR; } #else NCX_PUTN(int64, longlong) #endif NCX_PUTN(int64, schar) NCX_PUTN(int64, short) NCX_PUTN(int64, int) NCX_PUTN(int64, long) NCX_PUTN(int64, float) NCX_PUTN(int64, double) NCX_PUTN(int64, uchar) NCX_PUTN(int64, ushort) NCX_PUTN(int64, uint) NCX_PUTN(int64, ulonglong) /* uint64 --------------------------------------------------------------------*/ #if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG /* optimized version */ int APIPrefix`x_getn_'NC_TYPE(uint64)_ulonglong(const void **xpp, IntType nelems, unsigned long long *tp) { #ifdef WORDS_BIGENDIAN (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG); # else swapn8b(tp, *xpp, nelems); # endif *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64); return NC_NOERR; } #else NCX_GETN(uint64, ulonglong) #endif NCX_GETN(uint64, schar) NCX_GETN(uint64, short) NCX_GETN(uint64, int) NCX_GETN(uint64, long) NCX_GETN(uint64, float) NCX_GETN(uint64, double) NCX_GETN(uint64, longlong) NCX_GETN(uint64, uchar) NCX_GETN(uint64, ushort) NCX_GETN(uint64, uint) #if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG /* optimized version */ int APIPrefix`x_putn_'NC_TYPE(uint64)_ulonglong(void **xpp, IntType nelems, const unsigned long long *tp, void *fillp) { #ifdef WORDS_BIGENDIAN (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64); # else swapn8b(*xpp, tp, nelems); # endif *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64); return NC_NOERR; } #else NCX_PUTN(uint64, ulonglong) #endif NCX_PUTN(uint64, schar) NCX_PUTN(uint64, short) NCX_PUTN(uint64, int) NCX_PUTN(uint64, long) NCX_PUTN(uint64, float) NCX_PUTN(uint64, double) NCX_PUTN(uint64, longlong) NCX_PUTN(uint64, uchar) NCX_PUTN(uint64, ushort) NCX_PUTN(uint64, uint) /* * Other aggregate conversion functions. */ /* text */ int APIPrefix`x_getn_text'(const void **xpp, IntType nelems, char *tp) { NCX_GETN_Byte_Body } int APIPrefix`x_pad_getn_text'(const void **xpp, IntType nelems, char *tp) { NCX_PAD_GETN_Byte_Body } int APIPrefix`x_putn_text'(void **xpp, IntType nelems, const char *tp) { NCX_PUTN_Byte_Body } int APIPrefix`x_pad_putn_text'(void **xpp, IntType nelems, const char *tp) { NCX_PAD_PUTN_Byte_Body } /* opaque */ int APIPrefix`x_getn_void'(const void **xpp, IntType nelems, void *tp) { NCX_GETN_Byte_Body } int APIPrefix`x_pad_getn_void'(const void **xpp, IntType nelems, void *tp) { NCX_PAD_GETN_Byte_Body } int APIPrefix`x_putn_void'(void **xpp, IntType nelems, const void *tp) { NCX_PUTN_Byte_Body } int APIPrefix`x_pad_putn_void'(void **xpp, IntType nelems, const void *tp) { NCX_PAD_PUTN_Byte_Body }