netcdf-c/libsrc/ncx.m4
Even Rouault b3418d2cd6 Fix undefined left shift in ncx_get_size_t()
Running a build on the .nc file corresponding to the below ncdump output
with -fsanitize=undefined raises

libsrc/ncx.c:4722:26: runtime error: left shift of 255 by 24 places cannot be represented in type 'int'

This is due to *cp being promoted to int before doing the left shift, instead
of the intended unsigned. So do the cast to unsigned internally rather than
externally

ncdump file to reproduce:

netcdf temp {
dimensions:
	y = UNLIMITED ; // (0 currently)
	x = 109067 ;
variables:
	byte t(y, x, x) ;
data:
}

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2265

Credit to OSS Fuzz
2017-06-15 12:46:37 +02:00

3724 lines
88 KiB
Plaintext

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 the m4 macro "ERANGE_FILL" is defined, the I/O to data elements
dnl that cause NC_ERANGE will be filled with the NC default fill values.
dnl
define(`SKIP_LOOP', `ifdef(`ERANGE_FILL', `$1++; $2++; continue;')')
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 <ncconfig.h>
`#'endif',`
`#'if HAVE_CONFIG_H
`#'include <config.h>
`#'endif')
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
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 <inttypes.h> /* uint16_t, uint32_t, uint64_t */
#elif defined(HAVE_STDINT_H)
#include <stdint.h> /* 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);')')')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 <float.h>
#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 <assert.h>
#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) )
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<nn; i++) {
op[i] = ip[i];
op[i] = (uint16_t)SWAP2(op[i]);
}
#if 0
char *op = dst;
const char *ip = src;
/* unroll the following to reduce loop overhead
*
* while (nn-- > 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<nn; i++) {
/* copy over, make the below swap in-place */
op[i] = ip[i];
op[i] = SWAP4(op[i]);
}
#if 0
char *op = dst;
const char *ip = src;
/* unroll the following to reduce loop overhead
* while (nn-- > 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 *op = (uint64_t*)dst;
/* copy over, make the below swap in-place */
*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<nn; i++) {
/* copy over, make the below swap in-place */
dst_p[i] = src_p[i];
uint32_t *op = (uint32_t*)(&dst_p[i]);
*op = SWAP4(*op);
op = (uint32_t*)((char*)op+4);
*op = SWAP4(*op);
}
#else
int i;
uint64_t *op = (uint64_t*) dst;
uint64_t *ip = (uint64_t*) src;
for (i=0; i<nn; i++) {
/* copy over, make the below swap in-place */
op[i] = ip[i];
op[i] = SWAP8(op[i]);
}
#endif
#if 0
char *op = dst;
const char *ip = src;
/* unroll the following to reduce loop overhead
* 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;
* }
*/
# 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);')
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);')
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;
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;
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',`dnl
*ip = FillDefaultValue($2);
DEBUG_RETURN_ERROR(NC_ERANGE)',`
DEBUG_ASSIGN_ERROR(err, NC_ERANGE)')
}'
`#'endif
`ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0,`dnl
if (xx < 0) {
ifdef(`ERANGE_FILL',`dnl
*ip = FillDefaultValue($2);
DEBUG_RETURN_ERROR(NC_ERANGE)',`
DEBUG_ASSIGN_ERROR(err, NC_ERANGE)') /* because ip is unsigned */
}')'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')',
`$2', `float', `if (*ip > (double)Xmax($1) || *ip < FXmin($1)) {
FillValue($1, &xx)
DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
} ifdef(`ERANGE_FILL',`else')')
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
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')
')')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', `dnl
if (fillp != NULL) memcpy(xp, fillp, 2);
#ifndef WORDS_BIGENDIAN
swapn2b(xp, xp, 1);
#endif
DEBUG_RETURN_ERROR(NC_ERANGE)',`dnl
DEBUG_ASSIGN_ERROR(err, NC_ERANGE)')
}
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;
*ip = *cp++ << 24;
#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', `dnl
if (fillp != NULL) memcpy(xp, fillp, 4);
#ifndef WORDS_BIGENDIAN
swapn4b(xp, xp, 1);
#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;')
if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
FillValue(float, &tmp)
ifdef(`ERANGE_FILL',`_ip = &tmp;')
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;
get_ix_double(xp, &xx);
if (xx > FLT_MAX) {
ifdef(`ERANGE_FILL', `*ip = NC_FILL_FLOAT;', `*ip = FLT_MAX;')
DEBUG_RETURN_ERROR(NC_ERANGE)
}
if (xx < (-FLT_MAX)) {
ifdef(`ERANGE_FILL', `*ip = NC_FILL_FLOAT;', `*ip = (-FLT_MAX);')
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
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;')
if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
FillValue(double, &tmp)
ifdef(`ERANGE_FILL',`_ip = &tmp;')
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)
{
/* 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);
/* similar to put_ix_int() */
uchar *cp = (uchar *) *xpp;
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);')
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);')
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<nelems && nrange==0; j+=LOOPCNT) {
ni=Min(nelems-j,LOOPCNT);
if (realign) {
memcpy(tmp, *xpp, (size_t)(ni*Isizeof($1)));
xp = tmp;
} else {
xp = ($1 *) *xpp;
}
/* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
for (i=0; i<ni; i++) {
tp[i] = ($2) Max( Imin($2), Min(Imax($2), ($2) xp[i]));
/* test for range errors (not always needed but do it anyway) */
/* if xpp is unsigned, we need not check if xp[i] < Imin */
/* if xpp is signed && tp is unsigned, we need check if xp[i] >= 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<nelems && nrange==0; j+=LOOPCNT) {
ni=Min(nelems-j,LOOPCNT);
if (realign) {
xp = tmp;
} else {
xp = ($1 *) *xpp;
}
/* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
for (i=0; i<ni; i++) {
ifelse( $1$2, intfloat,dnl
`dnl
/* for some reason int to float, for putn, requires a special case */
d = tp[i];
xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) d));
nrange += tp[i] > 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
}