/* Do not edit this file. It is produced from the corresponding .m4 source */
/*
 *	Copyright 2018, University Corporation for Atmospheric Research
 *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
 */
/* $Id: putget.m4 2783 2014-10-26 05:19:35Z wkliao $ */

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include "netcdf.h"
#include "nc3dispatch.h"
#include "nc3internal.h"
#include "ncx.h"
#include "fbits.h"
#include "onstack.h"
#ifdef LOCKNUMREC
#  include <mpp/shmem.h>	/* for SGI/Cray SHMEM routines */
#  ifdef LN_TEST
#    include <stdio.h>
#  endif
#endif


#undef MIN  /* system may define MIN somewhere and complain */
#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))

static int
readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start,
        const size_t nelems, void* value, const nc_type memtype);
static int
writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start,
         const size_t nelems, const void* value, const nc_type memtype);


/* #define ODEBUG 1 */

#if ODEBUG
#include <stdio.h>
/*
 * Print the values of an array of size_t
 */
void
arrayp(const char *label, size_t count, const size_t *array)
{
	(void) fprintf(stderr, "%s", label);
	(void) fputc('\t',stderr);
	for(; count > 0; count--, array++)
		(void) fprintf(stderr," %lu", (unsigned long)*array);
	(void) fputc('\n',stderr);
}
#endif /* ODEBUG */


/* Begin fill */
/*
 * This is tunable parameter.
 * It essentially controls the tradeoff between the number of times
 * memcpy() gets called to copy the external data to fill
 * a large buffer vs the number of times its called to
 * prepare the external data.
 */
#if	_SX
/* NEC SX specific optimization */
#define	NFILL	2048
#else
#define	NFILL	16
#endif



/*
 * Next 6 type specific functions
 * Fill a some memory with the default special value.
 * Formerly
NC_arrayfill()
 */
static int
NC_fill_schar(
	void **xpp,
	size_t nelems)	/* how many */
{
	schar fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		schar *vp = fillp;	/* lower bound of area to be filled */
		const schar *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_BYTE;
		}
	}
	return ncx_putn_schar_schar(xpp, nelems, fillp ,NULL);
}

static int
NC_fill_char(
	void **xpp,
	size_t nelems)	/* how many */
{
	char fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		char *vp = fillp;	/* lower bound of area to be filled */
		const char *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_CHAR;
		}
	}
	return ncx_putn_char_char(xpp, nelems, fillp );
}

static int
NC_fill_short(
	void **xpp,
	size_t nelems)	/* how many */
{
	short fillp[NFILL * sizeof(double)/X_SIZEOF_SHORT];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		short *vp = fillp;	/* lower bound of area to be filled */
		const short *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_SHORT;
		}
	}
	return ncx_putn_short_short(xpp, nelems, fillp ,NULL);
}


#if (SIZEOF_INT >= X_SIZEOF_INT)
static int
NC_fill_int(
	void **xpp,
	size_t nelems)	/* how many */
{
	int fillp[NFILL * sizeof(double)/X_SIZEOF_INT];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		int *vp = fillp;	/* lower bound of area to be filled */
		const int *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_INT;
		}
	}
	return ncx_putn_int_int(xpp, nelems, fillp ,NULL);
}

#elif SIZEOF_LONG == X_SIZEOF_INT
static int
NC_fill_int(
	void **xpp,
	size_t nelems)	/* how many */
{
	long fillp[NFILL * sizeof(double)/X_SIZEOF_INT];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		long *vp = fillp;	/* lower bound of area to be filled */
		const long *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_INT;
		}
	}
	return ncx_putn_int_long(xpp, nelems, fillp ,NULL);
}

#else
#error "NC_fill_int implementation"
#endif

static int
NC_fill_float(
	void **xpp,
	size_t nelems)	/* how many */
{
	float fillp[NFILL * sizeof(double)/X_SIZEOF_FLOAT];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		float *vp = fillp;	/* lower bound of area to be filled */
		const float *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_FLOAT;
		}
	}
	return ncx_putn_float_float(xpp, nelems, fillp ,NULL);
}

static int
NC_fill_double(
	void **xpp,
	size_t nelems)	/* how many */
{
	double fillp[NFILL * sizeof(double)/X_SIZEOF_DOUBLE];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		double *vp = fillp;	/* lower bound of area to be filled */
		const double *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_DOUBLE;
		}
	}
	return ncx_putn_double_double(xpp, nelems, fillp ,NULL);
}


static int
NC_fill_uchar(
	void **xpp,
	size_t nelems)	/* how many */
{
	uchar fillp[NFILL * sizeof(double)/X_SIZEOF_UBYTE];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		uchar *vp = fillp;	/* lower bound of area to be filled */
		const uchar *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_UBYTE;
		}
	}
	return ncx_putn_uchar_uchar(xpp, nelems, fillp ,NULL);
}

static int
NC_fill_ushort(
	void **xpp,
	size_t nelems)	/* how many */
{
	ushort fillp[NFILL * sizeof(double)/X_SIZEOF_USHORT];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		ushort *vp = fillp;	/* lower bound of area to be filled */
		const ushort *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_USHORT;
		}
	}
	return ncx_putn_ushort_ushort(xpp, nelems, fillp ,NULL);
}

static int
NC_fill_uint(
	void **xpp,
	size_t nelems)	/* how many */
{
	uint fillp[NFILL * sizeof(double)/X_SIZEOF_UINT];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		uint *vp = fillp;	/* lower bound of area to be filled */
		const uint *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_UINT;
		}
	}
	return ncx_putn_uint_uint(xpp, nelems, fillp ,NULL);
}

static int
NC_fill_longlong(
	void **xpp,
	size_t nelems)	/* how many */
{
	longlong fillp[NFILL * sizeof(double)/X_SIZEOF_LONGLONG];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		longlong *vp = fillp;	/* lower bound of area to be filled */
		const longlong *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_INT64;
		}
	}
	return ncx_putn_longlong_longlong(xpp, nelems, fillp ,NULL);
}

static int
NC_fill_ulonglong(
	void **xpp,
	size_t nelems)	/* how many */
{
	ulonglong fillp[NFILL * sizeof(double)/X_SIZEOF_ULONGLONG];

	assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));

	{
		ulonglong *vp = fillp;	/* lower bound of area to be filled */
		const ulonglong *const end = vp + nelems;
		while(vp < end)
		{
			*vp++ = NC_FILL_UINT64;
		}
	}
	return ncx_putn_ulonglong_ulonglong(xpp, nelems, fillp ,NULL);
}




/*
 * Fill the external space for variable 'varp' values at 'recno' with
 * the appropriate value. If 'varp' is not a record variable, fill the
 * whole thing.  For the special case when 'varp' is the only record
 * variable and it is of type byte, char, or short, varsize should be
 * ncp->recsize, otherwise it should be varp->len.
 * Formerly
xdr_NC_fill()
 */
int
fill_NC_var(NC3_INFO* ncp, const NC_var *varp, long long varsize, size_t recno)
{
	char xfillp[NFILL * X_SIZEOF_DOUBLE];
	const size_t step = varp->xsz;
	const size_t nelems = sizeof(xfillp)/step;
	const size_t xsz = varp->xsz * nelems;
	NC_attr **attrpp = NULL;
	off_t offset;
	long long remaining = varsize;

	void *xp;
	int status = NC_NOERR;

	/*
	 * Set up fill value
	 */
	attrpp = NC_findattr(&varp->attrs, _FillValue);
	if( attrpp != NULL )
	{
		/* User defined fill value */
		if( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 )
		{
			return NC_EBADTYPE;
		}
		else
		{
			/* Use the user defined value */
			char *cp = xfillp;
			const char *const end = &xfillp[sizeof(xfillp)];

			assert(step <= (*attrpp)->xsz);

			for( /*NADA*/; cp < end; cp += step)
			{
				(void) memcpy(cp, (*attrpp)->xvalue, step);
			}
		}
	}
	else
	{
		/* use the default */

		assert(xsz % X_ALIGN == 0);
		assert(xsz <= sizeof(xfillp));

		xp = xfillp;

		switch(varp->type){
		case NC_BYTE :
			status = NC_fill_schar(&xp, nelems);
			break;
		case NC_CHAR :
			status = NC_fill_char(&xp, nelems);
			break;
		case NC_SHORT :
			status = NC_fill_short(&xp, nelems);
			break;
		case NC_INT :
			status = NC_fill_int(&xp, nelems);
			break;
		case NC_FLOAT :
			status = NC_fill_float(&xp, nelems);
			break;
		case NC_DOUBLE :
			status = NC_fill_double(&xp, nelems);
			break;
                case NC_UBYTE :
                        status = NC_fill_uchar(&xp, nelems);
                        break;
                case NC_USHORT :
                        status = NC_fill_ushort(&xp, nelems);
                        break;
                case NC_UINT :
                        status = NC_fill_uint(&xp, nelems);
                        break;
                case NC_INT64 :
                        status = NC_fill_longlong(&xp, nelems);
                        break;
                case NC_UINT64 :
                        status = NC_fill_ulonglong(&xp, nelems);
                        break;
		default :
			assert("fill_NC_var invalid type" == 0);
			status = NC_EBADTYPE;
			break;
		}
		if(status != NC_NOERR)
			return status;

		assert(xp == xfillp + xsz);
	}

	/*
	 * copyout:
	 * xfillp now contains 'nelems' elements of the fill value
	 * in external representation.
	 */

	/*
	 * Copy it out.
	 */

	offset = varp->begin;
	if(IS_RECVAR(varp))
	{
		offset += (off_t)ncp->recsize * recno;
	}

	assert(remaining > 0);
	for(;;)
	{
		const size_t chunksz = MIN(remaining, ncp->chunk);
		size_t ii;

		status = ncio_get(ncp->nciop, offset, chunksz,
				 RGN_WRITE, &xp);
		if(status != NC_NOERR)
		{
			return status;
		}

		/*
		 * fill the chunksz buffer in units  of xsz
		 */
		for(ii = 0; ii < chunksz/xsz; ii++)
		{
			(void) memcpy(xp, xfillp, xsz);
			xp = (char *)xp + xsz;
		}
		/*
		 * Deal with any remainder
		 */
		{
			const size_t rem = chunksz % xsz;
			if(rem != 0)
			{
				(void) memcpy(xp, xfillp, rem);
				/* xp = (char *)xp + xsz; */
			}

		}

		status = ncio_rel(ncp->nciop, offset, RGN_MODIFIED);

		if(status != NC_NOERR)
		{
			break;
		}

		remaining -= chunksz;
		if(remaining == 0)
			break;	/* normal loop exit */
		offset += chunksz;

	}

	return status;
}
/* End fill */


/*
 * Add a record containing the fill values.
 */
static int
NCfillrecord(NC3_INFO* ncp, const NC_var *const *varpp, size_t recno)
{
	size_t ii = 0;
	for(; ii < ncp->vars.nelems; ii++, varpp++)
	{
		if( !IS_RECVAR(*varpp) )
		{
			continue;	/* skip non-record variables */
		}
		{
		const int status = fill_NC_var(ncp, *varpp, (*varpp)->len, recno);
		if(status != NC_NOERR)
			return status;
		}
	}
	return NC_NOERR;
}


/*
 * Add a record containing the fill values in the special case when
 * there is exactly one record variable, where we don't require each
 * record to be four-byte aligned (no record padding).
 */
static int
NCfillspecialrecord(NC3_INFO* ncp, const NC_var *varp, size_t recno)
{
    int status;
    assert(IS_RECVAR(varp));
    status = fill_NC_var(ncp, varp, ncp->recsize, recno);
    if(status != NC_NOERR)
	return status;
    return NC_NOERR;
}


/*
 * It is advantageous to
 * #define TOUCH_LAST
 * when using memory mapped io.
 */
#if TOUCH_LAST
/*
 * Grow the file to a size which can contain recno
 */
static int
NCtouchlast(NC3_INFO* ncp, const NC_var *const *varpp, size_t recno)
{
	int status = NC_NOERR;
	const NC_var *varp = NULL;

	{
	size_t ii = 0;
	for(; ii < ncp->vars.nelems; ii++, varpp++)
	{
		if( !IS_RECVAR(*varpp) )
		{
			continue;	/* skip non-record variables */
		}
		varp = *varpp;
	}
	}
	assert(varp != NULL);
	assert( IS_RECVAR(varp) );
	{
		const off_t offset = varp->begin
				+ (off_t)(recno-1) * (off_t)ncp->recsize
				+ (off_t)(varp->len - varp->xsz);
		void *xp;


		status = ncio_get(ncp->nciop, offset, varp->xsz,
				 RGN_WRITE, &xp);
		if(status != NC_NOERR)
			return status;
		(void)memset(xp, 0, varp->xsz);
		status = ncio_rel(ncp->nciop, offset, RGN_MODIFIED);
	}
	return status;
}
#endif /* TOUCH_LAST */


/*
 * Ensure that the netcdf file has 'numrecs' records,
 * add records and fill as necessary.
 */
static int
NCvnrecs(NC3_INFO* ncp, size_t numrecs)
{
	int status = NC_NOERR;
#ifdef LOCKNUMREC
	ushmem_t myticket = 0, nowserving = 0;
	ushmem_t numpe = (ushmem_t) _num_pes();

	/* get ticket and wait */
	myticket = shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
		ncp->lock[LOCKNUMREC_BASEPE]);
#ifdef LN_TEST
		fprintf(stderr,"%d of %d : ticket = %hu\n",
			_my_pe(), _num_pes(), myticket);
#endif
	do {
		shmem_short_get((shmem_t *) &nowserving,
			(shmem_t *) ncp->lock + LOCKNUMREC_SERVING, 1,
			ncp->lock[LOCKNUMREC_BASEPE]);
#ifdef LN_TEST
		fprintf(stderr,"%d of %d : serving = %hu\n",
			_my_pe(), _num_pes(), nowserving);
#endif
		/* work-around for non-unique tickets */
		if (nowserving > myticket && nowserving < myticket + numpe ) {
			/* get a new ticket ... you've been bypassed */
			/* and handle the unlikely wrap-around effect */
			myticket = shmem_short_finc(
				(shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
				ncp->lock[LOCKNUMREC_BASEPE]);
#ifdef LN_TEST
				fprintf(stderr,"%d of %d : new ticket = %hu\n",
					_my_pe(), _num_pes(), myticket);
#endif
		}
	} while(nowserving != myticket);
	/* now our turn to check & update value */
#endif

	if(numrecs > NC_get_numrecs(ncp))
	{


#if TOUCH_LAST
		status = NCtouchlast(ncp,
			(const NC_var *const*)ncp->vars.value,
			numrecs);
		if(status != NC_NOERR)
			goto common_return;
#endif /* TOUCH_LAST */

		set_NC_ndirty(ncp);

		if(!NC_dofill(ncp))
		{
			/* Simply set the new numrecs value */
			NC_set_numrecs(ncp, numrecs);
		}
		else
		{
		    /* Treat two cases differently:
		        - exactly one record variable (no padding)
                        - multiple record variables (each record padded
                          to 4-byte alignment)
		    */
		    NC_var **vpp = (NC_var **)ncp->vars.value;
		    NC_var *const *const end = &vpp[ncp->vars.nelems];
		    NC_var *recvarp = NULL;	/* last record var */
		    int numrecvars = 0;
		    size_t cur_nrecs;

		    /* determine how many record variables */
		    for( /*NADA*/; vpp < end; vpp++) {
			if(IS_RECVAR(*vpp)) {
			    recvarp = *vpp;
			    numrecvars++;
			}
		    }

		    if (numrecvars != 1) { /* usual case */
			/* Fill each record out to numrecs */
			while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs)
			    {
				status = NCfillrecord(ncp,
					(const NC_var *const*)ncp->vars.value,
					cur_nrecs);
				if(status != NC_NOERR)
				{
					break;
				}
				NC_increase_numrecs(ncp, cur_nrecs +1);
			}
			if(status != NC_NOERR)
				goto common_return;
		    } else {	/* special case */
			/* Fill each record out to numrecs */
			while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs)
			    {
				status = NCfillspecialrecord(ncp,
					recvarp,
					cur_nrecs);
				if(status != NC_NOERR)
				{
					break;
				}
				NC_increase_numrecs(ncp, cur_nrecs +1);
			}
			if(status != NC_NOERR)
				goto common_return;

		    }
		}

		if(NC_doNsync(ncp))
		{
			status = write_numrecs(ncp);
		}

	}
common_return:
#ifdef LOCKNUMREC
	/* finished with our lock - increment serving number */
	(void) shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_SERVING,
		ncp->lock[LOCKNUMREC_BASEPE]);
#endif
	return status;
}


/*
 * Check whether 'coord' values are valid for the variable.
 */
static int
NCcoordck(NC3_INFO* ncp, const NC_var *varp, const size_t *coord)
{
	const size_t *ip;
	size_t *up;

	if(varp->ndims == 0)
		return NC_NOERR;	/* 'scalar' variable */

	if(IS_RECVAR(varp))
	{
		if(*coord > X_UINT_MAX) /* rkr: bug fix from previous X_INT_MAX */
			return NC_EINVALCOORDS; /* sanity check */
#ifdef RELAX_COORD_BOUND
		if(NC_readonly(ncp) && *coord > NC_get_numrecs(ncp))
#else
		if(NC_readonly(ncp) && *coord >= NC_get_numrecs(ncp))
#endif
		{
			if(!NC_doNsync(ncp))
				return NC_EINVALCOORDS;
			/* else */
			{
				/* Update from disk and check again */
				const int status = read_numrecs(ncp);
				if(status != NC_NOERR)
					return status;
#ifdef RELAX_COORD_BOUND
				if(*coord > NC_get_numrecs(ncp))
#else
				if(*coord >= NC_get_numrecs(ncp))
#endif
					return NC_EINVALCOORDS;
			}
		}
		ip = coord + 1;
		up = varp->shape + 1;
	}
	else
	{
		ip = coord;
		up = varp->shape;
	}

#ifdef CDEBUG
fprintf(stderr,"	NCcoordck: coord %ld, count %d, ip %ld\n",
		coord, varp->ndims, ip );
#endif /* CDEBUG */

	for(; ip < coord + varp->ndims; ip++, up++)
	{

#ifdef CDEBUG
fprintf(stderr,"	NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n",
			ip, *ip, up, *up );
#endif /* CDEBUG */

		/* cast needed for braindead systems with signed size_t */
#ifdef RELAX_COORD_BOUND
		if((unsigned long) *ip > (unsigned long) *up )
#else
		if((unsigned long) *ip >= (unsigned long) *up )
#endif
			return NC_EINVALCOORDS;
	}

	return NC_NOERR;
}


/*
 * Check whether 'edges' are valid for the variable and 'start'
 */
/*ARGSUSED*/
static int
NCedgeck(const NC3_INFO* ncp, const NC_var *varp,
	 const size_t *start, const size_t *edges)
{
	const size_t *const end = start + varp->ndims;
	const size_t *shp = varp->shape;

	if(varp->ndims == 0)
		return NC_NOERR;	/* 'scalar' variable */

	if(IS_RECVAR(varp))
	{
#ifdef RELAX_COORD_BOUND
		if (NC_readonly(ncp) &&
                    (start[0] == NC_get_numrecs(ncp) && edges[0] > 0))
			return(NC_EINVALCOORDS);
#endif
		start++;
		edges++;
		shp++;
	}

	for(; start < end; start++, edges++, shp++)
	{
#ifdef RELAX_COORD_BOUND
		if ((unsigned long) *start == *shp && *edges > 0)
			return(NC_EINVALCOORDS);
#endif
		/* cast needed for braindead systems with signed size_t */
		if((unsigned long) *edges > *shp ||
			(unsigned long) *start + (unsigned long) *edges > *shp)
		{
			return(NC_EEDGE);
		}
	}
	return NC_NOERR;
}


/*
 * Translate the (variable, coord) pair into a seek index
 */
static off_t
NC_varoffset(const NC3_INFO* ncp, const NC_var *varp, const size_t *coord)
{
	if(varp->ndims == 0) /* 'scalar' variable */
		return varp->begin;

	if(varp->ndims == 1)
	{
		if(IS_RECVAR(varp))
			return varp->begin +
				 (off_t)(*coord) * (off_t)ncp->recsize;
		/* else */
		return varp->begin + (off_t)(*coord) * (off_t)varp->xsz;
	}
	/* else */
	{
		off_t lcoord = (off_t)coord[varp->ndims -1];

		off_t *up = varp->dsizes +1;
		const size_t *ip = coord;
		const off_t *const end = varp->dsizes + varp->ndims;

		if(IS_RECVAR(varp))
			up++, ip++;

		for(; up < end; up++, ip++)
			lcoord += (off_t)(*up) * (off_t)(*ip);

		lcoord *= varp->xsz;

		if(IS_RECVAR(varp))
			lcoord += (off_t)(*coord) * ncp->recsize;

		lcoord += varp->begin;
		return lcoord;
	}
}



static int
putNCvx_char_char(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const char *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_char_char(&xp, nput, value );
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_schar_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_schar_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_schar_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_short_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_short_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_short_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_int_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_int_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_int_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_float_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_float_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_float_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_double_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_double_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_double_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_uchar_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uchar_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uchar_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_ushort_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ushort_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ushort_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_uint_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_uint_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_uint_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_longlong_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_longlong_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_longlong_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}


static int
putNCvx_ulonglong_schar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_schar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_uchar(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_uchar(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_short(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_short(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_int(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_int(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_float(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_float(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_double(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_double(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_longlong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_longlong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_ushort(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_ushort(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_uint(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_uint(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}

static int
putNCvx_ulonglong_ulonglong(NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, const ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	void *xp;
        void *fillp=NULL;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

#ifdef ERANGE_FILL
        fillp = malloc(varp->xsz);
        status = NC3_inq_var_fill(varp, fillp);
#endif

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nput = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 RGN_WRITE, &xp);
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_putn_ulonglong_ulonglong(&xp, nput, value ,fillp);
		if(lstatus != NC_NOERR && status == NC_NOERR)
		{
			/* not fatal to the loop */
			status = lstatus;
		}

		(void) ncio_rel(ncp->nciop, offset,
				 RGN_MODIFIED);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nput;

	}
#ifdef ERANGE_FILL
        free(fillp);
#endif

	return status;
}



static int
getNCvx_char_char(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, char *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_char_char(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_schar_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_schar_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_short_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_short_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_short_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_int_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_int_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_int_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_float_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_float_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_float_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_double_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_double_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_double_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_uchar_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uchar_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uchar_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_ushort_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ushort_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ushort_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_uint_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_uint_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_uint_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_longlong_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_longlong_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_longlong_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


static int
getNCvx_ulonglong_schar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, schar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_schar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_short(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, short *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_short(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_int(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, int *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_int(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_float(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_double(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, double *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_double(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_longlong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, longlong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_longlong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_uint(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uint *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_uint(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_ulonglong(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ulonglong *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_ulonglong(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

static int
getNCvx_ulonglong_ushort(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, ushort *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_ulonglong_ushort(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}


#ifdef NOTUSED
static int
getNCvx_schar_uchar(const NC3_INFO* ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, uchar *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncio_get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;

		lstatus = ncx_getn_schar_uchar(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncio_rel(ncp->nciop, offset, 0);

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += (off_t)extent;
		value += nget;
	}

	return status;
}

#endif /*NOTUSED*/

/*
 *  For ncvar{put,get},
 *  find the largest contiguous block from within 'edges'.
 *  returns the index to the left of this (which may be -1).
 *  Compute the number of contiguous elements and return
 *  that in *iocountp.
 *  The presence of "record" variables makes this routine
 *  overly subtle.
 */
static int
NCiocount(const NC3_INFO* const ncp, const NC_var *const varp,
	const size_t *const edges,
	size_t *const iocountp)
{
	const size_t *edp0 = edges;
	const size_t *edp = edges + varp->ndims;
	const size_t *shp = varp->shape + varp->ndims;

	if(IS_RECVAR(varp))
	{
		if(varp->ndims == 1 && ncp->recsize <= varp->len)
		{
			/* one dimensional && the only 'record' variable */
			*iocountp = *edges;
			return(0);
		}
		/* else */
		edp0++;
	}

	assert(edges != NULL);

	/* find max contiguous */
	while(edp > edp0)
	{
		shp--; edp--;
		if(*edp < *shp )
		{
			const size_t *zedp = edp;
			while(zedp >= edp0)
			{
				if(*zedp == 0)
				{
					*iocountp = 0;
					goto done;
				}
				/* Tip of the hat to segmented architectures */
				if(zedp == edp0)
					break;
				zedp--;
			}
			break;
		}
		assert(*edp == *shp);
	}

	/*
	 * edp, shp reference rightmost index s.t. *(edp +1) == *(shp +1)
	 *
	 * Or there is only one dimension.
	 * If there is only one dimension and it is 'non record' dimension,
	 * 	edp is &edges[0] and we will return -1.
	 * If there is only one dimension and and it is a "record dimension",
	 *	edp is &edges[1] (out of bounds) and we will return 0;
	 */
	assert(shp >= varp->shape + varp->ndims -1
		|| *(edp +1) == *(shp +1));

	/* now accumulate max count for a single io operation */
	for(*iocountp = 1, edp0 = edp;
		 	edp0 < edges + varp->ndims;
			edp0++)
	{
		*iocountp *= *edp0;
	}

done:
	return((int)(edp - edges) - 1);
}


/*
 * Set the elements of the array 'upp' to
 * the sum of the corresponding elements of
 * 'stp' and 'edp'. 'end' should be &stp[nelems].
 */
static void
set_upper(size_t *upp, /* modified on return */
	const size_t *stp,
	const size_t *edp,
	const size_t *const end)
{
	while(upp < end) {
		*upp++ = *stp++ + *edp++;
	}
}


/*
 * The infamous and oft-discussed odometer code.
 *
 * 'start[]' is the starting coordinate.
 * 'upper[]' is the upper bound s.t. start[ii] < upper[ii].
 * 'coord[]' is the register, the current coordinate value.
 * For some ii,
 * upp == &upper[ii]
 * cdp == &coord[ii]
 *
 * Running this routine increments *cdp.
 *
 * If after the increment, *cdp is equal to *upp
 * (and cdp is not the leftmost dimension),
 * *cdp is "zeroed" to the starting value and
 * we need to "carry", eg, increment one place to
 * the left.
 *
 * TODO: Some architectures hate recursion?
 * 	Reimplement non-recursively.
 */
static void
odo1(const size_t *const start, const size_t *const upper,
	size_t *const coord, /* modified on return */
	const size_t *upp,
	size_t *cdp)
{
	assert(coord <= cdp && cdp <= coord + NC_MAX_VAR_DIMS);
	assert(upper <= upp && upp <= upper + NC_MAX_VAR_DIMS);
	assert(upp - upper == cdp - coord);

	assert(*cdp <= *upp);

	(*cdp)++;
	if(cdp != coord && *cdp >= *upp)
	{
		*cdp = start[cdp - coord];
		odo1(start, upper, coord, upp -1, cdp -1);
	}
}
#ifdef _CRAYC
#pragma _CRI noinline odo1
#endif



/* Define a macro to allow hash on two type values */
#define CASE(nc1,nc2) (nc1*256+nc2)

static int
readNCv(const NC3_INFO* ncp, const NC_var* varp, const size_t* start,
        const size_t nelems, void* value, const nc_type memtype)
{
    int status = NC_NOERR;
    switch (CASE(varp->type,memtype)) {

    case CASE(NC_CHAR,NC_CHAR):
    case CASE(NC_CHAR,NC_UBYTE):
    return getNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value);
    break;
    case CASE(NC_BYTE,NC_BYTE):
        return getNCvx_schar_schar(ncp,varp,start,nelems, (schar*)value);
	break;
    case CASE(NC_BYTE,NC_UBYTE):
        if (fIsSet(ncp->flags,NC_64BIT_DATA))
            return getNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
        else
            /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
            return getNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_BYTE,NC_SHORT):
        return getNCvx_schar_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_BYTE,NC_INT):
        return getNCvx_schar_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_BYTE,NC_FLOAT):
        return getNCvx_schar_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_BYTE,NC_DOUBLE):
        return getNCvx_schar_double(ncp,varp,start,nelems,(double *)value);
	break;
    case CASE(NC_BYTE,NC_INT64):
        return getNCvx_schar_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_BYTE,NC_UINT):
        return getNCvx_schar_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_BYTE,NC_UINT64):
        return getNCvx_schar_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
    	break;
    case CASE(NC_BYTE,NC_USHORT):
        return getNCvx_schar_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_SHORT,NC_BYTE):
        return getNCvx_short_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_SHORT,NC_UBYTE):
        return getNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_SHORT,NC_SHORT):
        return getNCvx_short_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_SHORT,NC_INT):
        return getNCvx_short_int(ncp,varp,start,nelems,(int*)value);
	break;
   case CASE(NC_SHORT,NC_FLOAT):
        return getNCvx_short_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_SHORT,NC_DOUBLE):
        return getNCvx_short_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_SHORT,NC_INT64):
        return getNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value);
   	break;
    case CASE(NC_SHORT,NC_UINT):
        return getNCvx_short_uint(ncp,varp,start,nelems,(unsigned int*)value);
    	break;
    case CASE(NC_SHORT,NC_UINT64):
        return getNCvx_short_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_SHORT,NC_USHORT):
        return getNCvx_short_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_INT,NC_BYTE):
        return getNCvx_int_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_INT,NC_UBYTE):
        return getNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_INT,NC_SHORT):
        return getNCvx_int_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_INT,NC_INT):
        return getNCvx_int_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_INT,NC_FLOAT):
        return getNCvx_int_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_INT,NC_DOUBLE):
        return getNCvx_int_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_INT,NC_INT64):
        return getNCvx_int_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_INT,NC_UINT):
        return getNCvx_int_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_INT,NC_UINT64):
        return getNCvx_int_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_INT,NC_USHORT):
        return getNCvx_int_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_FLOAT,NC_BYTE):
        return getNCvx_float_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_FLOAT,NC_UBYTE):
        return getNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_FLOAT,NC_SHORT):
        return getNCvx_float_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_FLOAT,NC_INT):
        return getNCvx_float_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_FLOAT,NC_FLOAT):
        return getNCvx_float_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_FLOAT,NC_DOUBLE):
        return getNCvx_float_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_FLOAT,NC_INT64):
        return getNCvx_float_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_FLOAT,NC_UINT):
        return getNCvx_float_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_FLOAT,NC_UINT64):
        return getNCvx_float_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_FLOAT,NC_USHORT):
        return getNCvx_float_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_DOUBLE,NC_BYTE):
        return getNCvx_double_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_DOUBLE,NC_UBYTE):
        return getNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_DOUBLE,NC_SHORT):
        return getNCvx_double_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_DOUBLE,NC_INT):
        return getNCvx_double_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_DOUBLE,NC_FLOAT):
        return getNCvx_double_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_DOUBLE,NC_DOUBLE):
        return getNCvx_double_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_DOUBLE,NC_INT64):
        return getNCvx_double_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_DOUBLE,NC_UINT):
        return getNCvx_double_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_DOUBLE,NC_UINT64):
        return getNCvx_double_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_DOUBLE,NC_USHORT):
        return getNCvx_double_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_UBYTE,NC_UBYTE):
        return getNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_UBYTE,NC_BYTE):
        return getNCvx_uchar_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_UBYTE,NC_SHORT):
        return getNCvx_uchar_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_UBYTE,NC_INT):
        return getNCvx_uchar_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_UBYTE,NC_FLOAT):
        return getNCvx_uchar_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_UBYTE,NC_DOUBLE):
        return getNCvx_uchar_double(ncp,varp,start,nelems,(double *)value);
	break;
    case CASE(NC_UBYTE,NC_INT64):
        return getNCvx_uchar_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_UBYTE,NC_UINT):
        return getNCvx_uchar_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_UBYTE,NC_UINT64):
        return getNCvx_uchar_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_UBYTE,NC_USHORT):
        return getNCvx_uchar_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_USHORT,NC_BYTE):
        return getNCvx_ushort_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_USHORT,NC_UBYTE):
        return getNCvx_ushort_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_USHORT,NC_SHORT):
        return getNCvx_ushort_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_USHORT,NC_INT):
        return getNCvx_ushort_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_USHORT,NC_FLOAT):
        return getNCvx_ushort_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_USHORT,NC_DOUBLE):
        return getNCvx_ushort_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_USHORT,NC_INT64):
        return getNCvx_ushort_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_USHORT,NC_UINT):
        return getNCvx_ushort_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_USHORT,NC_UINT64):
        return getNCvx_ushort_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_USHORT,NC_USHORT):
        return getNCvx_ushort_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_UINT,NC_BYTE):
        return getNCvx_uint_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_UINT,NC_UBYTE):
        return getNCvx_uint_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_UINT,NC_SHORT):
        return getNCvx_uint_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_UINT,NC_INT):
        return getNCvx_uint_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_UINT,NC_FLOAT):
        return getNCvx_uint_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_UINT,NC_DOUBLE):
        return getNCvx_uint_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_UINT,NC_INT64):
        return getNCvx_uint_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_UINT,NC_UINT):
        return getNCvx_uint_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_UINT,NC_UINT64):
        return getNCvx_uint_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_UINT,NC_USHORT):
        return getNCvx_uint_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_INT64,NC_BYTE):
        return getNCvx_longlong_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_INT64,NC_UBYTE):
        return getNCvx_longlong_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_INT64,NC_SHORT):
        return getNCvx_longlong_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_INT64,NC_INT):
        return getNCvx_longlong_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_INT64,NC_FLOAT):
        return getNCvx_longlong_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_INT64,NC_DOUBLE):
        return getNCvx_longlong_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_INT64,NC_INT64):
        return getNCvx_longlong_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_INT64,NC_UINT):
        return getNCvx_longlong_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_INT64,NC_UINT64):
        return getNCvx_longlong_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_INT64,NC_USHORT):
        return getNCvx_longlong_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    case CASE(NC_UINT64,NC_BYTE):
        return getNCvx_ulonglong_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_UINT64,NC_UBYTE):
        return getNCvx_ulonglong_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_UINT64,NC_SHORT):
        return getNCvx_ulonglong_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_UINT64,NC_INT):
        return getNCvx_ulonglong_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_UINT64,NC_FLOAT):
        return getNCvx_ulonglong_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_UINT64,NC_DOUBLE):
        return getNCvx_ulonglong_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_UINT64,NC_INT64):
        return getNCvx_ulonglong_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_UINT64,NC_UINT):
        return getNCvx_ulonglong_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_UINT64,NC_UINT64):
        return getNCvx_ulonglong_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_UINT64,NC_USHORT):
        return getNCvx_ulonglong_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    default:
	return NC_EBADTYPE;
	break;
    }
    return status;
}


static int
writeNCv(NC3_INFO* ncp, const NC_var* varp, const size_t* start,
         const size_t nelems, const void* value, const nc_type memtype)
{
    int status = NC_NOERR;
    switch (CASE(varp->type,memtype)) {

    case CASE(NC_CHAR,NC_CHAR):
    case CASE(NC_CHAR,NC_UBYTE):
        return putNCvx_char_char(ncp,varp,start,nelems,(char*)value);
	break;
    case CASE(NC_BYTE,NC_BYTE):
        return putNCvx_schar_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_BYTE,NC_UBYTE):
        if (fIsSet(ncp->flags,NC_64BIT_DATA))
            return putNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
        else
            /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
            return putNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_BYTE,NC_SHORT):
        return putNCvx_schar_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_BYTE,NC_INT):
        return putNCvx_schar_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_BYTE,NC_FLOAT):
        return putNCvx_schar_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_BYTE,NC_DOUBLE):
        return putNCvx_schar_double(ncp,varp,start,nelems,(double *)value);
	break;
    case CASE(NC_BYTE,NC_INT64):
        return putNCvx_schar_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_BYTE,NC_UINT):
        return putNCvx_schar_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_BYTE,NC_UINT64):
        return putNCvx_schar_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_BYTE,NC_USHORT):
        return putNCvx_schar_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_SHORT,NC_BYTE):
        return putNCvx_short_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_SHORT,NC_UBYTE):
        return putNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_SHORT,NC_SHORT):
        return putNCvx_short_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_SHORT,NC_INT):
        return putNCvx_short_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_SHORT,NC_FLOAT):
        return putNCvx_short_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_SHORT,NC_DOUBLE):
        return putNCvx_short_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_SHORT,NC_INT64):
        return putNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_SHORT,NC_UINT):
        return putNCvx_short_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_SHORT,NC_UINT64):
        return putNCvx_short_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_SHORT,NC_USHORT):
        return putNCvx_short_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_INT,NC_BYTE):
        return putNCvx_int_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_INT,NC_UBYTE):
        return putNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_INT,NC_SHORT):
        return putNCvx_int_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_INT,NC_INT):
        return putNCvx_int_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_INT,NC_FLOAT):
        return putNCvx_int_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_INT,NC_DOUBLE):
        return putNCvx_int_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_INT,NC_INT64):
        return putNCvx_int_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_INT,NC_UINT):
        return putNCvx_int_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_INT,NC_UINT64):
        return putNCvx_int_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_INT,NC_USHORT):
        return putNCvx_int_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_FLOAT,NC_BYTE):
        return putNCvx_float_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_FLOAT,NC_UBYTE):
        return putNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_FLOAT,NC_SHORT):
        return putNCvx_float_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_FLOAT,NC_INT):
        return putNCvx_float_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_FLOAT,NC_FLOAT):
        return putNCvx_float_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_FLOAT,NC_DOUBLE):
        return putNCvx_float_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_FLOAT,NC_INT64):
        return putNCvx_float_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_FLOAT,NC_UINT):
        return putNCvx_float_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_FLOAT,NC_UINT64):
        return putNCvx_float_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_FLOAT,NC_USHORT):
        return putNCvx_float_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_DOUBLE,NC_BYTE):
        return putNCvx_double_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_DOUBLE,NC_UBYTE):
        return putNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_DOUBLE,NC_SHORT):
        return putNCvx_double_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_DOUBLE,NC_INT):
        return putNCvx_double_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_DOUBLE,NC_FLOAT):
        return putNCvx_double_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_DOUBLE,NC_DOUBLE):
        return putNCvx_double_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_DOUBLE,NC_INT64):
        return putNCvx_double_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_DOUBLE,NC_UINT):
        return putNCvx_double_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_DOUBLE,NC_UINT64):
        return putNCvx_double_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_DOUBLE,NC_USHORT):
        return putNCvx_double_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_UBYTE,NC_UBYTE):
        return putNCvx_uchar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_UBYTE,NC_BYTE):
        return putNCvx_uchar_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_UBYTE,NC_SHORT):
        return putNCvx_uchar_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_UBYTE,NC_INT):
        return putNCvx_uchar_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_UBYTE,NC_FLOAT):
        return putNCvx_uchar_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_UBYTE,NC_DOUBLE):
        return putNCvx_uchar_double(ncp,varp,start,nelems,(double *)value);
	break;
    case CASE(NC_UBYTE,NC_INT64):
        return putNCvx_uchar_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_UBYTE,NC_UINT):
        return putNCvx_uchar_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_UBYTE,NC_UINT64):
        return putNCvx_uchar_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_UBYTE,NC_USHORT):
        return putNCvx_uchar_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_USHORT,NC_BYTE):
        return putNCvx_ushort_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_USHORT,NC_UBYTE):
        return putNCvx_ushort_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_USHORT,NC_SHORT):
        return putNCvx_ushort_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_USHORT,NC_INT):
        return putNCvx_ushort_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_USHORT,NC_FLOAT):
        return putNCvx_ushort_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_USHORT,NC_DOUBLE):
        return putNCvx_ushort_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_USHORT,NC_INT64):
        return putNCvx_ushort_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_USHORT,NC_UINT):
        return putNCvx_ushort_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_USHORT,NC_UINT64):
        return putNCvx_ushort_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_USHORT,NC_USHORT):
        return putNCvx_ushort_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_UINT,NC_BYTE):
        return putNCvx_uint_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_UINT,NC_UBYTE):
        return putNCvx_uint_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_UINT,NC_SHORT):
        return putNCvx_uint_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_UINT,NC_INT):
        return putNCvx_uint_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_UINT,NC_FLOAT):
        return putNCvx_uint_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_UINT,NC_DOUBLE):
        return putNCvx_uint_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_UINT,NC_INT64):
        return putNCvx_uint_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_UINT,NC_UINT):
        return putNCvx_uint_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_UINT,NC_UINT64):
        return putNCvx_uint_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_UINT,NC_USHORT):
        return putNCvx_uint_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_INT64,NC_BYTE):
        return putNCvx_longlong_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_INT64,NC_UBYTE):
        return putNCvx_longlong_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_INT64,NC_SHORT):
        return putNCvx_longlong_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_INT64,NC_INT):
        return putNCvx_longlong_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_INT64,NC_FLOAT):
        return putNCvx_longlong_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_INT64,NC_DOUBLE):
        return putNCvx_longlong_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_INT64,NC_INT64):
        return putNCvx_longlong_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_INT64,NC_UINT):
        return putNCvx_longlong_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_INT64,NC_UINT64):
        return putNCvx_longlong_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_INT64,NC_USHORT):
        return putNCvx_longlong_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;
    case CASE(NC_UINT64,NC_BYTE):
        return putNCvx_ulonglong_schar(ncp,varp,start,nelems,(schar*)value);
	break;
    case CASE(NC_UINT64,NC_UBYTE):
        return putNCvx_ulonglong_uchar(ncp,varp,start,nelems,(unsigned char*)value);
	break;
    case CASE(NC_UINT64,NC_SHORT):
        return putNCvx_ulonglong_short(ncp,varp,start,nelems,(short*)value);
	break;
    case CASE(NC_UINT64,NC_INT):
        return putNCvx_ulonglong_int(ncp,varp,start,nelems,(int*)value);
	break;
    case CASE(NC_UINT64,NC_FLOAT):
        return putNCvx_ulonglong_float(ncp,varp,start,nelems,(float*)value);
	break;
    case CASE(NC_UINT64,NC_DOUBLE):
        return putNCvx_ulonglong_double(ncp,varp,start,nelems,(double*)value);
	break;
    case CASE(NC_UINT64,NC_INT64):
        return putNCvx_ulonglong_longlong(ncp,varp,start,nelems,(long long*)value);
	break;
    case CASE(NC_UINT64,NC_UINT):
        return putNCvx_ulonglong_uint(ncp,varp,start,nelems,(unsigned int*)value);
	break;
    case CASE(NC_UINT64,NC_UINT64):
        return putNCvx_ulonglong_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
	break;
    case CASE(NC_UINT64,NC_USHORT):
        return putNCvx_ulonglong_ushort(ncp,varp,start,nelems,(unsigned short*)value);
	break;

    default:
	return NC_EBADTYPE;
	break;
    }
    return status;
}

/**************************************************/

int
NC3_get_vara(int ncid, int varid,
	    const size_t *start, const size_t *edges0,
            void *value0,
	    nc_type memtype)
{
    int status = NC_NOERR;
    NC* nc;
    NC3_INFO* nc3;
    NC_var *varp;
    int ii;
    size_t iocount;
    size_t memtypelen;
    signed char* value = (signed char*) value0; /* legally allow ptr arithmetic */
    const size_t* edges = edges0; /* so we can modify for special cases */
    size_t modedges[NC_MAX_VAR_DIMS];

    status = NC_check_id(ncid, &nc);
    if(status != NC_NOERR)
        return status;
    nc3 = NC3_DATA(nc);

    if(NC_indef(nc3))
        return NC_EINDEFINE;

    status = NC_lookupvar(nc3, varid, &varp);
    if(status != NC_NOERR)
        return status;

    if(memtype == NC_NAT) memtype=varp->type;

    if(memtype == NC_CHAR && varp->type != NC_CHAR)
        return NC_ECHAR;
    else if(memtype != NC_CHAR && varp->type == NC_CHAR)
        return NC_ECHAR;

    /* If edges is NULL, then this was called from nc_get_var() */
    if(edges == NULL && varp->ndims > 0) {
	/* If this is a record variable, then we have to
           substitute the number of records into dimension 0. */
	if(varp->shape[0] == 0) {
	    (void)memcpy((void*)modedges,(void*)varp->shape,
                          sizeof(size_t)*varp->ndims);
	    modedges[0] = NC_get_numrecs(nc3);
	    edges = modedges;
	} else
	    edges = varp->shape;
    }

    status = NCcoordck(nc3, varp, start);
    if(status != NC_NOERR)
        return status;

    status = NCedgeck(nc3, varp, start, edges);
    if(status != NC_NOERR)
        return status;

    /* Get the size of the memtype */
    memtypelen = nctypelen(memtype);

    if(varp->ndims == 0) /* scalar variable */
    {
        return( readNCv(nc3, varp, start, 1, (void*)value, memtype) );
    }

    if(IS_RECVAR(varp))
    {
        if(*start + *edges > NC_get_numrecs(nc3))
            return NC_EEDGE;
        if(varp->ndims == 1 && nc3->recsize <= varp->len)
        {
            /* one dimensional && the only record variable  */
            return( readNCv(nc3, varp, start, *edges, (void*)value, memtype) );
        }
    }

    /*
     * find max contiguous
     *   and accumulate max count for a single io operation
     */
    ii = NCiocount(nc3, varp, edges, &iocount);

    if(ii == -1)
    {
        return( readNCv(nc3, varp, start, iocount, (void*)value, memtype) );
    }

    assert(ii >= 0);

    { /* inline */
    ALLOC_ONSTACK(coord, size_t, varp->ndims);
    ALLOC_ONSTACK(upper, size_t, varp->ndims);
    const size_t index = ii;

    /* copy in starting indices */
    (void) memcpy(coord, start, varp->ndims * sizeof(size_t));

    /* set up in maximum indices */
    set_upper(upper, start, edges, &upper[varp->ndims]);

    /* ripple counter */
    while(*coord < *upper)
    {
        const int lstatus = readNCv(nc3, varp, coord, iocount, (void*)value, memtype);
	if(lstatus != NC_NOERR)
        {
            if(lstatus != NC_ERANGE)
            {
                status = lstatus;
                /* fatal for the loop */
                break;
            }
            /* else NC_ERANGE, not fatal for the loop */
            if(status == NC_NOERR)
                status = lstatus;
        }
        value += (iocount * memtypelen);
        odo1(start, upper, coord, &upper[index], &coord[index]);
    }

    FREE_ONSTACK(upper);
    FREE_ONSTACK(coord);
    } /* end inline */

    return status;
}

int
NC3_put_vara(int ncid, int varid,
	    const size_t *start, const size_t *edges0,
            const void *value0,
	    nc_type memtype)
{
    int status = NC_NOERR;
    NC *nc;
    NC3_INFO* nc3;
    NC_var *varp;
    int ii;
    size_t iocount;
    size_t memtypelen;
    signed char* value = (signed char*) value0; /* legally allow ptr arithmetic */
    const size_t* edges = edges0; /* so we can modify for special cases */
    size_t modedges[NC_MAX_VAR_DIMS];

    status = NC_check_id(ncid, &nc);
    if(status != NC_NOERR)
        return status;
    nc3 = NC3_DATA(nc);

    if(NC_readonly(nc3))
        return NC_EPERM;

    if(NC_indef(nc3))
        return NC_EINDEFINE;

    status = NC_lookupvar(nc3, varid, &varp);
    if(status != NC_NOERR)
       return status; /*invalid varid */


    if(memtype == NC_NAT) memtype=varp->type;

    if(memtype == NC_CHAR && varp->type != NC_CHAR)
        return NC_ECHAR;
    else if(memtype != NC_CHAR && varp->type == NC_CHAR)
        return NC_ECHAR;

    /* Get the size of the memtype */
    memtypelen = nctypelen(memtype);

    /* If edges is NULL, then this was called from nc_get_var() */
    if(edges == NULL && varp->ndims > 0) {
	/* If this is a record variable, then we have to
           substitute the number of records into dimension 0. */
	if(varp->shape[0] == 0) {
	    (void)memcpy((void*)modedges,(void*)varp->shape,
                          sizeof(size_t)*varp->ndims);
	    modedges[0] = NC_get_numrecs(nc3);
	    edges = modedges;
	} else
	    edges = varp->shape;
    }

    status = NCcoordck(nc3, varp, start);
    if(status != NC_NOERR)
        return status;
    status = NCedgeck(nc3, varp, start, edges);
    if(status != NC_NOERR)
        return status;

    if(varp->ndims == 0) /* scalar variable */
    {
        return( writeNCv(nc3, varp, start, 1, (void*)value, memtype) );
    }

    if(IS_RECVAR(varp))
    {
        status = NCvnrecs(nc3, *start + *edges);
        if(status != NC_NOERR)
            return status;

        if(varp->ndims == 1
            && nc3->recsize <= varp->len)
        {
            /* one dimensional && the only record variable  */
            return( writeNCv(nc3, varp, start, *edges, (void*)value, memtype) );
        }
    }

    /*
     * find max contiguous
     *   and accumulate max count for a single io operation
     */
    ii = NCiocount(nc3, varp, edges, &iocount);

    if(ii == -1)
    {
        return( writeNCv(nc3, varp, start, iocount, (void*)value, memtype) );
    }

    assert(ii >= 0);

    { /* inline */
    ALLOC_ONSTACK(coord, size_t, varp->ndims);
    ALLOC_ONSTACK(upper, size_t, varp->ndims);
    const size_t index = ii;

    /* copy in starting indices */
    (void) memcpy(coord, start, varp->ndims * sizeof(size_t));

    /* set up in maximum indices */
    set_upper(upper, start, edges, &upper[varp->ndims]);

    /* ripple counter */
    while(*coord < *upper)
    {
        const int lstatus = writeNCv(nc3, varp, coord, iocount, (void*)value, memtype);
        if(lstatus != NC_NOERR)
        {
            if(lstatus != NC_ERANGE)
            {
                status = lstatus;
                /* fatal for the loop */
                break;
            }
            /* else NC_ERANGE, not fatal for the loop */
            if(status == NC_NOERR)
                status = lstatus;
        }
        value += (iocount * memtypelen);
        odo1(start, upper, coord, &upper[index], &coord[index]);
    }

    FREE_ONSTACK(upper);
    FREE_ONSTACK(coord);
    } /* end inline */

    return status;
}
