netcdf-c/libsrc/ncx.m4

3788 lines
89 KiB
Plaintext
Raw Normal View History

dnl Process this m4 file to produce 'C' language file.
2010-06-03 21:24:43 +08:00
dnl
2016-10-13 15:15:45 +08:00
dnl This file is supposed to be the same as PnetCDF's ncx.m4
2010-06-03 21:24:43 +08:00
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.
2010-06-03 21:24:43 +08:00
*/
/* $Id: ncx.m4 2601 2016-11-07 04:54:42Z wkliao $ */
2010-06-03 21:24:43 +08:00
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
dnl
dnl If "ERANGE_FILL" is defined, the data elements that cause NC_ERANGE will
dnl be filled with the NC default fill values.
2016-10-06 13:36:54 +08:00
dnl
define(`SKIP_LOOP', `
#ifdef ERANGE_FILL
$1++; $2++; continue;
#endif')
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
dnl
2016-10-13 15:15:45 +08:00
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.
2016-10-06 13:36:54 +08:00
dnl
ifdef(`PNETCDF',`
`#'if HAVE_CONFIG_H
`#'include <ncconfig.h>
`#'endif',`
`#'if HAVE_CONFIG_H
`#'include <config.h>
`#'endif')
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
#include <stdio.h>
#include <stdlib.h>
2010-06-03 21:24:43 +08:00
#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(
2016-10-06 13:36:54 +08:00
`$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;')')
2016-10-06 13:36:54 +08:00
#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);')
#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
2016-10-06 13:36:54 +08:00
/*
* The only error code returned from subroutines in this file is NC_ERANGE,
* if errors are detected.
*/
/*
* An external data representation interface.
*/
2010-06-03 21:24:43 +08:00
/* 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
2012-07-17 06:31:35 +08:00
#ifndef LONG_LONG_MAX
#define LONG_LONG_MAX LLONG_MAX
2012-07-17 06:31:35 +08:00
#endif
2015-08-16 06:26:35 +08:00
#ifndef LONGLONG_MAX
#define LONGLONG_MAX LONG_LONG_MAX
#endif
2012-07-17 06:31:35 +08:00
#ifndef LONG_LONG_MIN
#define LONG_LONG_MIN LLONG_MIN
2012-07-17 06:31:35 +08:00
#endif
2015-08-16 06:26:35 +08:00
#ifndef LONGLONG_MIN
#define LONGLONG_MIN LONG_LONG_MIN
#endif
2012-07-17 06:31:35 +08:00
#ifndef ULONG_LONG_MAX
#define ULONG_LONG_MAX ULLONG_MAX
2012-07-17 06:31:35 +08:00
#endif
2015-08-16 06:26:35 +08:00
#ifndef ULONGLONG_MAX
#define ULONGLONG_MAX ULONG_LONG_MAX
#endif
2010-06-03 21:24:43 +08:00
#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))
2016-10-06 13:36:54 +08:00
#ifndef SIZEOF_UCHAR
#ifdef SIZEOF_UNSIGNED_CHAR
2016-10-06 13:36:54 +08:00
#define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR
#else
#error "unknown SIZEOF_UCHAR"
#endif
2016-10-06 13:36:54 +08:00
#endif
2015-08-16 06:26:35 +08:00
#ifndef SIZEOF_USHORT
#ifdef SIZEOF_UNSIGNED_SHORT_INT
2015-08-16 06:26:35 +08:00
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
#elif defined(SIZEOF_UNSIGNED_SHORT)
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT
#else
#error "unknown SIZEOF_USHORT"
#endif
2015-08-16 06:26:35 +08:00
#endif
2015-08-16 06:26:35 +08:00
#ifndef SIZEOF_UINT
#ifdef SIZEOF_UNSIGNED_INT
2015-08-16 06:26:35 +08:00
#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
#else
#error "unknown SIZEOF_UINT"
2015-08-16 06:26:35 +08:00
#endif
#endif
2016-10-06 13:36:54 +08:00
#ifndef SIZEOF_LONGLONG
#ifdef SIZEOF_LONG_LONG
2016-10-06 13:36:54 +08:00
#define SIZEOF_LONGLONG SIZEOF_LONG_LONG
#else
#error "unknown SIZEOF_LONGLONG"
#endif
2016-10-06 13:36:54 +08:00
#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
2016-10-06 13:36:54 +08:00
#ifndef SIZEOF_ULONGLONG
#ifdef SIZEOF_UNSIGNED_LONG_LONG
2016-10-06 13:36:54 +08:00
#define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG
#else
#error "unknown SIZEOF_ULONGLONG"
2015-08-16 06:26:35 +08:00
#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"
2015-08-16 06:26:35 +08:00
#endif
#endif
2010-06-03 21:24:43 +08:00
/*
* 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
2016-10-06 13:36:54 +08:00
#if defined(_SX) && _SX != 0 /* NEC SUPER UX */
2010-06-03 21:24:43 +08:00
#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 */
/*
2016-10-06 13:36:54 +08:00
* Routines to convert to BIG ENDIAN.
* Optimize the swapn?b() and swap?b() routines aggressively.
2010-06-03 21:24:43 +08:00
*/
#define SWAP2(a) ( (((a) & 0xff) << 8) | \
2016-10-06 13:36:54 +08:00
(((a) >> 8) & 0xff) )
2010-06-03 21:24:43 +08:00
#define SWAP4(a) ( ((a) << 24) | \
2016-10-06 13:36:54 +08:00
(((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
2016-10-06 13:36:54 +08:00
inline static void
swapn2b(void *dst, const void *src, IntType nn)
{
/* it is OK if dst == src */
2016-10-06 13:36:54 +08:00
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]);
2016-10-06 13:36:54 +08:00
}
#if 0
2010-06-03 21:24:43 +08:00
char *op = dst;
const char *ip = src;
/* unroll the following to reduce loop overhead
*
2016-10-06 13:36:54 +08:00
* while (nn-- > 0)
2010-06-03 21:24:43 +08:00
* {
* *op++ = *(++ip);
* *op++ = *(ip++ -1);
* }
2010-06-03 21:24:43 +08:00
*/
2016-10-06 13:36:54 +08:00
while (nn > 3)
2010-06-03 21:24:43 +08:00
{
*op++ = *(++ip);
*op++ = *(ip++ -1);
*op++ = *(++ip);
*op++ = *(ip++ -1);
*op++ = *(++ip);
*op++ = *(ip++ -1);
*op++ = *(++ip);
*op++ = *(ip++ -1);
nn -= 4;
}
2016-10-06 13:36:54 +08:00
while (nn-- > 0)
2010-06-03 21:24:43 +08:00
{
*op++ = *(++ip);
*op++ = *(ip++ -1);
}
2016-10-06 13:36:54 +08:00
#endif
2010-06-03 21:24:43 +08:00
}
# ifndef vax
2016-10-06 13:36:54 +08:00
inline static void
2010-06-03 21:24:43 +08:00
swap4b(void *dst, const void *src)
{
2016-10-06 13:36:54 +08:00
/* 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);
2016-10-06 13:36:54 +08:00
*(float *)dst = *(float *)(&tempOut);
#endif
2016-10-06 13:36:54 +08:00
/* 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];
*/
2010-06-03 21:24:43 +08:00
}
# endif /* !vax */
2016-10-06 13:36:54 +08:00
inline static void
swapn4b(void *dst, const void *src, IntType nn)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
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
2010-06-03 21:24:43 +08:00
char *op = dst;
const char *ip = src;
/* unroll the following to reduce loop overhead
2016-10-06 13:36:54 +08:00
* while (nn-- > 0)
2010-06-03 21:24:43 +08:00
* {
* op[0] = ip[3];
* op[1] = ip[2];
* op[2] = ip[1];
* op[3] = ip[0];
* op += 4;
* ip += 4;
* }
*/
2016-10-06 13:36:54 +08:00
while (nn > 3)
2010-06-03 21:24:43 +08:00
{
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;
}
2016-10-06 13:36:54 +08:00
while (nn-- > 0)
2010-06-03 21:24:43 +08:00
{
op[0] = ip[3];
op[1] = ip[2];
op[2] = ip[1];
op[3] = ip[0];
op += 4;
ip += 4;
}
2016-10-06 13:36:54 +08:00
#endif
2010-06-03 21:24:43 +08:00
}
# ifndef vax
2016-10-06 13:36:54 +08:00
inline static void
2010-06-03 21:24:43 +08:00
swap8b(void *dst, const void *src)
{
2016-10-06 13:36:54 +08:00
#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
2016-10-06 13:36:54 +08:00
uint64_t *op = (uint64_t*)dst;
*op = *(uint64_t*)src;
*op = SWAP8(*op);
*/
2016-10-06 13:36:54 +08:00
#endif
#if 0
2010-06-03 21:24:43 +08:00
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];
2016-10-06 13:36:54 +08:00
#endif
#endif
2010-06-03 21:24:43 +08:00
}
# endif /* !vax */
# ifndef vax
2016-10-06 13:36:54 +08:00
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
2010-06-03 21:24:43 +08:00
char *op = dst;
const char *ip = src;
/* unroll the following to reduce loop overhead
2016-10-06 13:36:54 +08:00
* while (nn-- > 0)
2010-06-03 21:24:43 +08:00
* {
* 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
2016-10-06 13:36:54 +08:00
while (nn > 1)
2010-06-03 21:24:43 +08:00
{
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;
}
2016-10-06 13:36:54 +08:00
while (nn-- > 0)
2010-06-03 21:24:43 +08:00
{
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
2016-10-06 13:36:54 +08:00
while (nn-- > 0)
2010-06-03 21:24:43 +08:00
{
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;
}
2016-10-06 13:36:54 +08:00
#endif
#endif
2010-06-03 21:24:43 +08:00
}
# endif /* !vax */
#endif /* LITTLE_ENDIAN */
2015-08-16 06:26:35 +08:00
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
2016-10-06 13:36:54 +08:00
define(`Dmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl
2015-08-16 06:26:35 +08:00
define(`FXmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Xmin($1)')')dnl
define(`DXmin', `ifelse(index(`$1',`u'), 0, `0', `Xmin($1)')')dnl
2016-10-06 13:36:54 +08:00
define(`Cast_Signed2Unsigned',
`ifelse(index(`$1',`u'), 0,
`ifelse(index(`$2',`u'), 0, , `(signed)')')')dnl
2015-08-16 06:26:35 +08:00
dnl
2016-10-06 13:36:54 +08:00
dnl For GET APIs boundary check
2015-08-16 06:26:35 +08:00
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
2016-10-06 13:36:54 +08:00
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)
}
2016-10-06 13:36:54 +08:00
else *ip = ($1)xx;')
2010-06-03 21:24:43 +08:00
/*
* Primitive numeric conversion functions.
*/
2015-08-16 06:26:35 +08:00
dnl dnl dnl
dnl
dnl NCX_GET1F(xtype, itype) for floating-point types
dnl
define(`NCX_GET1F',dnl
`dnl
2016-10-06 13:36:54 +08:00
static int
APIPrefix`x_get_'NC_TYPE($1)_$2(const void *xp, $2 *ip)
2015-08-16 06:26:35 +08:00
{
ix_$1 xx = 0;
2015-08-16 06:26:35 +08:00
get_ix_$1(xp, &xx);
2016-10-06 13:36:54 +08:00
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;
2015-08-16 06:26:35 +08:00
}
')dnl
dnl dnl dnl
dnl
dnl NCX_GET1I(xtype, itype, isComptable) for integral types
dnl
define(`NCX_GET1I',dnl
`dnl
2016-10-06 13:36:54 +08:00
static int
APIPrefix`x_get_'NC_TYPE($1)_$2(const void *xp, $2 *ip)
2015-08-16 06:26:35 +08:00
{
int err=NC_NOERR;
2015-08-16 06:26:35 +08:00
ifelse(`$3', `1',
``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX
2016-10-13 15:15:45 +08:00
get_ix_$1(xp, (ix_$1 *)ip);
2015-08-16 06:26:35 +08:00
`#'else
')dnl
ix_$1 xx = 0;
2016-10-13 15:15:45 +08:00
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
2016-10-13 15:15:45 +08:00
*ip = ($2) xx;
`ifelse(`$3', `1', ``#'endif
2015-08-16 06:26:35 +08:00
')dnl
return err;
2015-08-16 06:26:35 +08:00
}
')dnl
dnl dnl dnl
dnl
dnl NCX_PUT1F(xtype, itype) for floating-point types
dnl
define(`NCX_PUT1F',dnl
`dnl
2016-10-06 13:36:54 +08:00
static int
APIPrefix`x_put_'NC_TYPE($1)_$2(void *xp, const $2 *ip, void *fillp)
2015-08-16 06:26:35 +08:00
{
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;
2015-08-16 06:26:35 +08:00
}
')dnl
dnl dnl dnl
dnl
dnl NCX_PUT1I(xtype, itype, isComptable) for integral types
dnl
define(`NCX_PUT1I',dnl
`dnl
2016-10-06 13:36:54 +08:00
static int
APIPrefix`x_put_'NC_TYPE($1)_$2(void *xp, const $2 *ip, void *fillp)
2015-08-16 06:26:35 +08:00
{
int err=NC_NOERR;
2015-08-16 06:26:35 +08:00
ifelse(`$3', `1',
``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX
2016-10-13 15:15:45 +08:00
put_ix_$1(xp, (const ix_$1 *)ip);
2015-08-16 06:26:35 +08:00
`#'else
')dnl
ix_$1 xx = FillDefaultValue($1);
2016-10-13 15:15:45 +08:00
`#'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;
2016-10-13 15:15:45 +08:00
put_ix_$1(xp, &xx);
2015-08-16 06:26:35 +08:00
ifelse(`$3', `1', ``#'endif
')dnl
return err;
2015-08-16 06:26:35 +08:00
}
')dnl
2010-06-03 21:24:43 +08:00
/* x_schar */
2015-08-16 06:26:35 +08:00
/* x_uchar */
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
/* We don't implement any x_schar and x_uchar primitives. */
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_SHORT --------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#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;
2016-10-06 13:36:54 +08:00
#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
#define IX_SHORT_MAX LLONG_MAX
2010-06-03 21:24:43 +08:00
#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);
2010-06-03 21:24:43 +08:00
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
2016-10-06 13:36:54 +08:00
if (*ip & 0x8000)
2010-06-03 21:24:43 +08:00
{
/* extern is negative */
*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
}
#endif
*ip = (ix_short)(*ip | *cp);
2010-06-03 21:24:43 +08:00
}
static void
put_ix_short(void *xp, const ix_short *ip)
{
uchar *cp = (uchar *) xp;
*cp++ = (uchar)((*ip) >> 8);
*cp = (uchar)((*ip) & 0xff);
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(short)_schar(void *xp, const schar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
uchar *cp = (uchar *) xp;
2016-10-06 13:36:54 +08:00
if (*ip & 0x80)
2010-06-03 21:24:43 +08:00
*cp++ = 0xff;
else
*cp++ = 0;
2016-10-06 13:36:54 +08:00
*cp = (uchar)*ip;
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(short)_uchar(void *xp, const uchar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
uchar *cp = (uchar *) xp;
*cp++ = 0;
*cp = *ip;
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_USHORT -------------------------------------------------------*/
2015-08-16 06:26:35 +08:00
#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;
2016-10-06 13:36:54 +08:00
#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
2015-08-16 06:26:35 +08:00
#define IX_USHORT_MAX ULLONG_MAX
2010-06-03 21:24:43 +08:00
#else
2015-08-16 06:26:35 +08:00
#error "ix_ushort implementation"
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
static void
get_ix_ushort(const void *xp, ix_ushort *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
const uchar *cp = (const uchar *) xp;
*ip = (ix_ushort)(*cp++ << 8);
2015-08-16 06:26:35 +08:00
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
2016-10-06 13:36:54 +08:00
if (*ip & 0x8000)
2015-08-16 06:26:35 +08:00
{
/* extern is negative */
*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
}
2010-06-03 21:24:43 +08:00
#endif
*ip = (ix_ushort)(*ip | *cp);
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static void
put_ix_ushort(void *xp, const ix_ushort *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
uchar *cp = (uchar *) xp;
*cp++ = (uchar)((*ip) >> 8);
*cp = (uchar)((*ip) & 0xff);
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(ushort)_schar(void *xp, const schar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
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
}
2010-06-03 21:24:43 +08:00
cp = (uchar *) xp;
if (*ip & 0x80)
*cp++ = 0xff;
else
*cp++ = 0;
*cp = (uchar)*ip;
return err;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(ushort)_uchar(void *xp, const uchar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
uchar *cp = (uchar *) xp;
*cp++ = 0;
*cp = *ip;
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_INT ----------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#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
2010-06-03 21:24:43 +08:00
*ip = *cp++ << 24;
#endif
2010-06-03 21:24:43 +08:00
#if SIZEOF_IX_INT > X_SIZEOF_INT
2016-10-06 13:36:54 +08:00
if (*ip & 0x80000000)
2010-06-03 21:24:43 +08:00
{
/* extern is negative */
*ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
}
#endif
*ip |= (*cp++ << 16);
*ip |= (*cp++ << 8);
*ip |= *cp;
2010-06-03 21:24:43 +08:00
}
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);
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
#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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(int)_schar(void *xp, const schar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
uchar *cp = (uchar *) xp;
2016-10-06 13:36:54 +08:00
if (*ip & 0x80)
2010-06-03 21:24:43 +08:00
{
*cp++ = 0xff;
*cp++ = 0xff;
*cp++ = 0xff;
}
else
{
*cp++ = 0x00;
*cp++ = 0x00;
*cp++ = 0x00;
}
*cp = (uchar)*ip;
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(int)_uchar(void *xp, const uchar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
uchar *cp = (uchar *) xp;
*cp++ = 0x00;
*cp++ = 0x00;
*cp++ = 0x00;
*cp = *ip;
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
#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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_UINT ---------------------------------------------------------*/
2015-08-16 06:26:35 +08:00
#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
2010-06-03 21:24:43 +08:00
#else
2015-08-16 06:26:35 +08:00
#error "ix_uint implementation"
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
static void
get_ix_uint(const void *xp, ix_uint *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
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);
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static void
put_ix_uint(void *xp, const ix_uint *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
uchar *cp = (uchar *) xp;
*cp++ = (uchar)((*ip) >> 24);
*cp++ = (uchar)(((*ip) & 0x00ff0000) >> 16);
*cp++ = (uchar)(((*ip) & 0x0000ff00) >> 8);
*cp = (uchar)( (*ip) & 0x000000ff);
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#if X_SIZEOF_UINT != SIZEOF_UINT
2016-10-06 13:36:54 +08:00
NCX_GET1I(uint, uint, 1)
2010-06-03 21:24:43 +08:00
#endif
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(uint)_schar(void *xp, const schar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
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)
}
2015-08-16 06:26:35 +08:00
cp = (uchar *) xp;
*cp++ = 0x00;
*cp++ = 0x00;
*cp++ = 0x00;
*cp = (uchar)*ip;
2015-08-16 06:26:35 +08:00
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(uint)_uchar(void *xp, const uchar *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
uchar *cp = (uchar *) xp;
*cp++ = 0x00;
*cp++ = 0x00;
*cp++ = 0x00;
*cp = *ip;
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#if X_SIZEOF_UINT != SIZEOF_UINT
2016-10-06 13:36:54 +08:00
NCX_PUT1I(uint, uint, 1)
2015-08-16 06:26:35 +08:00
#endif
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_FLOAT --------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
2016-10-06 13:36:54 +08:00
inline static void
2010-06-03 21:24:43 +08:00
get_ix_float(const void *xp, float *ip)
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(ip, xp, SIZEOF_FLOAT);
2010-06-03 21:24:43 +08:00
#else
swap4b(ip, xp);
#endif
}
2016-10-06 13:36:54 +08:00
inline static void
2010-06-03 21:24:43 +08:00
put_ix_float(void *xp, const float *ip)
{
#ifdef WORDS_BIGENDIAN
(void) memcpy(xp, ip, X_SIZEOF_FLOAT);
#else
swap4b(xp, ip);
#endif
}
2016-10-06 13:36:54 +08:00
#elif defined(vax) && vax != 0
2010-06-03 21:24:43 +08:00
/* 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 */
2016-10-06 13:36:54 +08:00
if (isp->mant_hi == min.ieee.mant_hi
2010-06-03 21:24:43 +08:00
&& 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;
2016-10-06 13:36:54 +08:00
if (tmp >= 4) {
2010-06-03 21:24:43 +08:00
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 */
2016-10-06 13:36:54 +08:00
if (vsp->mantissa2 == max.s.mantissa2 &&
vsp->mantissa1 == max.s.mantissa1)
2010-06-03 21:24:43 +08:00
{
/* 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,
2010-06-03 21:24:43 +08:00
* 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;
2016-10-06 13:36:54 +08:00
if (isp->exp == 0)
2010-06-03 21:24:43 +08:00
{
/* ieee subnormal */
*ip = (double)isp->mant;
2016-10-06 13:36:54 +08:00
if (isp->mant != 0)
2010-06-03 21:24:43 +08:00
{
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;
2016-10-06 13:36:54 +08:00
if (ieee_exp >= 0xff)
2010-06-03 21:24:43 +08:00
{
/* NC_ERANGE => ieee Inf */
isp->exp = 0xff;
isp->mant = 0x0;
}
2016-10-06 13:36:54 +08:00
else if (ieee_exp > 0)
2010-06-03 21:24:43 +08:00
{
/* 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));
}
2016-10-06 13:36:54 +08:00
else if (ieee_exp > -23)
2010-06-03 21:24:43 +08:00
{
/* ieee subnormal, right shift */
const int rshift = (48 - 23 - ieee_exp);
isp->mant = csp->mant >> rshift;
#if 0
2016-10-06 13:36:54 +08:00
if (csp->mant & (1 << (rshift -1)))
2010-06-03 21:24:43 +08:00
{
/* 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)
{
2016-10-06 13:36:54 +08:00
if (word_align(xp) == 0)
2010-06-03 21:24:43 +08:00
{
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)
{
2016-10-06 13:36:54 +08:00
if (word_align(xp) == 0)
2010-06-03 21:24:43 +08:00
{
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;
2016-10-06 13:36:54 +08:00
if (word_align(xp) == 0)
2010-06-03 21:24:43 +08:00
{
const ieee_single_hi *isp = (const ieee_single_hi *) xp;
2016-10-06 13:36:54 +08:00
if (isp->exp == 0 && isp->mant == 0)
2010-06-03 21:24:43 +08:00
{
idp->exp = 0;
idp->mant = 0;
}
else
{
idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
2015-08-16 06:26:35 +08:00
idp->mant = isp->mant << (52 - 23);
}
idp->sign = isp->sign;
}
else
{
const ieee_single_lo *isp = (const ieee_single_lo *) xp;
2016-10-06 13:36:54 +08:00
if (isp->exp == 0 && isp->mant == 0)
2015-08-16 06:26:35 +08:00
{
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;
}
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static void
put_ix_float(void *xp, const float *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
const ieee_double *idp = (const ieee_double *) ip;
2016-10-06 13:36:54 +08:00
if (word_align(xp) == 0)
2015-08-16 06:26:35 +08:00
{
ieee_single_hi *isp = (ieee_single_hi*)xp;
2016-10-06 13:36:54 +08:00
if (idp->exp > (ieee_double_bias - ieee_single_bias))
2015-08-16 06:26:35 +08:00
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;
2016-10-06 13:36:54 +08:00
if (idp->exp > (ieee_double_bias - ieee_single_bias))
2015-08-16 06:26:35 +08:00
isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
else
isp->exp = 0;
isp->mant = idp->mant >> (52 - 23);
isp->sign = idp->sign;
}
2010-06-03 21:24:43 +08:00
}
#endif
2015-08-16 06:26:35 +08:00
#else
#error "ix_float implementation"
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
/* TODO */
get_ix_float(xp, ip);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#endif
2015-08-16 06:26:35 +08:00
#define ix_float float
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
int err=NC_NOERR;
float *_ip=ip;
2010-06-03 21:24:43 +08:00
#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)
}
2010-06-03 21:24:43 +08:00
#endif
put_ix_float(xp, _ip);
return err;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#endif
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_DOUBLE -------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
static void
get_ix_double(const void *xp, double *ip)
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(ip, xp, SIZEOF_DOUBLE);
2010-06-03 21:24:43 +08:00
#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
}
2016-10-06 13:36:54 +08:00
#elif defined(vax) && vax != 0
2010-06-03 21:24:43 +08:00
/* 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 =
2010-06-03 21:24:43 +08:00
(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);
2016-10-06 13:36:54 +08:00
if ((vdp->mantissa4 & 7) > 4)
2010-06-03 21:24:43 +08:00
{
/* round up */
mant_lo++;
2016-10-06 13:36:54 +08:00
if (mant_lo == 0)
2010-06-03 21:24:43 +08:00
{
mant_hi++;
2016-10-06 13:36:54 +08:00
if (mant_hi > 0xffffff)
2010-06-03 21:24:43 +08:00
{
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;
}
2010-06-03 21:24:43 +08:00
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;
2016-10-06 13:36:54 +08:00
if (idp->exp == 0)
2010-06-03 21:24:43 +08:00
{
/* ieee subnormal */
*ip = (double)idp->mant;
2016-10-06 13:36:54 +08:00
if (idp->mant != 0)
2010-06-03 21:24:43 +08:00
{
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;
2016-10-06 13:36:54 +08:00
if (ieee_exp >= 0x7ff)
2010-06-03 21:24:43 +08:00
{
/* NC_ERANGE => ieee Inf */
idp->exp = 0x7ff;
idp->mant = 0x0;
}
2016-10-06 13:36:54 +08:00
else if (ieee_exp > 0)
2010-06-03 21:24:43 +08:00
{
/* 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));
}
2016-10-06 13:36:54 +08:00
else if (ieee_exp >= (-(52 -48)))
2010-06-03 21:24:43 +08:00
{
/* ieee subnormal, left shift */
const int lshift = (52 - 48) + ieee_exp;
idp->mant = csp->mant << lshift;
idp->exp = 0;
}
2016-10-06 13:36:54 +08:00
else if (ieee_exp >= -52)
2010-06-03 21:24:43 +08:00
{
/* ieee subnormal, right shift */
const int rshift = (- (52 - 48) - ieee_exp);
idp->mant = csp->mant >> rshift;
#if 0
2016-10-06 13:36:54 +08:00
if (csp->mant & (1 << (rshift -1)))
2010-06-03 21:24:43 +08:00
{
/* 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
2015-08-16 06:26:35 +08:00
#define ix_double double
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_get_'NC_TYPE(double)_float(const void *xp, float *ip)
2010-06-03 21:24:43 +08:00
{
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;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
/* TODO */
get_ix_double(xp, ip);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#endif
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
static int
APIPrefix`x_put_'NC_TYPE(double)_float(void *xp, const float *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
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
2010-06-03 21:24:43 +08:00
#endif
xx = (double) *ip;
put_ix_double(xp, &xx);
return err;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
int err=NC_NOERR;
double *_ip = ip;
2015-08-16 06:26:35 +08:00
#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)
}
2010-06-03 21:24:43 +08:00
#endif
put_ix_double(xp, _ip);
return err;
2010-06-03 21:24:43 +08:00
}
#endif
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* external NC_INT64 --------------------------------------------------------*/
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
#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
2015-08-16 06:26:35 +08:00
#else
2016-10-06 13:36:54 +08:00
#error "ix_int64 implementation"
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
static void
2016-10-06 13:36:54 +08:00
get_ix_int64(const void *xp, ix_int64 *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
const uchar *cp = (const uchar *) xp;
2016-10-06 13:36:54 +08:00
*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;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static void
2016-10-06 13:36:54 +08:00
put_ix_int64(void *xp, const ix_int64 *ip)
2015-08-16 06:26:35 +08:00
{
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);
2015-08-16 06:26:35 +08:00
}
2016-10-06 13:36:54 +08:00
#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
2015-08-16 06:26:35 +08:00
#else
2016-10-06 13:36:54 +08:00
#error "ix_uint64 implementation"
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
static void
2016-10-06 13:36:54 +08:00
get_ix_uint64(const void *xp, ix_uint64 *ip)
2010-06-03 21:24:43 +08:00
{
2015-08-16 06:26:35 +08:00
const uchar *cp = (const uchar *) xp;
2016-10-06 13:36:54 +08:00
*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;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
static void
2016-10-06 13:36:54 +08:00
put_ix_uint64(void *xp, const ix_uint64 *ip)
2015-08-16 06:26:35 +08:00
{
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);
2015-08-16 06:26:35 +08:00
}
2016-10-06 13:36:54 +08:00
#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)
2010-06-03 21:24:43 +08:00
/* 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
2016-10-06 13:36:54 +08:00
APIPrefix`x_put_size_t'(void **xpp, const size_t *ulp)
2010-06-03 21:24:43 +08:00
{
/* 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;
2010-06-03 21:24:43 +08:00
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_get_size_t'(const void **xpp, size_t *ulp)
2010-06-03 21:24:43 +08:00
{
/* similar to get_ix_int */
const uchar *cp = (const uchar *) *xpp;
*ulp = (unsigned)(*cp++) << 24;
*ulp |= (*cp++ << 16);
*ulp |= (*cp++ << 8);
*ulp |= *cp;
2010-06-03 21:24:43 +08:00
*xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
/* x_off_t */
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_put_off_t'(void **xpp, const off_t *lp, size_t sizeof_off_t)
2010-06-03 21:24:43 +08:00
{
/* similar to put_ix_int() */
uchar *cp = (uchar *) *xpp;
2016-10-06 13:36:54 +08:00
/* No negative offsets stored in netcdf */
2010-06-03 21:24:43 +08:00
if (*lp < 0) {
/* Assume this is an overflow of a 32-bit int... */
2016-10-06 13:36:54 +08:00
DEBUG_RETURN_ERROR(NC_ERANGE)
2010-06-03 21:24:43 +08:00
}
2010-06-03 21:24:43 +08:00
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);
2016-10-06 13:36:54 +08:00
*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);
2010-06-03 21:24:43 +08:00
#endif
}
*xpp = (void *)((char *)(*xpp) + sizeof_off_t);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_get_off_t'(const void **xpp, off_t *lp, size_t sizeof_off_t)
2010-06-03 21:24:43 +08:00
{
/* 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;
2010-06-03 21:24:43 +08:00
} 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) {
2016-10-06 13:36:54 +08:00
DEBUG_RETURN_ERROR(NC_ERANGE)
2010-06-03 21:24:43 +08:00
}
*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
*/
2016-10-06 13:36:54 +08:00
DEBUG_RETURN_ERROR(NC_ERANGE)
2010-06-03 21:24:43 +08:00
}
#else
2015-08-16 06:26:35 +08:00
*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;
2015-08-16 06:26:35 +08:00
}
2016-10-06 13:36:54 +08:00
/*----< APIPrefix`x_get_uint32'() >------------------------------------------*/
2015-08-16 06:26:35 +08:00
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_get_uint32'(const void **xpp, uint *ip)
2015-08-16 06:26:35 +08:00
{
2016-10-06 13:36:54 +08:00
#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);
2016-10-06 13:36:54 +08:00
#else
2015-08-16 06:26:35 +08:00
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);
2016-10-06 13:36:54 +08:00
#endif
2015-08-16 06:26:35 +08:00
/* advance *xpp 4 bytes */
*xpp = (void *)((const char *)(*xpp) + 4);
return NC_NOERR;
}
2016-10-06 13:36:54 +08:00
/*----< APIPrefix`x_get_uint64'() >------------------------------------------*/
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_get_uint64'(const void **xpp, unsigned long long *ullp)
2015-08-16 06:26:35 +08:00
{
2016-10-06 13:36:54 +08:00
#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);
2016-10-06 13:36:54 +08:00
#else
2015-08-16 06:26:35 +08:00
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));
2016-10-06 13:36:54 +08:00
#endif
2015-08-16 06:26:35 +08:00
/* advance *xpp 8 bytes */
*xpp = (void *)((const char *)(*xpp) + 8);
return NC_NOERR;
}
2016-10-06 13:36:54 +08:00
/*---< APIPrefix`x_put_uint32'() >-------------------------------------------*/
/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
2015-08-16 06:26:35 +08:00
* form and advance *xpp 4 bytes
*/
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_put_uint32'(void **xpp, const unsigned int ip)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
/* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
* some system, such as HPUX */
(void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
2015-08-16 06:26:35 +08:00
#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;
}
2016-10-06 13:36:54 +08:00
/*---< APIPrefix`x_put_uint64'() >-------------------------------------------*/
/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
2015-08-16 06:26:35 +08:00
* form and advance *xpp 8 bytes
*/
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_put_uint64'(void **xpp, const unsigned long long ip)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
/* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
* some system, such as HPUX */
(void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
2015-08-16 06:26:35 +08:00
#else
uchar *cp = (uchar *) *xpp;
/* below is the same as calling swap8b(*xpp, &ip) */
2016-10-06 13:36:54 +08:00
*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);
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
/* advance *xpp 8 bytes */
*xpp = (void *)((char *)(*xpp) + 8);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
/*
* Aggregate numeric conversion functions.
*/
dnl
2016-10-06 13:36:54 +08:00
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
2015-08-16 06:26:35 +08:00
2010-06-03 21:24:43 +08:00
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
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems);
*xpp = (void *)((char *)(*xpp) + nelems);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
')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
2016-10-06 13:36:54 +08:00
IntType rndup = nelems % X_ALIGN;
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
if (rndup)
2010-06-03 21:24:43 +08:00
rndup = X_ALIGN - rndup;
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems);
*xpp = (void *)((char *)(*xpp) + nelems + rndup);
2010-06-03 21:24:43 +08:00
return NC_NOERR;
2010-06-03 21:24:43 +08:00
')dnl
dnl dnl dnl
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_GETN_BYTE(xtype, itype)
2010-06-03 21:24:43 +08:00
dnl
2016-10-06 13:36:54 +08:00
define(`NCX_GETN_BYTE',dnl
2010-06-03 21:24:43 +08:00
`dnl
int
APIPrefix`x_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp)
2010-06-03 21:24:43 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
$1 *xp = ($1 *)(*xpp);
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
while (nelems-- != 0) {
ifelse(index(`$1',`u'), 0, ,
index(`$2',`u'), 0, `
if (*xp < 0) {
#ifdef ERANGE_FILL
*tp = FillDefaultValue($2);
#endif
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}')dnl
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
*tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */
}
*xpp = (const void *)xp;
return status;
2010-06-03 21:24:43 +08:00
}
')dnl
dnl dnl dnl
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_GETN_BYTE(xtype, itype)
2010-06-03 21:24:43 +08:00
dnl
2016-10-06 13:36:54 +08:00
define(`NCX_PAD_GETN_BYTE',dnl
2010-06-03 21:24:43 +08:00
`dnl
int
APIPrefix`x_pad_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp)
2010-06-03 21:24:43 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
IntType rndup = nelems % X_ALIGN;
$1 *xp = ($1 *) *xpp;
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
if (rndup)
rndup = X_ALIGN - rndup;
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
while (nelems-- != 0) {
ifelse(index(`$1',`u'), 0, ,
index(`$2',`u'), 0, `
if (*xp < 0) {
#ifdef ERANGE_FILL
*tp = FillDefaultValue($2);
#endif
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}')dnl
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
*tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */
}
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (void *)(xp + rndup);
return status;
2010-06-03 21:24:43 +08:00
}
')dnl
dnl dnl dnl
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_GETN(xtype, itype)
2010-06-03 21:24:43 +08:00
dnl
define(`NCX_GETN',dnl
`dnl
int
APIPrefix`x_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
`#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1)
2010-06-03 21:24:43 +08:00
/* 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) {
2016-10-06 13:36:54 +08:00
memcpy(tmp, *xpp, (size_t)(ni*Isizeof($1)));
2010-06-03 21:24:43 +08:00
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) */
2015-08-16 06:26:35 +08:00
/* 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);
2010-06-03 21:24:43 +08:00
}
/* update xpp and tp */
if (realign) xp = ($1 *) *xpp;
xp += ni;
tp += ni;
*xpp = (void*)xp;
}
return nrange == 0 ? NC_NOERR : NC_ERANGE;
2010-06-03 21:24:43 +08:00
#else /* not SX */
const char *xp = (const char *) *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
{
const int lstatus = APIPrefix`x_get_'NC_TYPE($1)_$2(xp, tp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
*xpp = (const void *)xp;
return status;
2016-10-06 13:36:54 +08:00
#endif
2010-06-03 21:24:43 +08:00
}
')dnl
dnl dnl dnl
dnl
2015-08-16 06:26:35 +08:00
dnl NCX_PAD_GETN_SHORT(xtype ttype)
2010-06-03 21:24:43 +08:00
dnl
define(`NCX_PAD_GETN_SHORT',dnl
`dnl
int
APIPrefix`x_pad_getn_'NC_TYPE($1)_$2(const void **xpp, IntType nelems, $2 *tp)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
const IntType rndup = nelems % X_SIZEOF_SHORT;
2010-06-03 21:24:43 +08:00
const char *xp = (const char *) *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
2010-06-03 21:24:43 +08:00
{
const int lstatus = APIPrefix`x_get_'NC_TYPE($1)_$2(xp, tp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
2016-10-06 13:36:54 +08:00
if (rndup != 0)
2015-08-16 06:26:35 +08:00
xp += Xsizeof($1);
2016-10-06 13:36:54 +08:00
2010-06-03 21:24:43 +08:00
*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
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems);
2010-06-03 21:24:43 +08:00
*xpp = (void *)((char *)(*xpp) + nelems);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
')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
2016-10-06 13:36:54 +08:00
IntType rndup = nelems % X_ALIGN;
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
if (rndup)
2010-06-03 21:24:43 +08:00
rndup = X_ALIGN - rndup;
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems);
2010-06-03 21:24:43 +08:00
*xpp = (void *)((char *)(*xpp) + nelems);
2016-10-06 13:36:54 +08:00
if (rndup)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, nada, (size_t)rndup);
2010-06-03 21:24:43 +08:00
*xpp = (void *)((char *)(*xpp) + rndup);
}
return NC_NOERR;
2010-06-03 21:24:43 +08:00
`dnl
')dnl
dnl dnl dnl
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_PUTN_BYTE(xtype, itype)
2010-06-03 21:24:43 +08:00
dnl
2016-10-06 13:36:54 +08:00
define(`NCX_PUTN_BYTE',dnl
2010-06-03 21:24:43 +08:00
`dnl
int
APIPrefix`x_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
$1 *xp = ($1 *) *xpp;
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
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)
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}
*xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */
}
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (void *)xp;
return status;
2010-06-03 21:24:43 +08:00
}
')dnl
dnl dnl dnl
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_PUTN_BYTE(xtype, ttype)
2010-06-03 21:24:43 +08:00
dnl
2016-10-06 13:36:54 +08:00
define(`NCX_PAD_PUTN_BYTE',dnl
2010-06-03 21:24:43 +08:00
`dnl
int
APIPrefix`x_pad_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
IntType rndup = nelems % X_ALIGN;
$1 *xp = ($1 *) *xpp;
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
if (rndup) rndup = X_ALIGN - rndup;
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
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)
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}
*xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */
}
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
if (rndup) {
(void) memcpy(xp, nada, (size_t)rndup);
xp += rndup;
}
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (void *)xp;
return status;
2010-06-03 21:24:43 +08:00
}
')dnl
dnl dnl dnl
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_PUTN(xtype, itype)
2010-06-03 21:24:43 +08:00
dnl
define(`NCX_PUTN',dnl
`dnl
int
APIPrefix`x_putn_'NC_TYPE($1)_$2(void **xpp, IntType nelems, const $2 *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
`#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1)
2010-06-03 21:24:43 +08:00
/* 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
2016-10-06 13:36:54 +08:00
double d; /* special case for APIPrefix`x_putn_int_float' */
2010-06-03 21:24:43 +08:00
')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 */
2010-06-03 21:24:43 +08:00
d = tp[i];
xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) d));
2015-08-16 06:26:35 +08:00
nrange += tp[i] > Xmax($1) PUTN_CheckBND($1, $2);
2010-06-03 21:24:43 +08:00
',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) */
2015-08-16 06:26:35 +08:00
/* 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);
2010-06-03 21:24:43 +08:00
')dnl
}
/* copy workspace back if necessary */
2010-06-03 21:24:43 +08:00
if (realign) {
2016-10-06 13:36:54 +08:00
memcpy(*xpp, tmp, (size_t)*ni*Xsizeof($1));
2010-06-03 21:24:43 +08:00
xp = ($1 *) *xpp;
}
/* update xpp and tp */
xp += ni;
tp += ni;
*xpp = (void*)xp;
}
return nrange == 0 ? NC_NOERR : NC_ERANGE;
2010-06-03 21:24:43 +08:00
#else /* not SX */
char *xp = (char *) *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
{
int lstatus = APIPrefix`x_put_'NC_TYPE($1)_$2(xp, tp, fillp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
*xpp = (void *)xp;
return status;
#endif
}
')dnl
dnl dnl dnl
dnl
2015-08-16 06:26:35 +08:00
dnl NCX_PAD_PUTN_SHORT(xtype, ttype)
2010-06-03 21:24:43 +08:00
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)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
const IntType rndup = nelems % X_SIZEOF_SHORT;
2010-06-03 21:24:43 +08:00
char *xp = (char *) *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
2010-06-03 21:24:43 +08:00
{
int lstatus = APIPrefix`x_put_'NC_TYPE($1)_$2(xp, tp, fillp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
2016-10-06 13:36:54 +08:00
if (rndup != 0)
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
(void) memcpy(xp, nada, (size_t)(Xsizeof($1)));
2015-08-16 06:26:35 +08:00
xp += Xsizeof($1);
2010-06-03 21:24:43 +08:00
}
2010-06-03 21:24:43 +08:00
*xpp = (void *)xp;
return status;
}
')dnl
dnl dnl dnl
dnl
dnl Declare & define routines
dnl
dnl dnl dnl
2015-08-16 06:26:35 +08:00
/* schar ---------------------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_GETN_BYTE(schar, schar)
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_getn_'NC_TYPE(schar)_schar(const void **xpp, IntType nelems, schar *tp)
2010-06-03 21:24:43 +08:00
{
NCX_GETN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_GETN_BYTE(schar, schar)
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_pad_getn_'NC_TYPE(schar)_schar(const void **xpp, IntType nelems, schar *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PAD_GETN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_PUTN_BYTE(schar, schar)
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_putn_'NC_TYPE(schar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
NCX_PUTN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_PUTN_BYTE(schar, schar)
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_pad_putn_'NC_TYPE(schar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
NCX_PAD_PUTN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
/* uchar ---------------------------------------------------------------------*/
dnl
2016-10-06 13:36:54 +08:00
dnl NCX_GETN_BYTE(uchar, schar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_getn_'NC_TYPE(uchar)_schar(const void **xpp, IntType nelems, schar *tp)
2015-08-16 06:26:35 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
uchar *xp = (uchar *)(*xpp);
2016-10-06 13:36:54 +08:00
2016-10-13 15:15:45 +08:00
while (nelems-- != 0) {
if (*xp > SCHAR_MAX) {
*tp = NC_FILL_BYTE;
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}
*tp++ = (schar) *xp++; /* type cast from uchar to schar */
}
2016-10-06 13:36:54 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (const void *)xp;
return status;
2015-08-16 06:26:35 +08:00
}
2016-10-06 13:36:54 +08:00
dnl NCX_GETN_BYTE(uchar, uchar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_getn_'NC_TYPE(uchar)_uchar(const void **xpp, IntType nelems, uchar *tp)
2015-08-16 06:26:35 +08:00
{
NCX_GETN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_GETN_BYTE(uchar, schar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_pad_getn_'NC_TYPE(uchar)_schar(const void **xpp, IntType nelems, schar *tp)
2015-08-16 06:26:35 +08:00
{
2016-10-13 15:15:45 +08:00
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;
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
SKIP_LOOP(xp, tp)
2016-10-06 13:36:54 +08:00
}
2016-10-13 15:15:45 +08:00
*tp++ = (schar) *xp++; /* type cast from uchar to schar */
}
2010-06-03 21:24:43 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (void *)(xp + rndup);
return status;
2015-08-16 06:26:35 +08:00
}
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_GETN_BYTE(uchar, uchar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_pad_getn_'NC_TYPE(uchar)_uchar(const void **xpp, IntType nelems, uchar *tp)
2015-08-16 06:26:35 +08:00
{
NCX_PAD_GETN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_PUTN_BYTE(uchar, schar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_putn_'NC_TYPE(uchar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp)
2015-08-16 06:26:35 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
uchar *xp = (uchar *) *xpp;
2016-10-06 13:36:54 +08:00
2016-10-13 15:15:45 +08:00
while (nelems-- != 0) {
if (*tp < 0) {
FillValue(uchar, xp)
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}
*xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
}
2015-08-16 06:26:35 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (void *)xp;
return status;
2015-08-16 06:26:35 +08:00
}
2016-10-06 13:36:54 +08:00
dnl NCX_PUTN_BYTE(uchar, uchar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_putn_'NC_TYPE(uchar)_uchar(void **xpp, IntType nelems, const uchar *tp, void *fillp)
2015-08-16 06:26:35 +08:00
{
NCX_PUTN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
dnl NCX_PAD_PUTN_BYTE(uchar, schar)
2015-08-16 06:26:35 +08:00
int
APIPrefix`x_pad_putn_'NC_TYPE(uchar)_schar(void **xpp, IntType nelems, const schar *tp, void *fillp)
2015-08-16 06:26:35 +08:00
{
2016-10-13 15:15:45 +08:00
int status = NC_NOERR;
IntType rndup = nelems % X_ALIGN;
uchar *xp = (uchar *) *xpp;
2016-10-06 13:36:54 +08:00
2016-10-13 15:15:45 +08:00
if (rndup) rndup = X_ALIGN - rndup;
2016-10-06 13:36:54 +08:00
2016-10-13 15:15:45 +08:00
while (nelems-- != 0) {
if (*tp < 0) {
FillValue(uchar, xp)
2016-10-13 15:15:45 +08:00
DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
SKIP_LOOP(xp, tp)
2016-10-13 15:15:45 +08:00
}
*xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
}
2015-08-16 06:26:35 +08:00
2016-10-13 15:15:45 +08:00
if (rndup) {
(void) memcpy(xp, nada, (size_t)rndup);
xp += rndup;
}
2016-10-06 13:36:54 +08:00
2016-10-13 15:15:45 +08:00
*xpp = (void *)xp;
return status;
2015-08-16 06:26:35 +08:00
}
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)
2015-08-16 06:26:35 +08:00
{
NCX_PAD_PUTN_Byte_Body
}
2016-10-06 13:36:54 +08:00
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)
2015-08-16 06:26:35 +08:00
/* short ---------------------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#if X_SIZEOF_SHORT == SIZEOF_SHORT
/* optimized version */
int
APIPrefix`x_getn_'NC_TYPE(short)_short(const void **xpp, IntType nelems, short *tp)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
2010-06-03 21:24:43 +08:00
# else
swapn2b(tp, *xpp, nelems);
# endif
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#else
NCX_GETN(short, short)
#endif
2015-08-16 06:26:35 +08:00
NCX_GETN(short, schar)
2010-06-03 21:24:43 +08:00
NCX_GETN(short, int)
2016-10-06 13:36:54 +08:00
NCX_GETN(short, long)
2010-06-03 21:24:43 +08:00
NCX_GETN(short, float)
NCX_GETN(short, double)
2015-08-16 06:26:35 +08:00
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)
2016-10-06 13:36:54 +08:00
NCX_PAD_GETN_SHORT(short, long)
2015-08-16 06:26:35 +08:00
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)
2010-06-03 21:24:43 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
2010-06-03 21:24:43 +08:00
# else
swapn2b(*xpp, tp, nelems);
# endif
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#else
NCX_PUTN(short, short)
#endif
2015-08-16 06:26:35 +08:00
NCX_PUTN(short, schar)
2010-06-03 21:24:43 +08:00
NCX_PUTN(short, int)
2016-10-06 13:36:54 +08:00
NCX_PUTN(short, long)
2010-06-03 21:24:43 +08:00
NCX_PUTN(short, float)
NCX_PUTN(short, double)
NCX_PUTN(short, longlong)
2015-08-16 06:26:35 +08:00
NCX_PUTN(short, uchar)
NCX_PUTN(short, uint)
2010-06-03 21:24:43 +08:00
NCX_PUTN(short, ulonglong)
2015-08-16 06:26:35 +08:00
NCX_PUTN(short, ushort)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
NCX_PAD_PUTN_SHORT(short, schar)
NCX_PAD_PUTN_SHORT(short, uchar)
NCX_PAD_PUTN_SHORT(short, short)
NCX_PAD_PUTN_SHORT(short, int)
2016-10-06 13:36:54 +08:00
NCX_PAD_PUTN_SHORT(short, long)
2015-08-16 06:26:35 +08:00
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)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
/* ushort --------------------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
#if X_SIZEOF_USHORT == SIZEOF_USHORT
2010-06-03 21:24:43 +08:00
/* optimized version */
int
APIPrefix`x_getn_'NC_TYPE(ushort)_ushort(const void **xpp, IntType nelems, unsigned short *tp)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
2010-06-03 21:24:43 +08:00
# else
2015-08-16 06:26:35 +08:00
swapn2b(tp, *xpp, nelems);
2010-06-03 21:24:43 +08:00
# endif
2015-08-16 06:26:35 +08:00
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
return NC_NOERR;
2015-08-16 06:26:35 +08:00
}
#else
NCX_GETN(ushort, ushort)
#endif
NCX_GETN(ushort, schar)
NCX_GETN(ushort, short)
NCX_GETN(ushort, int)
2016-10-06 13:36:54 +08:00
NCX_GETN(ushort, long)
2015-08-16 06:26:35 +08:00
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)
2016-10-06 13:36:54 +08:00
NCX_PAD_GETN_SHORT(ushort, long)
2015-08-16 06:26:35 +08:00
NCX_PAD_GETN_SHORT(ushort, float)
NCX_PAD_GETN_SHORT(ushort, double)
2016-10-06 13:36:54 +08:00
NCX_PAD_GETN_SHORT(ushort, uchar)
NCX_PAD_GETN_SHORT(ushort, ushort)
NCX_PAD_GETN_SHORT(ushort, uint)
2015-08-16 06:26:35 +08:00
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)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
2015-08-16 06:26:35 +08:00
# else
swapn2b(*xpp, tp, nelems);
# endif
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#else
NCX_PUTN(ushort, ushort)
#endif
NCX_PUTN(ushort, schar)
NCX_PUTN(ushort, short)
NCX_PUTN(ushort, int)
2016-10-06 13:36:54 +08:00
NCX_PUTN(ushort, long)
2015-08-16 06:26:35 +08:00
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)
2016-10-06 13:36:54 +08:00
NCX_PAD_PUTN_SHORT(ushort, long)
2015-08-16 06:26:35 +08:00
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 */
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_getn_'NC_TYPE(int)_int(const void **xpp, IntType nelems, int *tp)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
2010-06-03 21:24:43 +08:00
# else
swapn4b(tp, *xpp, nelems);
# endif
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#else
NCX_GETN(int, int)
#endif
2015-08-16 06:26:35 +08:00
NCX_GETN(int, schar)
NCX_GETN(int, short)
2016-10-06 13:36:54 +08:00
NCX_GETN(int, long)
2010-06-03 21:24:43 +08:00
NCX_GETN(int, float)
NCX_GETN(int, double)
2015-08-16 06:26:35 +08:00
NCX_GETN(int, longlong)
NCX_GETN(int, uchar)
NCX_GETN(int, ushort)
NCX_GETN(int, uint)
NCX_GETN(int, ulonglong)
2010-06-03 21:24:43 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
2010-06-03 21:24:43 +08:00
# else
swapn4b(*xpp, tp, nelems);
# endif
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2015-08-16 06:26:35 +08:00
#else
NCX_PUTN(int, int)
#endif
NCX_PUTN(int, schar)
NCX_PUTN(int, short)
2016-10-06 13:36:54 +08:00
NCX_PUTN(int, long)
2015-08-16 06:26:35 +08:00
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)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
2015-08-16 06:26:35 +08:00
# else
swapn4b(tp, *xpp, nelems);
# endif
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
return NC_NOERR;
2015-08-16 06:26:35 +08:00
}
#else
NCX_GETN(uint, uint)
#endif
NCX_GETN(uint, schar)
NCX_GETN(uint, short)
NCX_GETN(uint, int)
2016-10-06 13:36:54 +08:00
NCX_GETN(uint, long)
2015-08-16 06:26:35 +08:00
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 */
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_putn_'NC_TYPE(uint)_uint(void **xpp, IntType nelems, const unsigned int *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
2010-06-03 21:24:43 +08:00
# else
swapn4b(*xpp, tp, nelems);
# endif
2015-08-16 06:26:35 +08:00
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#else
2015-08-16 06:26:35 +08:00
NCX_PUTN(uint, uint)
2010-06-03 21:24:43 +08:00
#endif
2015-08-16 06:26:35 +08:00
NCX_PUTN(uint, schar)
NCX_PUTN(uint, short)
NCX_PUTN(uint, int)
2016-10-06 13:36:54 +08:00
NCX_PUTN(uint, long)
2015-08-16 06:26:35 +08:00
NCX_PUTN(uint, float)
NCX_PUTN(uint, double)
NCX_PUTN(uint, longlong)
NCX_PUTN(uint, uchar)
NCX_PUTN(uint, ushort)
NCX_PUTN(uint, ulonglong)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
/* float ---------------------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
2010-06-03 21:24:43 +08:00
# else
swapn4b(tp, *xpp, nelems);
# endif
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
#elif defined(vax) && vax != 0
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nfloats, float *ip)
2010-06-03 21:24:43 +08:00
{
float *const end = ip + nfloats;
2016-10-06 13:36:54 +08:00
while (ip < end)
2010-06-03 21:24:43 +08:00
{
GET_VAX_DFLOAT_Body(`(*xpp)')
ip++;
*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
}
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#else
int
APIPrefix`x_getn_'NC_TYPE(float)_float(const void **xpp, IntType nelems, float *tp)
2010-06-03 21:24:43 +08:00
{
const char *xp = *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
{
const int lstatus = APIPrefix`x_get_'NC_TYPE(float)_float(xp, tp, fillp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
*xpp = (const void *)xp;
return status;
}
#endif
2015-08-16 06:26:35 +08:00
NCX_GETN(float, schar)
NCX_GETN(float, short)
NCX_GETN(float, int)
2016-10-06 13:36:54 +08:00
NCX_GETN(float, long)
2010-06-03 21:24:43 +08:00
NCX_GETN(float, double)
NCX_GETN(float, longlong)
2015-08-16 06:26:35 +08:00
NCX_GETN(float, ushort)
NCX_GETN(float, uchar)
NCX_GETN(float, uint)
2010-06-03 21:24:43 +08:00
NCX_GETN(float, ulonglong)
2016-10-06 13:36:54 +08:00
int
APIPrefix`x_putn_'NC_TYPE(float)_float(void **xpp, IntType nelems, const float *tp, void *fillp)
2010-06-03 21:24:43 +08:00
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
/* optimized version */
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
2010-06-03 21:24:43 +08:00
# else
swapn4b(*xpp, tp, nelems);
# endif
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
#elif defined(vax) && vax != 0
2010-06-03 21:24:43 +08:00
{
2016-10-06 13:36:54 +08:00
const float *const end = tp + nelems;
2016-10-06 13:36:54 +08:00
while (tp < end) {
PUT_VAX_DFLOAT_Body(`(*xpp)')
tp++;
2010-06-03 21:24:43 +08:00
*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
}
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
#else
{
char *xp = *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
2016-10-06 13:36:54 +08:00
for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
int lstatus = APIPrefix`x_put_'NC_TYPE(float)_float(xp, tp, fillp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
*xpp = (void *)xp;
return status;
}
#endif
2015-08-16 06:26:35 +08:00
NCX_PUTN(float, schar)
NCX_PUTN(float, short)
NCX_PUTN(float, int)
2016-10-06 13:36:54 +08:00
NCX_PUTN(float, long)
2010-06-03 21:24:43 +08:00
NCX_PUTN(float, double)
NCX_PUTN(float, longlong)
2015-08-16 06:26:35 +08:00
NCX_PUTN(float, uchar)
NCX_PUTN(float, ushort)
NCX_PUTN(float, uint)
2010-06-03 21:24:43 +08:00
NCX_PUTN(float, ulonglong)
2015-08-16 06:26:35 +08:00
/* double --------------------------------------------------------------------*/
2010-06-03 21:24:43 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
2010-06-03 21:24:43 +08:00
# else
swapn8b(tp, *xpp, nelems);
# endif
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
#elif defined(vax) && vax != 0
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType ndoubles, double *ip)
2010-06-03 21:24:43 +08:00
{
double *const end = ip + ndoubles;
2016-10-06 13:36:54 +08:00
while (ip < end)
2010-06-03 21:24:43 +08:00
{
GET_VAX_DDOUBLE_Body(`(*xpp)')
ip++;
*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
}
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
/* vax */
#else
int
APIPrefix`x_getn_'NC_TYPE(double)_double(const void **xpp, IntType nelems, double *tp)
2010-06-03 21:24:43 +08:00
{
const char *xp = *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
{
const int lstatus = APIPrefix`x_get_'NC_TYPE(double)_double(xp, tp, fillp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
*xpp = (const void *)xp;
return status;
}
#endif
2015-08-16 06:26:35 +08:00
NCX_GETN(double, schar)
NCX_GETN(double, short)
NCX_GETN(double, int)
2016-10-06 13:36:54 +08:00
NCX_GETN(double, long)
2015-08-16 06:26:35 +08:00
NCX_GETN(double, float)
NCX_GETN(double, longlong)
NCX_GETN(double, uchar)
NCX_GETN(double, ushort)
NCX_GETN(double, uint)
NCX_GETN(double, ulonglong)
2010-06-03 21:24:43 +08:00
#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)
2010-06-03 21:24:43 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
2010-06-03 21:24:43 +08:00
# else
swapn8b(*xpp, tp, nelems);
# endif
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
2016-10-06 13:36:54 +08:00
#elif defined(vax) && vax != 0
2010-06-03 21:24:43 +08:00
int
APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType ndoubles, const double *ip, void *fillp)
2010-06-03 21:24:43 +08:00
{
const double *const end = ip + ndoubles;
2016-10-06 13:36:54 +08:00
while (ip < end)
2010-06-03 21:24:43 +08:00
{
PUT_VAX_DDOUBLE_Body(`(*xpp)')
ip++;
*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
}
return NC_NOERR;
2010-06-03 21:24:43 +08:00
}
/* vax */
#else
int
APIPrefix`x_putn_'NC_TYPE(double)_double(void **xpp, IntType nelems, const double *tp, void *fillp)
2010-06-03 21:24:43 +08:00
{
char *xp = *xpp;
int status = NC_NOERR;
2010-06-03 21:24:43 +08:00
for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
{
int lstatus = APIPrefix`x_put_'NC_TYPE(double)_double(xp, tp, fillp);
2016-10-06 13:36:54 +08:00
if (status == NC_NOERR) /* report the first encountered error */
2010-06-03 21:24:43 +08:00
status = lstatus;
}
*xpp = (void *)xp;
return status;
}
2015-08-16 06:26:35 +08:00
#endif
NCX_PUTN(double, schar)
NCX_PUTN(double, short)
NCX_PUTN(double, int)
2016-10-06 13:36:54 +08:00
NCX_PUTN(double, long)
2015-08-16 06:26:35 +08:00
NCX_PUTN(double, float)
NCX_PUTN(double, longlong)
NCX_PUTN(double, uchar)
NCX_PUTN(double, ushort)
NCX_PUTN(double, uint)
NCX_PUTN(double, ulonglong)
2010-06-03 21:24:43 +08:00
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
/* longlong ------------------------------------------------------------------*/
2015-08-16 06:26:35 +08:00
2016-10-06 13:36:54 +08:00
#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
2015-08-16 06:26:35 +08:00
/* optimized version */
int
APIPrefix`x_getn_'NC_TYPE(int64)_longlong(const void **xpp, IntType nelems, long long *tp)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
2015-08-16 06:26:35 +08:00
# else
swapn8b(tp, *xpp, nelems);
# endif
2016-10-06 13:36:54 +08:00
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
return NC_NOERR;
2015-08-16 06:26:35 +08:00
}
#else
2016-10-06 13:36:54 +08:00
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
2015-08-16 06:26:35 +08:00
/* optimized version */
int
APIPrefix`x_putn_'NC_TYPE(int64)_longlong(void **xpp, IntType nelems, const long long *tp, void *fillp)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
2015-08-16 06:26:35 +08:00
# else
swapn8b(*xpp, tp, nelems);
# endif
2016-10-06 13:36:54 +08:00
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
return NC_NOERR;
2015-08-16 06:26:35 +08:00
}
#else
2016-10-06 13:36:54 +08:00
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
2015-08-16 06:26:35 +08:00
/* optimized version */
int
APIPrefix`x_getn_'NC_TYPE(uint64)_ulonglong(const void **xpp, IntType nelems, unsigned long long *tp)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
2015-08-16 06:26:35 +08:00
# else
swapn8b(tp, *xpp, nelems);
# endif
2016-10-06 13:36:54 +08:00
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
return NC_NOERR;
2015-08-16 06:26:35 +08:00
}
#else
2016-10-06 13:36:54 +08:00
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
2015-08-16 06:26:35 +08:00
/* optimized version */
int
APIPrefix`x_putn_'NC_TYPE(uint64)_ulonglong(void **xpp, IntType nelems, const unsigned long long *tp, void *fillp)
2015-08-16 06:26:35 +08:00
{
#ifdef WORDS_BIGENDIAN
2016-10-06 13:36:54 +08:00
(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
2015-08-16 06:26:35 +08:00
# else
swapn8b(*xpp, tp, nelems);
# endif
2016-10-06 13:36:54 +08:00
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
return NC_NOERR;
2015-08-16 06:26:35 +08:00
}
#else
2016-10-06 13:36:54 +08:00
NCX_PUTN(uint64, ulonglong)
2015-08-16 06:26:35 +08:00
#endif
2016-10-06 13:36:54 +08:00
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)
2010-06-03 21:24:43 +08:00
/*
* Other aggregate conversion functions.
*/
/* text */
2016-10-06 13:36:54 +08:00
2010-06-03 21:24:43 +08:00
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_getn_text'(const void **xpp, IntType nelems, char *tp)
2010-06-03 21:24:43 +08:00
{
NCX_GETN_Byte_Body
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_pad_getn_text'(const void **xpp, IntType nelems, char *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PAD_GETN_Byte_Body
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_putn_text'(void **xpp, IntType nelems, const char *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PUTN_Byte_Body
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_pad_putn_text'(void **xpp, IntType nelems, const char *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PAD_PUTN_Byte_Body
}
/* opaque */
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_getn_void'(const void **xpp, IntType nelems, void *tp)
2010-06-03 21:24:43 +08:00
{
NCX_GETN_Byte_Body
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_pad_getn_void'(const void **xpp, IntType nelems, void *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PAD_GETN_Byte_Body
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_putn_void'(void **xpp, IntType nelems, const void *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PUTN_Byte_Body
}
int
2016-10-06 13:36:54 +08:00
APIPrefix`x_pad_putn_void'(void **xpp, IntType nelems, const void *tp)
2010-06-03 21:24:43 +08:00
{
NCX_PAD_PUTN_Byte_Body
}