source: XIOS/dev/branch_openmp/extern/src_netcdf4/putget.c @ 1501

Last change on this file since 1501 was 409, checked in by ymipsl, 11 years ago

Add improved nectdf internal library src

YM

  • Property svn:eol-style set to native
File size: 115.4 KB
Line 
1/* Do not edit this file. It is produced from the corresponding .m4 source */
2/*
3 *      Copyright 1996, University Corporation for Atmospheric Research
4 *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
5 */
6/* $Id: putget.m4,v 2.79 2010/05/29 22:25:01 russ Exp $ */
7
8#include "config.h"
9#include <string.h>
10#include <stdlib.h>
11#include <assert.h>
12
13#include "netcdf.h"
14#include "nc.h"
15#include "ncx.h"
16#include "fbits.h"
17#include "onstack.h"
18#ifdef LOCKNUMREC
19#  include <mpp/shmem.h>        /* for SGI/Cray SHMEM routines */
20#  ifdef LN_TEST
21#    include <stdio.h>
22#  endif
23#endif
24#include "nc3dispatch.h"
25
26
27#undef MIN  /* system may define MIN somewhere and complain */
28#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
29
30static int
31readNCv(const NC* ncp, const NC_var* varp, const size_t* start,
32        const size_t nelems, void* value, const nc_type memtype);
33static int
34writeNCv(NC* ncp, const NC_var* varp, const size_t* start,
35         const size_t nelems, const void* value, const nc_type memtype);
36
37
38/* #define ODEBUG 1 */
39
40#if ODEBUG
41#include <stdio.h>
42/*
43 * Print the values of an array of size_t
44 */
45void
46arrayp(const char *label, size_t count, const size_t *array)
47{
48        (void) fprintf(stderr, "%s", label);
49        (void) fputc('\t',stderr);     
50        for(; count > 0; count--, array++)
51                (void) fprintf(stderr," %lu", (unsigned long)*array);
52        (void) fputc('\n',stderr);     
53}
54#endif /* ODEBUG */
55
56
57/* Begin fill */
58/*
59 * This is tunable parameter.
60 * It essentially controls the tradeoff between the number of times
61 * memcpy() gets called to copy the external data to fill
62 * a large buffer vs the number of times its called to
63 * prepare the external data.
64 */
65#if     _SX
66/* NEC SX specific optimization */
67#define NFILL   2048
68#else
69#define NFILL   16
70#endif
71
72
73
74/*
75 * Next 6 type specific functions
76 * Fill a some memory with the default special value.
77 * Formerly
78NC_arrayfill()
79 */
80static int
81NC_fill_schar(
82        void **xpp,
83        size_t nelems)  /* how many */
84{
85        schar fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];
86
87        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
88
89        {
90                schar *vp = fillp;      /* lower bound of area to be filled */
91                const schar *const end = vp + nelems;
92                while(vp < end)
93                {
94                        *vp++ = NC_FILL_BYTE;
95                }
96        }
97        return ncx_putn_schar_schar(xpp, nelems, fillp);
98}
99
100static int
101NC_fill_char(
102        void **xpp,
103        size_t nelems)  /* how many */
104{
105        char fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];
106
107        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
108
109        {
110                char *vp = fillp;       /* lower bound of area to be filled */
111                const char *const end = vp + nelems;
112                while(vp < end)
113                {
114                        *vp++ = NC_FILL_CHAR;
115                }
116        }
117        return ncx_putn_char_char(xpp, nelems, fillp);
118}
119
120static int
121NC_fill_short(
122        void **xpp,
123        size_t nelems)  /* how many */
124{
125        short fillp[NFILL * sizeof(double)/X_SIZEOF_SHORT];
126
127        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
128
129        {
130                short *vp = fillp;      /* lower bound of area to be filled */
131                const short *const end = vp + nelems;
132                while(vp < end)
133                {
134                        *vp++ = NC_FILL_SHORT;
135                }
136        }
137        return ncx_putn_short_short(xpp, nelems, fillp);
138}
139
140
141#if (SIZEOF_INT >= X_SIZEOF_INT)
142static int
143NC_fill_int(
144        void **xpp,
145        size_t nelems)  /* how many */
146{
147        int fillp[NFILL * sizeof(double)/X_SIZEOF_INT];
148
149        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
150
151        {
152                int *vp = fillp;        /* lower bound of area to be filled */
153                const int *const end = vp + nelems;
154                while(vp < end)
155                {
156                        *vp++ = NC_FILL_INT;
157                }
158        }
159        return ncx_putn_int_int(xpp, nelems, fillp);
160}
161
162#elif SIZEOF_LONG == X_SIZEOF_INT
163static int
164NC_fill_int(
165        void **xpp,
166        size_t nelems)  /* how many */
167{
168        long fillp[NFILL * sizeof(double)/X_SIZEOF_INT];
169
170        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
171
172        {
173                long *vp = fillp;       /* lower bound of area to be filled */
174                const long *const end = vp + nelems;
175                while(vp < end)
176                {
177                        *vp++ = NC_FILL_INT;
178                }
179        }
180        return ncx_putn_int_long(xpp, nelems, fillp);
181}
182
183#else
184#error "NC_fill_int implementation"
185#endif
186
187static int
188NC_fill_float(
189        void **xpp,
190        size_t nelems)  /* how many */
191{
192        float fillp[NFILL * sizeof(double)/X_SIZEOF_FLOAT];
193
194        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
195
196        {
197                float *vp = fillp;      /* lower bound of area to be filled */
198                const float *const end = vp + nelems;
199                while(vp < end)
200                {
201                        *vp++ = NC_FILL_FLOAT;
202                }
203        }
204        return ncx_putn_float_float(xpp, nelems, fillp);
205}
206
207static int
208NC_fill_double(
209        void **xpp,
210        size_t nelems)  /* how many */
211{
212        double fillp[NFILL * sizeof(double)/X_SIZEOF_DOUBLE];
213
214        assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
215
216        {
217                double *vp = fillp;     /* lower bound of area to be filled */
218                const double *const end = vp + nelems;
219                while(vp < end)
220                {
221                        *vp++ = NC_FILL_DOUBLE;
222                }
223        }
224        return ncx_putn_double_double(xpp, nelems, fillp);
225}
226
227
228
229
230
231/*
232 * Fill the external space for variable 'varp' values at 'recno' with
233 * the appropriate value. If 'varp' is not a record variable, fill the
234 * whole thing.  For the special case when 'varp' is the only record
235 * variable and it is of type byte, char, or short, varsize should be
236 * ncp->recsize, otherwise it should be varp->len.
237 * Formerly
238xdr_NC_fill()
239 */
240int
241fill_NC_var(NC *ncp, const NC_var *varp, size_t varsize, size_t recno)
242{
243        char xfillp[NFILL * X_SIZEOF_DOUBLE];
244        const size_t step = varp->xsz;
245        const size_t nelems = sizeof(xfillp)/step;
246        const size_t xsz = varp->xsz * nelems;
247        NC_attr **attrpp = NULL;
248        off_t offset;
249        size_t remaining = varsize;
250
251        void *xp;
252        int status = NC_NOERR;
253
254        /*
255         * Set up fill value
256         */
257        attrpp = NC_findattr(&varp->attrs, _FillValue);
258        if( attrpp != NULL )
259        {
260                /* User defined fill value */
261                if( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 )
262                {
263                        return NC_EBADTYPE;
264                }
265                else
266                {
267                        /* Use the user defined value */
268                        char *cp = xfillp;
269                        const char *const end = &xfillp[sizeof(xfillp)];
270
271                        assert(step <= (*attrpp)->xsz);
272
273                        for( /*NADA*/; cp < end; cp += step)
274                        {
275                                (void) memcpy(cp, (*attrpp)->xvalue, step);
276                        }
277                }
278        }
279        else
280        {
281                /* use the default */
282               
283                assert(xsz % X_ALIGN == 0);
284                assert(xsz <= sizeof(xfillp));
285       
286                xp = xfillp;
287       
288                switch(varp->type){
289                case NC_BYTE :
290                        status = NC_fill_schar(&xp, nelems);
291                        break;
292                case NC_CHAR :
293                        status = NC_fill_char(&xp, nelems);
294                        break;
295                case NC_SHORT :
296                        status = NC_fill_short(&xp, nelems);
297                        break;
298                case NC_INT :
299                        status = NC_fill_int(&xp, nelems);
300                        break;
301                case NC_FLOAT :
302                        status = NC_fill_float(&xp, nelems);
303                        break;
304                case NC_DOUBLE :
305                        status = NC_fill_double(&xp, nelems);
306                        break;
307                default :
308                        assert("fill_NC_var invalid type" == 0);
309                        status = NC_EBADTYPE;
310                        break;
311                }
312                if(status != NC_NOERR)
313                        return status;
314       
315                assert(xp == xfillp + xsz);
316        }
317
318        /*
319         * copyout:
320         * xfillp now contains 'nelems' elements of the fill value
321         * in external representation.
322         */
323
324        /*
325         * Copy it out.
326         */
327
328        offset = varp->begin;
329        if(IS_RECVAR(varp))
330        {
331                offset += (off_t)ncp->recsize * recno;
332        }
333
334        assert(remaining > 0);
335        for(;;)
336        {
337                const size_t chunksz = MIN(remaining, ncp->chunk);
338                size_t ii;
339
340                status = ncio_get(ncp->nciop, offset, chunksz,
341                                 RGN_WRITE, &xp);       
342                if(status != NC_NOERR)
343                {
344                        return status;
345                }
346
347                /*
348                 * fill the chunksz buffer in units  of xsz
349                 */
350                for(ii = 0; ii < chunksz/xsz; ii++)
351                {
352                        (void) memcpy(xp, xfillp, xsz);
353                        xp = (char *)xp + xsz;
354                }
355                /*
356                 * Deal with any remainder
357                 */
358                {
359                        const size_t rem = chunksz % xsz;
360                        if(rem != 0)
361                        {
362                                (void) memcpy(xp, xfillp, rem);
363                                /* xp = (char *)xp + xsz; */
364                        }
365
366                }
367
368                status = ncio_rel(ncp->nciop, offset, RGN_MODIFIED);
369
370                if(status != NC_NOERR)
371                {
372                        break;
373                }
374
375                remaining -= chunksz;
376                if(remaining == 0)
377                        break;  /* normal loop exit */
378                offset += chunksz;
379
380        }
381
382        return status;
383}
384/* End fill */
385
386
387/*
388 * Add a record containing the fill values.
389 */
390static int
391NCfillrecord(NC *ncp, const NC_var *const *varpp, size_t recno)
392{
393        size_t ii = 0;
394        for(; ii < ncp->vars.nelems; ii++, varpp++)
395        {
396                if( !IS_RECVAR(*varpp) )
397                {
398                        continue;       /* skip non-record variables */
399                }
400                {
401                const int status = fill_NC_var(ncp, *varpp, (*varpp)->len, recno);
402                if(status != NC_NOERR)
403                        return status;
404                }
405        }
406        return NC_NOERR;
407}
408
409
410/*
411 * Add a record containing the fill values in the special case when
412 * there is exactly one record variable, where we don't require each
413 * record to be four-byte aligned (no record padding).
414 */
415static int
416NCfillspecialrecord(NC *ncp, const NC_var *varp, size_t recno)
417{
418    int status;
419    assert(IS_RECVAR(varp));
420    status = fill_NC_var(ncp, varp, ncp->recsize, recno);
421    if(status != NC_NOERR)
422        return status;
423    return NC_NOERR;
424}
425
426
427/*
428 * It is advantageous to
429 * #define TOUCH_LAST
430 * when using memory mapped io.
431 */
432#if TOUCH_LAST
433/*
434 * Grow the file to a size which can contain recno
435 */
436static int
437NCtouchlast(NC *ncp, const NC_var *const *varpp, size_t recno)
438{
439        int status = NC_NOERR;
440        const NC_var *varp = NULL;
441       
442        {
443        size_t ii = 0;
444        for(; ii < ncp->vars.nelems; ii++, varpp++)
445        {
446                if( !IS_RECVAR(*varpp) )
447                {
448                        continue;       /* skip non-record variables */
449                }
450                varp = *varpp;
451        }
452        }
453        assert(varp != NULL);
454        assert( IS_RECVAR(varp) );
455        {
456                const off_t offset = varp->begin
457                                + (off_t)(recno-1) * (off_t)ncp->recsize
458                                + (off_t)(varp->len - varp->xsz);
459                void *xp;
460
461
462                status = ncio_get(ncp->nciop, offset, varp->xsz,
463                                 RGN_WRITE, &xp);       
464                if(status != NC_NOERR)
465                        return status;
466                (void)memset(xp, 0, varp->xsz);
467                status = ncio_rel(ncp->nciop, offset, RGN_MODIFIED);
468        }
469        return status;
470}
471#endif /* TOUCH_LAST */
472
473
474/*
475 * Ensure that the netcdf file has 'numrecs' records,
476 * add records and fill as neccessary.
477 */
478static int
479NCvnrecs(NC *ncp, size_t numrecs)
480{
481        int status = NC_NOERR;
482#ifdef LOCKNUMREC
483        ushmem_t myticket = 0, nowserving = 0;
484        ushmem_t numpe = (ushmem_t) _num_pes();
485
486        /* get ticket and wait */
487        myticket = shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
488                ncp->lock[LOCKNUMREC_BASEPE]);
489#ifdef LN_TEST
490                fprintf(stderr,"%d of %d : ticket = %hu\n",
491                        _my_pe(), _num_pes(), myticket);
492#endif
493        do {
494                shmem_short_get((shmem_t *) &nowserving,
495                        (shmem_t *) ncp->lock + LOCKNUMREC_SERVING, 1,
496                        ncp->lock[LOCKNUMREC_BASEPE]);
497#ifdef LN_TEST
498                fprintf(stderr,"%d of %d : serving = %hu\n",
499                        _my_pe(), _num_pes(), nowserving);
500#endif
501                /* work-around for non-unique tickets */
502                if (nowserving > myticket && nowserving < myticket + numpe ) {
503                        /* get a new ticket ... you've been bypassed */ 
504                        /* and handle the unlikely wrap-around effect */
505                        myticket = shmem_short_finc(
506                                (shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
507                                ncp->lock[LOCKNUMREC_BASEPE]);
508#ifdef LN_TEST
509                                fprintf(stderr,"%d of %d : new ticket = %hu\n",
510                                        _my_pe(), _num_pes(), myticket);
511#endif
512                }
513        } while(nowserving != myticket);
514        /* now our turn to check & update value */
515#endif
516
517        if(numrecs > NC_get_numrecs(ncp))
518        {
519
520
521#if TOUCH_LAST
522                status = NCtouchlast(ncp,
523                        (const NC_var *const*)ncp->vars.value,
524                        numrecs);
525                if(status != NC_NOERR)
526                        goto common_return;
527#endif /* TOUCH_LAST */
528
529                set_NC_ndirty(ncp);
530
531                if(!NC_dofill(ncp))
532                {
533                        /* Simply set the new numrecs value */
534                        NC_set_numrecs(ncp, numrecs);
535                }
536                else
537                {
538                    /* Treat two cases differently:
539                        - exactly one record variable (no padding)
540                        - multiple record variables (each record padded
541                          to 4-byte alignment)
542                    */
543                    NC_var **vpp = (NC_var **)ncp->vars.value;
544                    NC_var *const *const end = &vpp[ncp->vars.nelems];
545                    NC_var *recvarp = NULL;     /* last record var */
546                    int numrecvars = 0;
547                    size_t cur_nrecs;
548                   
549                    /* determine how many record variables */
550                    for( /*NADA*/; vpp < end; vpp++) {
551                        if(IS_RECVAR(*vpp)) {
552                            recvarp = *vpp;
553                            numrecvars++;
554                        }
555                    }
556                   
557                    if (numrecvars != 1) { /* usual case */
558                        /* Fill each record out to numrecs */
559                        while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs)
560                            {
561                                status = NCfillrecord(ncp,
562                                        (const NC_var *const*)ncp->vars.value,
563                                        cur_nrecs);
564                                if(status != NC_NOERR)
565                                {
566                                        break;
567                                }
568                                NC_increase_numrecs(ncp, cur_nrecs +1);
569                        }
570                        if(status != NC_NOERR)
571                                goto common_return;
572                    } else {    /* special case */
573                        /* Fill each record out to numrecs */
574                        while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs)
575                            {
576                                status = NCfillspecialrecord(ncp,
577                                        recvarp,
578                                        cur_nrecs);
579                                if(status != NC_NOERR)
580                                {
581                                        break;
582                                }
583                                NC_increase_numrecs(ncp, cur_nrecs +1);
584                        }
585                        if(status != NC_NOERR)
586                                goto common_return;
587                       
588                    }
589                }
590
591                if(NC_doNsync(ncp))
592                {
593                        status = write_numrecs(ncp);
594                }
595
596        }
597common_return:
598#ifdef LOCKNUMREC
599        /* finished with our lock - increment serving number */
600        (void) shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_SERVING,
601                ncp->lock[LOCKNUMREC_BASEPE]);
602#endif
603        return status;
604}
605
606
607/*
608 * Check whether 'coord' values are valid for the variable.
609 */
610static int
611NCcoordck(NC *ncp, const NC_var *varp, const size_t *coord)
612{
613        const size_t *ip;
614        size_t *up;
615
616        if(varp->ndims == 0)
617                return NC_NOERR;        /* 'scalar' variable */
618
619        if(IS_RECVAR(varp))
620        {
621                if(*coord > X_UINT_MAX) /* rkr: bug fix from previous X_INT_MAX */
622                        return NC_EINVALCOORDS; /* sanity check */
623                if(NC_readonly(ncp) && *coord >= NC_get_numrecs(ncp))
624                {
625                        if(!NC_doNsync(ncp))
626                                return NC_EINVALCOORDS;
627                        /* else */
628                        {
629                                /* Update from disk and check again */
630                                const int status = read_numrecs(ncp);
631                                if(status != NC_NOERR)
632                                        return status;
633                                if(*coord >= NC_get_numrecs(ncp))
634                                        return NC_EINVALCOORDS;
635                        }
636                }
637                ip = coord + 1;
638                up = varp->shape + 1;
639        }
640        else
641        {
642                ip = coord;
643                up = varp->shape;
644        }
645       
646#ifdef CDEBUG
647fprintf(stderr,"        NCcoordck: coord %ld, count %d, ip %ld\n",
648                coord, varp->ndims, ip );
649#endif /* CDEBUG */
650
651        for(; ip < coord + varp->ndims; ip++, up++)
652        {
653
654#ifdef CDEBUG
655fprintf(stderr,"        NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n",
656                        ip, *ip, up, *up );
657#endif /* CDEBUG */
658
659                /* cast needed for braindead systems with signed size_t */
660                if((unsigned long) *ip >= (unsigned long) *up )
661                        return NC_EINVALCOORDS;
662        }
663
664        return NC_NOERR;
665}
666
667
668/*
669 * Check whether 'edges' are valid for the variable and 'start'
670 */
671/*ARGSUSED*/
672static int
673NCedgeck(const NC *ncp, const NC_var *varp,
674         const size_t *start, const size_t *edges)
675{
676        const size_t *const end = start + varp->ndims;
677        const size_t *shp = varp->shape;
678
679        if(varp->ndims == 0)
680                return NC_NOERR;        /* 'scalar' variable */
681
682        if(IS_RECVAR(varp))
683        {
684                start++;
685                edges++;
686                shp++;
687        }
688
689        for(; start < end; start++, edges++, shp++)
690        {
691                /* cast needed for braindead systems with signed size_t */
692                if((unsigned long) *edges > *shp ||
693                        (unsigned long) *start + (unsigned long) *edges > *shp)
694                {
695                        return(NC_EEDGE);
696                }
697        }
698        return NC_NOERR;
699}
700
701
702/*
703 * Translate the (variable, coord) pair into a seek index
704 */
705static off_t
706NC_varoffset(const NC *ncp, const NC_var *varp, const size_t *coord)
707{
708        if(varp->ndims == 0) /* 'scalar' variable */
709                return varp->begin;
710
711        if(varp->ndims == 1)
712        {
713                if(IS_RECVAR(varp))
714                        return varp->begin +
715                                 (off_t)(*coord) * (off_t)ncp->recsize;
716                /* else */
717                return varp->begin + (off_t)(*coord) * (off_t)varp->xsz;
718        }
719        /* else */
720        {
721                off_t lcoord = (off_t)coord[varp->ndims -1];
722
723                off_t *up = varp->dsizes +1;
724                const size_t *ip = coord;
725                const off_t *const end = varp->dsizes + varp->ndims;
726               
727                if(IS_RECVAR(varp))
728                        up++, ip++;
729
730                for(; up < end; up++, ip++)
731                        lcoord += (off_t)(*up) * (off_t)(*ip);
732
733                lcoord *= varp->xsz;
734               
735                if(IS_RECVAR(varp))
736                        lcoord += (off_t)(*coord) * ncp->recsize;
737               
738                lcoord += varp->begin;
739                return lcoord;
740        }
741}
742
743
744
745static int
746putNCvx_char_char(NC *ncp, const NC_var *varp,
747                 const size_t *start, size_t nelems, const char *value)
748{
749        off_t offset = NC_varoffset(ncp, varp, start);
750        size_t remaining = varp->xsz * nelems;
751        int status = NC_NOERR;
752        void *xp;
753
754        if(nelems == 0)
755                return NC_NOERR;
756
757        assert(value != NULL);
758
759        for(;;)
760        {
761                size_t extent = MIN(remaining, ncp->chunk);
762                size_t nput = ncx_howmany(varp->type, extent);
763
764                int lstatus = ncio_get(ncp->nciop, offset, extent,
765                                 RGN_WRITE, &xp);       
766                if(lstatus != NC_NOERR)
767                        return lstatus;
768               
769                lstatus = ncx_putn_char_char(&xp, nput, value);
770                if(lstatus != NC_NOERR && status == NC_NOERR)
771                {
772                        /* not fatal to the loop */
773                        status = lstatus;
774                }
775
776                (void) ncio_rel(ncp->nciop, offset,
777                                 RGN_MODIFIED); 
778
779                remaining -= extent;
780                if(remaining == 0)
781                        break; /* normal loop exit */
782                offset += extent;
783                value += nput;
784
785        }
786
787        return status;
788}
789
790
791static int
792putNCvx_schar_schar(NC *ncp, const NC_var *varp,
793                 const size_t *start, size_t nelems, const schar *value)
794{
795        off_t offset = NC_varoffset(ncp, varp, start);
796        size_t remaining = varp->xsz * nelems;
797        int status = NC_NOERR;
798        void *xp;
799
800        if(nelems == 0)
801                return NC_NOERR;
802
803        assert(value != NULL);
804
805        for(;;)
806        {
807                size_t extent = MIN(remaining, ncp->chunk);
808                size_t nput = ncx_howmany(varp->type, extent);
809
810                int lstatus = ncio_get(ncp->nciop, offset, extent,
811                                 RGN_WRITE, &xp);       
812                if(lstatus != NC_NOERR)
813                        return lstatus;
814               
815                lstatus = ncx_putn_schar_schar(&xp, nput, value);
816                if(lstatus != NC_NOERR && status == NC_NOERR)
817                {
818                        /* not fatal to the loop */
819                        status = lstatus;
820                }
821
822                (void) ncio_rel(ncp->nciop, offset,
823                                 RGN_MODIFIED); 
824
825                remaining -= extent;
826                if(remaining == 0)
827                        break; /* normal loop exit */
828                offset += extent;
829                value += nput;
830
831        }
832
833        return status;
834}
835
836static int
837putNCvx_schar_uchar(NC *ncp, const NC_var *varp,
838                 const size_t *start, size_t nelems, const uchar *value)
839{
840        off_t offset = NC_varoffset(ncp, varp, start);
841        size_t remaining = varp->xsz * nelems;
842        int status = NC_NOERR;
843        void *xp;
844
845        if(nelems == 0)
846                return NC_NOERR;
847
848        assert(value != NULL);
849
850        for(;;)
851        {
852                size_t extent = MIN(remaining, ncp->chunk);
853                size_t nput = ncx_howmany(varp->type, extent);
854
855                int lstatus = ncio_get(ncp->nciop, offset, extent,
856                                 RGN_WRITE, &xp);       
857                if(lstatus != NC_NOERR)
858                        return lstatus;
859               
860                lstatus = ncx_putn_schar_uchar(&xp, nput, value);
861                if(lstatus != NC_NOERR && status == NC_NOERR)
862                {
863                        /* not fatal to the loop */
864                        status = lstatus;
865                }
866
867                (void) ncio_rel(ncp->nciop, offset,
868                                 RGN_MODIFIED); 
869
870                remaining -= extent;
871                if(remaining == 0)
872                        break; /* normal loop exit */
873                offset += extent;
874                value += nput;
875
876        }
877
878        return status;
879}
880
881static int
882putNCvx_schar_short(NC *ncp, const NC_var *varp,
883                 const size_t *start, size_t nelems, const short *value)
884{
885        off_t offset = NC_varoffset(ncp, varp, start);
886        size_t remaining = varp->xsz * nelems;
887        int status = NC_NOERR;
888        void *xp;
889
890        if(nelems == 0)
891                return NC_NOERR;
892
893        assert(value != NULL);
894
895        for(;;)
896        {
897                size_t extent = MIN(remaining, ncp->chunk);
898                size_t nput = ncx_howmany(varp->type, extent);
899
900                int lstatus = ncio_get(ncp->nciop, offset, extent,
901                                 RGN_WRITE, &xp);       
902                if(lstatus != NC_NOERR)
903                        return lstatus;
904               
905                lstatus = ncx_putn_schar_short(&xp, nput, value);
906                if(lstatus != NC_NOERR && status == NC_NOERR)
907                {
908                        /* not fatal to the loop */
909                        status = lstatus;
910                }
911
912                (void) ncio_rel(ncp->nciop, offset,
913                                 RGN_MODIFIED); 
914
915                remaining -= extent;
916                if(remaining == 0)
917                        break; /* normal loop exit */
918                offset += extent;
919                value += nput;
920
921        }
922
923        return status;
924}
925
926static int
927putNCvx_schar_int(NC *ncp, const NC_var *varp,
928                 const size_t *start, size_t nelems, const int *value)
929{
930        off_t offset = NC_varoffset(ncp, varp, start);
931        size_t remaining = varp->xsz * nelems;
932        int status = NC_NOERR;
933        void *xp;
934
935        if(nelems == 0)
936                return NC_NOERR;
937
938        assert(value != NULL);
939
940        for(;;)
941        {
942                size_t extent = MIN(remaining, ncp->chunk);
943                size_t nput = ncx_howmany(varp->type, extent);
944
945                int lstatus = ncio_get(ncp->nciop, offset, extent,
946                                 RGN_WRITE, &xp);       
947                if(lstatus != NC_NOERR)
948                        return lstatus;
949               
950                lstatus = ncx_putn_schar_int(&xp, nput, value);
951                if(lstatus != NC_NOERR && status == NC_NOERR)
952                {
953                        /* not fatal to the loop */
954                        status = lstatus;
955                }
956
957                (void) ncio_rel(ncp->nciop, offset,
958                                 RGN_MODIFIED); 
959
960                remaining -= extent;
961                if(remaining == 0)
962                        break; /* normal loop exit */
963                offset += extent;
964                value += nput;
965
966        }
967
968        return status;
969}
970
971static int
972putNCvx_schar_float(NC *ncp, const NC_var *varp,
973                 const size_t *start, size_t nelems, const float *value)
974{
975        off_t offset = NC_varoffset(ncp, varp, start);
976        size_t remaining = varp->xsz * nelems;
977        int status = NC_NOERR;
978        void *xp;
979
980        if(nelems == 0)
981                return NC_NOERR;
982
983        assert(value != NULL);
984
985        for(;;)
986        {
987                size_t extent = MIN(remaining, ncp->chunk);
988                size_t nput = ncx_howmany(varp->type, extent);
989
990                int lstatus = ncio_get(ncp->nciop, offset, extent,
991                                 RGN_WRITE, &xp);       
992                if(lstatus != NC_NOERR)
993                        return lstatus;
994               
995                lstatus = ncx_putn_schar_float(&xp, nput, value);
996                if(lstatus != NC_NOERR && status == NC_NOERR)
997                {
998                        /* not fatal to the loop */
999                        status = lstatus;
1000                }
1001
1002                (void) ncio_rel(ncp->nciop, offset,
1003                                 RGN_MODIFIED); 
1004
1005                remaining -= extent;
1006                if(remaining == 0)
1007                        break; /* normal loop exit */
1008                offset += extent;
1009                value += nput;
1010
1011        }
1012
1013        return status;
1014}
1015
1016static int
1017putNCvx_schar_double(NC *ncp, const NC_var *varp,
1018                 const size_t *start, size_t nelems, const double *value)
1019{
1020        off_t offset = NC_varoffset(ncp, varp, start);
1021        size_t remaining = varp->xsz * nelems;
1022        int status = NC_NOERR;
1023        void *xp;
1024
1025        if(nelems == 0)
1026                return NC_NOERR;
1027
1028        assert(value != NULL);
1029
1030        for(;;)
1031        {
1032                size_t extent = MIN(remaining, ncp->chunk);
1033                size_t nput = ncx_howmany(varp->type, extent);
1034
1035                int lstatus = ncio_get(ncp->nciop, offset, extent,
1036                                 RGN_WRITE, &xp);       
1037                if(lstatus != NC_NOERR)
1038                        return lstatus;
1039               
1040                lstatus = ncx_putn_schar_double(&xp, nput, value);
1041                if(lstatus != NC_NOERR && status == NC_NOERR)
1042                {
1043                        /* not fatal to the loop */
1044                        status = lstatus;
1045                }
1046
1047                (void) ncio_rel(ncp->nciop, offset,
1048                                 RGN_MODIFIED); 
1049
1050                remaining -= extent;
1051                if(remaining == 0)
1052                        break; /* normal loop exit */
1053                offset += extent;
1054                value += nput;
1055
1056        }
1057
1058        return status;
1059}
1060
1061static int
1062putNCvx_schar_longlong(NC *ncp, const NC_var *varp,
1063                 const size_t *start, size_t nelems, const longlong *value)
1064{
1065        off_t offset = NC_varoffset(ncp, varp, start);
1066        size_t remaining = varp->xsz * nelems;
1067        int status = NC_NOERR;
1068        void *xp;
1069
1070        if(nelems == 0)
1071                return NC_NOERR;
1072
1073        assert(value != NULL);
1074
1075        for(;;)
1076        {
1077                size_t extent = MIN(remaining, ncp->chunk);
1078                size_t nput = ncx_howmany(varp->type, extent);
1079
1080                int lstatus = ncio_get(ncp->nciop, offset, extent,
1081                                 RGN_WRITE, &xp);       
1082                if(lstatus != NC_NOERR)
1083                        return lstatus;
1084               
1085                lstatus = ncx_putn_schar_longlong(&xp, nput, value);
1086                if(lstatus != NC_NOERR && status == NC_NOERR)
1087                {
1088                        /* not fatal to the loop */
1089                        status = lstatus;
1090                }
1091
1092                (void) ncio_rel(ncp->nciop, offset,
1093                                 RGN_MODIFIED); 
1094
1095                remaining -= extent;
1096                if(remaining == 0)
1097                        break; /* normal loop exit */
1098                offset += extent;
1099                value += nput;
1100
1101        }
1102
1103        return status;
1104}
1105
1106
1107static int
1108putNCvx_short_schar(NC *ncp, const NC_var *varp,
1109                 const size_t *start, size_t nelems, const schar *value)
1110{
1111        off_t offset = NC_varoffset(ncp, varp, start);
1112        size_t remaining = varp->xsz * nelems;
1113        int status = NC_NOERR;
1114        void *xp;
1115
1116        if(nelems == 0)
1117                return NC_NOERR;
1118
1119        assert(value != NULL);
1120
1121        for(;;)
1122        {
1123                size_t extent = MIN(remaining, ncp->chunk);
1124                size_t nput = ncx_howmany(varp->type, extent);
1125
1126                int lstatus = ncio_get(ncp->nciop, offset, extent,
1127                                 RGN_WRITE, &xp);       
1128                if(lstatus != NC_NOERR)
1129                        return lstatus;
1130               
1131                lstatus = ncx_putn_short_schar(&xp, nput, value);
1132                if(lstatus != NC_NOERR && status == NC_NOERR)
1133                {
1134                        /* not fatal to the loop */
1135                        status = lstatus;
1136                }
1137
1138                (void) ncio_rel(ncp->nciop, offset,
1139                                 RGN_MODIFIED); 
1140
1141                remaining -= extent;
1142                if(remaining == 0)
1143                        break; /* normal loop exit */
1144                offset += extent;
1145                value += nput;
1146
1147        }
1148
1149        return status;
1150}
1151
1152static int
1153putNCvx_short_uchar(NC *ncp, const NC_var *varp,
1154                 const size_t *start, size_t nelems, const uchar *value)
1155{
1156        off_t offset = NC_varoffset(ncp, varp, start);
1157        size_t remaining = varp->xsz * nelems;
1158        int status = NC_NOERR;
1159        void *xp;
1160
1161        if(nelems == 0)
1162                return NC_NOERR;
1163
1164        assert(value != NULL);
1165
1166        for(;;)
1167        {
1168                size_t extent = MIN(remaining, ncp->chunk);
1169                size_t nput = ncx_howmany(varp->type, extent);
1170
1171                int lstatus = ncio_get(ncp->nciop, offset, extent,
1172                                 RGN_WRITE, &xp);       
1173                if(lstatus != NC_NOERR)
1174                        return lstatus;
1175               
1176                lstatus = ncx_putn_short_uchar(&xp, nput, value);
1177                if(lstatus != NC_NOERR && status == NC_NOERR)
1178                {
1179                        /* not fatal to the loop */
1180                        status = lstatus;
1181                }
1182
1183                (void) ncio_rel(ncp->nciop, offset,
1184                                 RGN_MODIFIED); 
1185
1186                remaining -= extent;
1187                if(remaining == 0)
1188                        break; /* normal loop exit */
1189                offset += extent;
1190                value += nput;
1191
1192        }
1193
1194        return status;
1195}
1196
1197static int
1198putNCvx_short_short(NC *ncp, const NC_var *varp,
1199                 const size_t *start, size_t nelems, const short *value)
1200{
1201        off_t offset = NC_varoffset(ncp, varp, start);
1202        size_t remaining = varp->xsz * nelems;
1203        int status = NC_NOERR;
1204        void *xp;
1205
1206        if(nelems == 0)
1207                return NC_NOERR;
1208
1209        assert(value != NULL);
1210
1211        for(;;)
1212        {
1213                size_t extent = MIN(remaining, ncp->chunk);
1214                size_t nput = ncx_howmany(varp->type, extent);
1215
1216                int lstatus = ncio_get(ncp->nciop, offset, extent,
1217                                 RGN_WRITE, &xp);       
1218                if(lstatus != NC_NOERR)
1219                        return lstatus;
1220               
1221                lstatus = ncx_putn_short_short(&xp, nput, value);
1222                if(lstatus != NC_NOERR && status == NC_NOERR)
1223                {
1224                        /* not fatal to the loop */
1225                        status = lstatus;
1226                }
1227
1228                (void) ncio_rel(ncp->nciop, offset,
1229                                 RGN_MODIFIED); 
1230
1231                remaining -= extent;
1232                if(remaining == 0)
1233                        break; /* normal loop exit */
1234                offset += extent;
1235                value += nput;
1236
1237        }
1238
1239        return status;
1240}
1241
1242static int
1243putNCvx_short_int(NC *ncp, const NC_var *varp,
1244                 const size_t *start, size_t nelems, const int *value)
1245{
1246        off_t offset = NC_varoffset(ncp, varp, start);
1247        size_t remaining = varp->xsz * nelems;
1248        int status = NC_NOERR;
1249        void *xp;
1250
1251        if(nelems == 0)
1252                return NC_NOERR;
1253
1254        assert(value != NULL);
1255
1256        for(;;)
1257        {
1258                size_t extent = MIN(remaining, ncp->chunk);
1259                size_t nput = ncx_howmany(varp->type, extent);
1260
1261                int lstatus = ncio_get(ncp->nciop, offset, extent,
1262                                 RGN_WRITE, &xp);       
1263                if(lstatus != NC_NOERR)
1264                        return lstatus;
1265               
1266                lstatus = ncx_putn_short_int(&xp, nput, value);
1267                if(lstatus != NC_NOERR && status == NC_NOERR)
1268                {
1269                        /* not fatal to the loop */
1270                        status = lstatus;
1271                }
1272
1273                (void) ncio_rel(ncp->nciop, offset,
1274                                 RGN_MODIFIED); 
1275
1276                remaining -= extent;
1277                if(remaining == 0)
1278                        break; /* normal loop exit */
1279                offset += extent;
1280                value += nput;
1281
1282        }
1283
1284        return status;
1285}
1286
1287static int
1288putNCvx_short_float(NC *ncp, const NC_var *varp,
1289                 const size_t *start, size_t nelems, const float *value)
1290{
1291        off_t offset = NC_varoffset(ncp, varp, start);
1292        size_t remaining = varp->xsz * nelems;
1293        int status = NC_NOERR;
1294        void *xp;
1295
1296        if(nelems == 0)
1297                return NC_NOERR;
1298
1299        assert(value != NULL);
1300
1301        for(;;)
1302        {
1303                size_t extent = MIN(remaining, ncp->chunk);
1304                size_t nput = ncx_howmany(varp->type, extent);
1305
1306                int lstatus = ncio_get(ncp->nciop, offset, extent,
1307                                 RGN_WRITE, &xp);       
1308                if(lstatus != NC_NOERR)
1309                        return lstatus;
1310               
1311                lstatus = ncx_putn_short_float(&xp, nput, value);
1312                if(lstatus != NC_NOERR && status == NC_NOERR)
1313                {
1314                        /* not fatal to the loop */
1315                        status = lstatus;
1316                }
1317
1318                (void) ncio_rel(ncp->nciop, offset,
1319                                 RGN_MODIFIED); 
1320
1321                remaining -= extent;
1322                if(remaining == 0)
1323                        break; /* normal loop exit */
1324                offset += extent;
1325                value += nput;
1326
1327        }
1328
1329        return status;
1330}
1331
1332static int
1333putNCvx_short_double(NC *ncp, const NC_var *varp,
1334                 const size_t *start, size_t nelems, const double *value)
1335{
1336        off_t offset = NC_varoffset(ncp, varp, start);
1337        size_t remaining = varp->xsz * nelems;
1338        int status = NC_NOERR;
1339        void *xp;
1340
1341        if(nelems == 0)
1342                return NC_NOERR;
1343
1344        assert(value != NULL);
1345
1346        for(;;)
1347        {
1348                size_t extent = MIN(remaining, ncp->chunk);
1349                size_t nput = ncx_howmany(varp->type, extent);
1350
1351                int lstatus = ncio_get(ncp->nciop, offset, extent,
1352                                 RGN_WRITE, &xp);       
1353                if(lstatus != NC_NOERR)
1354                        return lstatus;
1355               
1356                lstatus = ncx_putn_short_double(&xp, nput, value);
1357                if(lstatus != NC_NOERR && status == NC_NOERR)
1358                {
1359                        /* not fatal to the loop */
1360                        status = lstatus;
1361                }
1362
1363                (void) ncio_rel(ncp->nciop, offset,
1364                                 RGN_MODIFIED); 
1365
1366                remaining -= extent;
1367                if(remaining == 0)
1368                        break; /* normal loop exit */
1369                offset += extent;
1370                value += nput;
1371
1372        }
1373
1374        return status;
1375}
1376
1377static int
1378putNCvx_short_longlong(NC *ncp, const NC_var *varp,
1379                 const size_t *start, size_t nelems, const longlong *value)
1380{
1381        off_t offset = NC_varoffset(ncp, varp, start);
1382        size_t remaining = varp->xsz * nelems;
1383        int status = NC_NOERR;
1384        void *xp;
1385
1386        if(nelems == 0)
1387                return NC_NOERR;
1388
1389        assert(value != NULL);
1390
1391        for(;;)
1392        {
1393                size_t extent = MIN(remaining, ncp->chunk);
1394                size_t nput = ncx_howmany(varp->type, extent);
1395
1396                int lstatus = ncio_get(ncp->nciop, offset, extent,
1397                                 RGN_WRITE, &xp);       
1398                if(lstatus != NC_NOERR)
1399                        return lstatus;
1400               
1401                lstatus = ncx_putn_short_longlong(&xp, nput, value);
1402                if(lstatus != NC_NOERR && status == NC_NOERR)
1403                {
1404                        /* not fatal to the loop */
1405                        status = lstatus;
1406                }
1407
1408                (void) ncio_rel(ncp->nciop, offset,
1409                                 RGN_MODIFIED); 
1410
1411                remaining -= extent;
1412                if(remaining == 0)
1413                        break; /* normal loop exit */
1414                offset += extent;
1415                value += nput;
1416
1417        }
1418
1419        return status;
1420}
1421
1422
1423static int
1424putNCvx_int_schar(NC *ncp, const NC_var *varp,
1425                 const size_t *start, size_t nelems, const schar *value)
1426{
1427        off_t offset = NC_varoffset(ncp, varp, start);
1428        size_t remaining = varp->xsz * nelems;
1429        int status = NC_NOERR;
1430        void *xp;
1431
1432        if(nelems == 0)
1433                return NC_NOERR;
1434
1435        assert(value != NULL);
1436
1437        for(;;)
1438        {
1439                size_t extent = MIN(remaining, ncp->chunk);
1440                size_t nput = ncx_howmany(varp->type, extent);
1441
1442                int lstatus = ncio_get(ncp->nciop, offset, extent,
1443                                 RGN_WRITE, &xp);       
1444                if(lstatus != NC_NOERR)
1445                        return lstatus;
1446               
1447                lstatus = ncx_putn_int_schar(&xp, nput, value);
1448                if(lstatus != NC_NOERR && status == NC_NOERR)
1449                {
1450                        /* not fatal to the loop */
1451                        status = lstatus;
1452                }
1453
1454                (void) ncio_rel(ncp->nciop, offset,
1455                                 RGN_MODIFIED); 
1456
1457                remaining -= extent;
1458                if(remaining == 0)
1459                        break; /* normal loop exit */
1460                offset += extent;
1461                value += nput;
1462
1463        }
1464
1465        return status;
1466}
1467
1468static int
1469putNCvx_int_uchar(NC *ncp, const NC_var *varp,
1470                 const size_t *start, size_t nelems, const uchar *value)
1471{
1472        off_t offset = NC_varoffset(ncp, varp, start);
1473        size_t remaining = varp->xsz * nelems;
1474        int status = NC_NOERR;
1475        void *xp;
1476
1477        if(nelems == 0)
1478                return NC_NOERR;
1479
1480        assert(value != NULL);
1481
1482        for(;;)
1483        {
1484                size_t extent = MIN(remaining, ncp->chunk);
1485                size_t nput = ncx_howmany(varp->type, extent);
1486
1487                int lstatus = ncio_get(ncp->nciop, offset, extent,
1488                                 RGN_WRITE, &xp);       
1489                if(lstatus != NC_NOERR)
1490                        return lstatus;
1491               
1492                lstatus = ncx_putn_int_uchar(&xp, nput, value);
1493                if(lstatus != NC_NOERR && status == NC_NOERR)
1494                {
1495                        /* not fatal to the loop */
1496                        status = lstatus;
1497                }
1498
1499                (void) ncio_rel(ncp->nciop, offset,
1500                                 RGN_MODIFIED); 
1501
1502                remaining -= extent;
1503                if(remaining == 0)
1504                        break; /* normal loop exit */
1505                offset += extent;
1506                value += nput;
1507
1508        }
1509
1510        return status;
1511}
1512
1513static int
1514putNCvx_int_short(NC *ncp, const NC_var *varp,
1515                 const size_t *start, size_t nelems, const short *value)
1516{
1517        off_t offset = NC_varoffset(ncp, varp, start);
1518        size_t remaining = varp->xsz * nelems;
1519        int status = NC_NOERR;
1520        void *xp;
1521
1522        if(nelems == 0)
1523                return NC_NOERR;
1524
1525        assert(value != NULL);
1526
1527        for(;;)
1528        {
1529                size_t extent = MIN(remaining, ncp->chunk);
1530                size_t nput = ncx_howmany(varp->type, extent);
1531
1532                int lstatus = ncio_get(ncp->nciop, offset, extent,
1533                                 RGN_WRITE, &xp);       
1534                if(lstatus != NC_NOERR)
1535                        return lstatus;
1536               
1537                lstatus = ncx_putn_int_short(&xp, nput, value);
1538                if(lstatus != NC_NOERR && status == NC_NOERR)
1539                {
1540                        /* not fatal to the loop */
1541                        status = lstatus;
1542                }
1543
1544                (void) ncio_rel(ncp->nciop, offset,
1545                                 RGN_MODIFIED); 
1546
1547                remaining -= extent;
1548                if(remaining == 0)
1549                        break; /* normal loop exit */
1550                offset += extent;
1551                value += nput;
1552
1553        }
1554
1555        return status;
1556}
1557
1558static int
1559putNCvx_int_int(NC *ncp, const NC_var *varp,
1560                 const size_t *start, size_t nelems, const int *value)
1561{
1562        off_t offset = NC_varoffset(ncp, varp, start);
1563        size_t remaining = varp->xsz * nelems;
1564        int status = NC_NOERR;
1565        void *xp;
1566
1567        if(nelems == 0)
1568                return NC_NOERR;
1569
1570        assert(value != NULL);
1571
1572        for(;;)
1573        {
1574                size_t extent = MIN(remaining, ncp->chunk);
1575                size_t nput = ncx_howmany(varp->type, extent);
1576
1577                int lstatus = ncio_get(ncp->nciop, offset, extent,
1578                                 RGN_WRITE, &xp);       
1579                if(lstatus != NC_NOERR)
1580                        return lstatus;
1581               
1582                lstatus = ncx_putn_int_int(&xp, nput, value);
1583                if(lstatus != NC_NOERR && status == NC_NOERR)
1584                {
1585                        /* not fatal to the loop */
1586                        status = lstatus;
1587                }
1588
1589                (void) ncio_rel(ncp->nciop, offset,
1590                                 RGN_MODIFIED); 
1591
1592                remaining -= extent;
1593                if(remaining == 0)
1594                        break; /* normal loop exit */
1595                offset += extent;
1596                value += nput;
1597
1598        }
1599
1600        return status;
1601}
1602
1603static int
1604putNCvx_int_float(NC *ncp, const NC_var *varp,
1605                 const size_t *start, size_t nelems, const float *value)
1606{
1607        off_t offset = NC_varoffset(ncp, varp, start);
1608        size_t remaining = varp->xsz * nelems;
1609        int status = NC_NOERR;
1610        void *xp;
1611
1612        if(nelems == 0)
1613                return NC_NOERR;
1614
1615        assert(value != NULL);
1616
1617        for(;;)
1618        {
1619                size_t extent = MIN(remaining, ncp->chunk);
1620                size_t nput = ncx_howmany(varp->type, extent);
1621
1622                int lstatus = ncio_get(ncp->nciop, offset, extent,
1623                                 RGN_WRITE, &xp);       
1624                if(lstatus != NC_NOERR)
1625                        return lstatus;
1626               
1627                lstatus = ncx_putn_int_float(&xp, nput, value);
1628                if(lstatus != NC_NOERR && status == NC_NOERR)
1629                {
1630                        /* not fatal to the loop */
1631                        status = lstatus;
1632                }
1633
1634                (void) ncio_rel(ncp->nciop, offset,
1635                                 RGN_MODIFIED); 
1636
1637                remaining -= extent;
1638                if(remaining == 0)
1639                        break; /* normal loop exit */
1640                offset += extent;
1641                value += nput;
1642
1643        }
1644
1645        return status;
1646}
1647
1648static int
1649putNCvx_int_double(NC *ncp, const NC_var *varp,
1650                 const size_t *start, size_t nelems, const double *value)
1651{
1652        off_t offset = NC_varoffset(ncp, varp, start);
1653        size_t remaining = varp->xsz * nelems;
1654        int status = NC_NOERR;
1655        void *xp;
1656
1657        if(nelems == 0)
1658                return NC_NOERR;
1659
1660        assert(value != NULL);
1661
1662        for(;;)
1663        {
1664                size_t extent = MIN(remaining, ncp->chunk);
1665                size_t nput = ncx_howmany(varp->type, extent);
1666
1667                int lstatus = ncio_get(ncp->nciop, offset, extent,
1668                                 RGN_WRITE, &xp);       
1669                if(lstatus != NC_NOERR)
1670                        return lstatus;
1671               
1672                lstatus = ncx_putn_int_double(&xp, nput, value);
1673                if(lstatus != NC_NOERR && status == NC_NOERR)
1674                {
1675                        /* not fatal to the loop */
1676                        status = lstatus;
1677                }
1678
1679                (void) ncio_rel(ncp->nciop, offset,
1680                                 RGN_MODIFIED); 
1681
1682                remaining -= extent;
1683                if(remaining == 0)
1684                        break; /* normal loop exit */
1685                offset += extent;
1686                value += nput;
1687
1688        }
1689
1690        return status;
1691}
1692
1693static int
1694putNCvx_int_longlong(NC *ncp, const NC_var *varp,
1695                 const size_t *start, size_t nelems, const longlong *value)
1696{
1697        off_t offset = NC_varoffset(ncp, varp, start);
1698        size_t remaining = varp->xsz * nelems;
1699        int status = NC_NOERR;
1700        void *xp;
1701
1702        if(nelems == 0)
1703                return NC_NOERR;
1704
1705        assert(value != NULL);
1706
1707        for(;;)
1708        {
1709                size_t extent = MIN(remaining, ncp->chunk);
1710                size_t nput = ncx_howmany(varp->type, extent);
1711
1712                int lstatus = ncio_get(ncp->nciop, offset, extent,
1713                                 RGN_WRITE, &xp);       
1714                if(lstatus != NC_NOERR)
1715                        return lstatus;
1716               
1717                lstatus = ncx_putn_int_longlong(&xp, nput, value);
1718                if(lstatus != NC_NOERR && status == NC_NOERR)
1719                {
1720                        /* not fatal to the loop */
1721                        status = lstatus;
1722                }
1723
1724                (void) ncio_rel(ncp->nciop, offset,
1725                                 RGN_MODIFIED); 
1726
1727                remaining -= extent;
1728                if(remaining == 0)
1729                        break; /* normal loop exit */
1730                offset += extent;
1731                value += nput;
1732
1733        }
1734
1735        return status;
1736}
1737
1738
1739static int
1740putNCvx_float_schar(NC *ncp, const NC_var *varp,
1741                 const size_t *start, size_t nelems, const schar *value)
1742{
1743        off_t offset = NC_varoffset(ncp, varp, start);
1744        size_t remaining = varp->xsz * nelems;
1745        int status = NC_NOERR;
1746        void *xp;
1747
1748        if(nelems == 0)
1749                return NC_NOERR;
1750
1751        assert(value != NULL);
1752
1753        for(;;)
1754        {
1755                size_t extent = MIN(remaining, ncp->chunk);
1756                size_t nput = ncx_howmany(varp->type, extent);
1757
1758                int lstatus = ncio_get(ncp->nciop, offset, extent,
1759                                 RGN_WRITE, &xp);       
1760                if(lstatus != NC_NOERR)
1761                        return lstatus;
1762               
1763                lstatus = ncx_putn_float_schar(&xp, nput, value);
1764                if(lstatus != NC_NOERR && status == NC_NOERR)
1765                {
1766                        /* not fatal to the loop */
1767                        status = lstatus;
1768                }
1769
1770                (void) ncio_rel(ncp->nciop, offset,
1771                                 RGN_MODIFIED); 
1772
1773                remaining -= extent;
1774                if(remaining == 0)
1775                        break; /* normal loop exit */
1776                offset += extent;
1777                value += nput;
1778
1779        }
1780
1781        return status;
1782}
1783
1784static int
1785putNCvx_float_uchar(NC *ncp, const NC_var *varp,
1786                 const size_t *start, size_t nelems, const uchar *value)
1787{
1788        off_t offset = NC_varoffset(ncp, varp, start);
1789        size_t remaining = varp->xsz * nelems;
1790        int status = NC_NOERR;
1791        void *xp;
1792
1793        if(nelems == 0)
1794                return NC_NOERR;
1795
1796        assert(value != NULL);
1797
1798        for(;;)
1799        {
1800                size_t extent = MIN(remaining, ncp->chunk);
1801                size_t nput = ncx_howmany(varp->type, extent);
1802
1803                int lstatus = ncio_get(ncp->nciop, offset, extent,
1804                                 RGN_WRITE, &xp);       
1805                if(lstatus != NC_NOERR)
1806                        return lstatus;
1807               
1808                lstatus = ncx_putn_float_uchar(&xp, nput, value);
1809                if(lstatus != NC_NOERR && status == NC_NOERR)
1810                {
1811                        /* not fatal to the loop */
1812                        status = lstatus;
1813                }
1814
1815                (void) ncio_rel(ncp->nciop, offset,
1816                                 RGN_MODIFIED); 
1817
1818                remaining -= extent;
1819                if(remaining == 0)
1820                        break; /* normal loop exit */
1821                offset += extent;
1822                value += nput;
1823
1824        }
1825
1826        return status;
1827}
1828
1829static int
1830putNCvx_float_short(NC *ncp, const NC_var *varp,
1831                 const size_t *start, size_t nelems, const short *value)
1832{
1833        off_t offset = NC_varoffset(ncp, varp, start);
1834        size_t remaining = varp->xsz * nelems;
1835        int status = NC_NOERR;
1836        void *xp;
1837
1838        if(nelems == 0)
1839                return NC_NOERR;
1840
1841        assert(value != NULL);
1842
1843        for(;;)
1844        {
1845                size_t extent = MIN(remaining, ncp->chunk);
1846                size_t nput = ncx_howmany(varp->type, extent);
1847
1848                int lstatus = ncio_get(ncp->nciop, offset, extent,
1849                                 RGN_WRITE, &xp);       
1850                if(lstatus != NC_NOERR)
1851                        return lstatus;
1852               
1853                lstatus = ncx_putn_float_short(&xp, nput, value);
1854                if(lstatus != NC_NOERR && status == NC_NOERR)
1855                {
1856                        /* not fatal to the loop */
1857                        status = lstatus;
1858                }
1859
1860                (void) ncio_rel(ncp->nciop, offset,
1861                                 RGN_MODIFIED); 
1862
1863                remaining -= extent;
1864                if(remaining == 0)
1865                        break; /* normal loop exit */
1866                offset += extent;
1867                value += nput;
1868
1869        }
1870
1871        return status;
1872}
1873
1874static int
1875putNCvx_float_int(NC *ncp, const NC_var *varp,
1876                 const size_t *start, size_t nelems, const int *value)
1877{
1878        off_t offset = NC_varoffset(ncp, varp, start);
1879        size_t remaining = varp->xsz * nelems;
1880        int status = NC_NOERR;
1881        void *xp;
1882
1883        if(nelems == 0)
1884                return NC_NOERR;
1885
1886        assert(value != NULL);
1887
1888        for(;;)
1889        {
1890                size_t extent = MIN(remaining, ncp->chunk);
1891                size_t nput = ncx_howmany(varp->type, extent);
1892
1893                int lstatus = ncio_get(ncp->nciop, offset, extent,
1894                                 RGN_WRITE, &xp);       
1895                if(lstatus != NC_NOERR)
1896                        return lstatus;
1897               
1898                lstatus = ncx_putn_float_int(&xp, nput, value);
1899                if(lstatus != NC_NOERR && status == NC_NOERR)
1900                {
1901                        /* not fatal to the loop */
1902                        status = lstatus;
1903                }
1904
1905                (void) ncio_rel(ncp->nciop, offset,
1906                                 RGN_MODIFIED); 
1907
1908                remaining -= extent;
1909                if(remaining == 0)
1910                        break; /* normal loop exit */
1911                offset += extent;
1912                value += nput;
1913
1914        }
1915
1916        return status;
1917}
1918
1919static int
1920putNCvx_float_float(NC *ncp, const NC_var *varp,
1921                 const size_t *start, size_t nelems, const float *value)
1922{
1923        off_t offset = NC_varoffset(ncp, varp, start);
1924        size_t remaining = varp->xsz * nelems;
1925        int status = NC_NOERR;
1926        void *xp;
1927
1928        if(nelems == 0)
1929                return NC_NOERR;
1930
1931        assert(value != NULL);
1932
1933        for(;;)
1934        {
1935                size_t extent = MIN(remaining, ncp->chunk);
1936                size_t nput = ncx_howmany(varp->type, extent);
1937
1938                int lstatus = ncio_get(ncp->nciop, offset, extent,
1939                                 RGN_WRITE, &xp);       
1940                if(lstatus != NC_NOERR)
1941                        return lstatus;
1942               
1943                lstatus = ncx_putn_float_float(&xp, nput, value);
1944                if(lstatus != NC_NOERR && status == NC_NOERR)
1945                {
1946                        /* not fatal to the loop */
1947                        status = lstatus;
1948                }
1949
1950                (void) ncio_rel(ncp->nciop, offset,
1951                                 RGN_MODIFIED); 
1952
1953                remaining -= extent;
1954                if(remaining == 0)
1955                        break; /* normal loop exit */
1956                offset += extent;
1957                value += nput;
1958
1959        }
1960
1961        return status;
1962}
1963
1964static int
1965putNCvx_float_double(NC *ncp, const NC_var *varp,
1966                 const size_t *start, size_t nelems, const double *value)
1967{
1968        off_t offset = NC_varoffset(ncp, varp, start);
1969        size_t remaining = varp->xsz * nelems;
1970        int status = NC_NOERR;
1971        void *xp;
1972
1973        if(nelems == 0)
1974                return NC_NOERR;
1975
1976        assert(value != NULL);
1977
1978        for(;;)
1979        {
1980                size_t extent = MIN(remaining, ncp->chunk);
1981                size_t nput = ncx_howmany(varp->type, extent);
1982
1983                int lstatus = ncio_get(ncp->nciop, offset, extent,
1984                                 RGN_WRITE, &xp);       
1985                if(lstatus != NC_NOERR)
1986                        return lstatus;
1987               
1988                lstatus = ncx_putn_float_double(&xp, nput, value);
1989                if(lstatus != NC_NOERR && status == NC_NOERR)
1990                {
1991                        /* not fatal to the loop */
1992                        status = lstatus;
1993                }
1994
1995                (void) ncio_rel(ncp->nciop, offset,
1996                                 RGN_MODIFIED); 
1997
1998                remaining -= extent;
1999                if(remaining == 0)
2000                        break; /* normal loop exit */
2001                offset += extent;
2002                value += nput;
2003
2004        }
2005
2006        return status;
2007}
2008
2009static int
2010putNCvx_float_longlong(NC *ncp, const NC_var *varp,
2011                 const size_t *start, size_t nelems, const longlong *value)
2012{
2013        off_t offset = NC_varoffset(ncp, varp, start);
2014        size_t remaining = varp->xsz * nelems;
2015        int status = NC_NOERR;
2016        void *xp;
2017
2018        if(nelems == 0)
2019                return NC_NOERR;
2020
2021        assert(value != NULL);
2022
2023        for(;;)
2024        {
2025                size_t extent = MIN(remaining, ncp->chunk);
2026                size_t nput = ncx_howmany(varp->type, extent);
2027
2028                int lstatus = ncio_get(ncp->nciop, offset, extent,
2029                                 RGN_WRITE, &xp);       
2030                if(lstatus != NC_NOERR)
2031                        return lstatus;
2032               
2033                lstatus = ncx_putn_float_longlong(&xp, nput, value);
2034                if(lstatus != NC_NOERR && status == NC_NOERR)
2035                {
2036                        /* not fatal to the loop */
2037                        status = lstatus;
2038                }
2039
2040                (void) ncio_rel(ncp->nciop, offset,
2041                                 RGN_MODIFIED); 
2042
2043                remaining -= extent;
2044                if(remaining == 0)
2045                        break; /* normal loop exit */
2046                offset += extent;
2047                value += nput;
2048
2049        }
2050
2051        return status;
2052}
2053
2054
2055static int
2056putNCvx_double_schar(NC *ncp, const NC_var *varp,
2057                 const size_t *start, size_t nelems, const schar *value)
2058{
2059        off_t offset = NC_varoffset(ncp, varp, start);
2060        size_t remaining = varp->xsz * nelems;
2061        int status = NC_NOERR;
2062        void *xp;
2063
2064        if(nelems == 0)
2065                return NC_NOERR;
2066
2067        assert(value != NULL);
2068
2069        for(;;)
2070        {
2071                size_t extent = MIN(remaining, ncp->chunk);
2072                size_t nput = ncx_howmany(varp->type, extent);
2073
2074                int lstatus = ncio_get(ncp->nciop, offset, extent,
2075                                 RGN_WRITE, &xp);       
2076                if(lstatus != NC_NOERR)
2077                        return lstatus;
2078               
2079                lstatus = ncx_putn_double_schar(&xp, nput, value);
2080                if(lstatus != NC_NOERR && status == NC_NOERR)
2081                {
2082                        /* not fatal to the loop */
2083                        status = lstatus;
2084                }
2085
2086                (void) ncio_rel(ncp->nciop, offset,
2087                                 RGN_MODIFIED); 
2088
2089                remaining -= extent;
2090                if(remaining == 0)
2091                        break; /* normal loop exit */
2092                offset += extent;
2093                value += nput;
2094
2095        }
2096
2097        return status;
2098}
2099
2100static int
2101putNCvx_double_uchar(NC *ncp, const NC_var *varp,
2102                 const size_t *start, size_t nelems, const uchar *value)
2103{
2104        off_t offset = NC_varoffset(ncp, varp, start);
2105        size_t remaining = varp->xsz * nelems;
2106        int status = NC_NOERR;
2107        void *xp;
2108
2109        if(nelems == 0)
2110                return NC_NOERR;
2111
2112        assert(value != NULL);
2113
2114        for(;;)
2115        {
2116                size_t extent = MIN(remaining, ncp->chunk);
2117                size_t nput = ncx_howmany(varp->type, extent);
2118
2119                int lstatus = ncio_get(ncp->nciop, offset, extent,
2120                                 RGN_WRITE, &xp);       
2121                if(lstatus != NC_NOERR)
2122                        return lstatus;
2123               
2124                lstatus = ncx_putn_double_uchar(&xp, nput, value);
2125                if(lstatus != NC_NOERR && status == NC_NOERR)
2126                {
2127                        /* not fatal to the loop */
2128                        status = lstatus;
2129                }
2130
2131                (void) ncio_rel(ncp->nciop, offset,
2132                                 RGN_MODIFIED); 
2133
2134                remaining -= extent;
2135                if(remaining == 0)
2136                        break; /* normal loop exit */
2137                offset += extent;
2138                value += nput;
2139
2140        }
2141
2142        return status;
2143}
2144
2145static int
2146putNCvx_double_short(NC *ncp, const NC_var *varp,
2147                 const size_t *start, size_t nelems, const short *value)
2148{
2149        off_t offset = NC_varoffset(ncp, varp, start);
2150        size_t remaining = varp->xsz * nelems;
2151        int status = NC_NOERR;
2152        void *xp;
2153
2154        if(nelems == 0)
2155                return NC_NOERR;
2156
2157        assert(value != NULL);
2158
2159        for(;;)
2160        {
2161                size_t extent = MIN(remaining, ncp->chunk);
2162                size_t nput = ncx_howmany(varp->type, extent);
2163
2164                int lstatus = ncio_get(ncp->nciop, offset, extent,
2165                                 RGN_WRITE, &xp);       
2166                if(lstatus != NC_NOERR)
2167                        return lstatus;
2168               
2169                lstatus = ncx_putn_double_short(&xp, nput, value);
2170                if(lstatus != NC_NOERR && status == NC_NOERR)
2171                {
2172                        /* not fatal to the loop */
2173                        status = lstatus;
2174                }
2175
2176                (void) ncio_rel(ncp->nciop, offset,
2177                                 RGN_MODIFIED); 
2178
2179                remaining -= extent;
2180                if(remaining == 0)
2181                        break; /* normal loop exit */
2182                offset += extent;
2183                value += nput;
2184
2185        }
2186
2187        return status;
2188}
2189
2190static int
2191putNCvx_double_int(NC *ncp, const NC_var *varp,
2192                 const size_t *start, size_t nelems, const int *value)
2193{
2194        off_t offset = NC_varoffset(ncp, varp, start);
2195        size_t remaining = varp->xsz * nelems;
2196        int status = NC_NOERR;
2197        void *xp;
2198
2199        if(nelems == 0)
2200                return NC_NOERR;
2201
2202        assert(value != NULL);
2203
2204        for(;;)
2205        {
2206                size_t extent = MIN(remaining, ncp->chunk);
2207                size_t nput = ncx_howmany(varp->type, extent);
2208
2209                int lstatus = ncio_get(ncp->nciop, offset, extent,
2210                                 RGN_WRITE, &xp);       
2211                if(lstatus != NC_NOERR)
2212                        return lstatus;
2213               
2214                lstatus = ncx_putn_double_int(&xp, nput, value);
2215                if(lstatus != NC_NOERR && status == NC_NOERR)
2216                {
2217                        /* not fatal to the loop */
2218                        status = lstatus;
2219                }
2220
2221                (void) ncio_rel(ncp->nciop, offset,
2222                                 RGN_MODIFIED); 
2223
2224                remaining -= extent;
2225                if(remaining == 0)
2226                        break; /* normal loop exit */
2227                offset += extent;
2228                value += nput;
2229
2230        }
2231
2232        return status;
2233}
2234
2235static int
2236putNCvx_double_float(NC *ncp, const NC_var *varp,
2237                 const size_t *start, size_t nelems, const float *value)
2238{
2239        off_t offset = NC_varoffset(ncp, varp, start);
2240        size_t remaining = varp->xsz * nelems;
2241        int status = NC_NOERR;
2242        void *xp;
2243
2244        if(nelems == 0)
2245                return NC_NOERR;
2246
2247        assert(value != NULL);
2248
2249        for(;;)
2250        {
2251                size_t extent = MIN(remaining, ncp->chunk);
2252                size_t nput = ncx_howmany(varp->type, extent);
2253
2254                int lstatus = ncio_get(ncp->nciop, offset, extent,
2255                                 RGN_WRITE, &xp);       
2256                if(lstatus != NC_NOERR)
2257                        return lstatus;
2258               
2259                lstatus = ncx_putn_double_float(&xp, nput, value);
2260                if(lstatus != NC_NOERR && status == NC_NOERR)
2261                {
2262                        /* not fatal to the loop */
2263                        status = lstatus;
2264                }
2265
2266                (void) ncio_rel(ncp->nciop, offset,
2267                                 RGN_MODIFIED); 
2268
2269                remaining -= extent;
2270                if(remaining == 0)
2271                        break; /* normal loop exit */
2272                offset += extent;
2273                value += nput;
2274
2275        }
2276
2277        return status;
2278}
2279
2280static int
2281putNCvx_double_double(NC *ncp, const NC_var *varp,
2282                 const size_t *start, size_t nelems, const double *value)
2283{
2284        off_t offset = NC_varoffset(ncp, varp, start);
2285        size_t remaining = varp->xsz * nelems;
2286        int status = NC_NOERR;
2287        void *xp;
2288
2289        if(nelems == 0)
2290                return NC_NOERR;
2291
2292        assert(value != NULL);
2293
2294        for(;;)
2295        {
2296                size_t extent = MIN(remaining, ncp->chunk);
2297                size_t nput = ncx_howmany(varp->type, extent);
2298
2299                int lstatus = ncio_get(ncp->nciop, offset, extent,
2300                                 RGN_WRITE, &xp);       
2301                if(lstatus != NC_NOERR)
2302                        return lstatus;
2303               
2304                lstatus = ncx_putn_double_double(&xp, nput, value);
2305                if(lstatus != NC_NOERR && status == NC_NOERR)
2306                {
2307                        /* not fatal to the loop */
2308                        status = lstatus;
2309                }
2310
2311                (void) ncio_rel(ncp->nciop, offset,
2312                                 RGN_MODIFIED); 
2313
2314                remaining -= extent;
2315                if(remaining == 0)
2316                        break; /* normal loop exit */
2317                offset += extent;
2318                value += nput;
2319
2320        }
2321
2322        return status;
2323}
2324
2325static int
2326putNCvx_double_longlong(NC *ncp, const NC_var *varp,
2327                 const size_t *start, size_t nelems, const longlong *value)
2328{
2329        off_t offset = NC_varoffset(ncp, varp, start);
2330        size_t remaining = varp->xsz * nelems;
2331        int status = NC_NOERR;
2332        void *xp;
2333
2334        if(nelems == 0)
2335                return NC_NOERR;
2336
2337        assert(value != NULL);
2338
2339        for(;;)
2340        {
2341                size_t extent = MIN(remaining, ncp->chunk);
2342                size_t nput = ncx_howmany(varp->type, extent);
2343
2344                int lstatus = ncio_get(ncp->nciop, offset, extent,
2345                                 RGN_WRITE, &xp);       
2346                if(lstatus != NC_NOERR)
2347                        return lstatus;
2348               
2349                lstatus = ncx_putn_double_longlong(&xp, nput, value);
2350                if(lstatus != NC_NOERR && status == NC_NOERR)
2351                {
2352                        /* not fatal to the loop */
2353                        status = lstatus;
2354                }
2355
2356                (void) ncio_rel(ncp->nciop, offset,
2357                                 RGN_MODIFIED); 
2358
2359                remaining -= extent;
2360                if(remaining == 0)
2361                        break; /* normal loop exit */
2362                offset += extent;
2363                value += nput;
2364
2365        }
2366
2367        return status;
2368}
2369
2370
2371#ifdef NOTUSED
2372static int
2373putNCvx_schar_uint(NC *ncp, const NC_var *varp,
2374                 const size_t *start, size_t nelems, const uint *value)
2375{
2376        off_t offset = NC_varoffset(ncp, varp, start);
2377        size_t remaining = varp->xsz * nelems;
2378        int status = NC_NOERR;
2379        void *xp;
2380
2381        if(nelems == 0)
2382                return NC_NOERR;
2383
2384        assert(value != NULL);
2385
2386        for(;;)
2387        {
2388                size_t extent = MIN(remaining, ncp->chunk);
2389                size_t nput = ncx_howmany(varp->type, extent);
2390
2391                int lstatus = ncio_get(ncp->nciop, offset, extent,
2392                                 RGN_WRITE, &xp);       
2393                if(lstatus != NC_NOERR)
2394                        return lstatus;
2395               
2396                lstatus = ncx_putn_schar_uint(&xp, nput, value);
2397                if(lstatus != NC_NOERR && status == NC_NOERR)
2398                {
2399                        /* not fatal to the loop */
2400                        status = lstatus;
2401                }
2402
2403                (void) ncio_rel(ncp->nciop, offset,
2404                                 RGN_MODIFIED); 
2405
2406                remaining -= extent;
2407                if(remaining == 0)
2408                        break; /* normal loop exit */
2409                offset += extent;
2410                value += nput;
2411
2412        }
2413
2414        return status;
2415}
2416
2417static int
2418putNCvx_schar_ulonglong(NC *ncp, const NC_var *varp,
2419                 const size_t *start, size_t nelems, const ulonglong *value)
2420{
2421        off_t offset = NC_varoffset(ncp, varp, start);
2422        size_t remaining = varp->xsz * nelems;
2423        int status = NC_NOERR;
2424        void *xp;
2425
2426        if(nelems == 0)
2427                return NC_NOERR;
2428
2429        assert(value != NULL);
2430
2431        for(;;)
2432        {
2433                size_t extent = MIN(remaining, ncp->chunk);
2434                size_t nput = ncx_howmany(varp->type, extent);
2435
2436                int lstatus = ncio_get(ncp->nciop, offset, extent,
2437                                 RGN_WRITE, &xp);       
2438                if(lstatus != NC_NOERR)
2439                        return lstatus;
2440               
2441                lstatus = ncx_putn_schar_ulonglong(&xp, nput, value);
2442                if(lstatus != NC_NOERR && status == NC_NOERR)
2443                {
2444                        /* not fatal to the loop */
2445                        status = lstatus;
2446                }
2447
2448                (void) ncio_rel(ncp->nciop, offset,
2449                                 RGN_MODIFIED); 
2450
2451                remaining -= extent;
2452                if(remaining == 0)
2453                        break; /* normal loop exit */
2454                offset += extent;
2455                value += nput;
2456
2457        }
2458
2459        return status;
2460}
2461
2462static int
2463putNCvx_short_uint(NC *ncp, const NC_var *varp,
2464                 const size_t *start, size_t nelems, const uint *value)
2465{
2466        off_t offset = NC_varoffset(ncp, varp, start);
2467        size_t remaining = varp->xsz * nelems;
2468        int status = NC_NOERR;
2469        void *xp;
2470
2471        if(nelems == 0)
2472                return NC_NOERR;
2473
2474        assert(value != NULL);
2475
2476        for(;;)
2477        {
2478                size_t extent = MIN(remaining, ncp->chunk);
2479                size_t nput = ncx_howmany(varp->type, extent);
2480
2481                int lstatus = ncio_get(ncp->nciop, offset, extent,
2482                                 RGN_WRITE, &xp);       
2483                if(lstatus != NC_NOERR)
2484                        return lstatus;
2485               
2486                lstatus = ncx_putn_short_uint(&xp, nput, value);
2487                if(lstatus != NC_NOERR && status == NC_NOERR)
2488                {
2489                        /* not fatal to the loop */
2490                        status = lstatus;
2491                }
2492
2493                (void) ncio_rel(ncp->nciop, offset,
2494                                 RGN_MODIFIED); 
2495
2496                remaining -= extent;
2497                if(remaining == 0)
2498                        break; /* normal loop exit */
2499                offset += extent;
2500                value += nput;
2501
2502        }
2503
2504        return status;
2505}
2506
2507static int
2508putNCvx_short_ulonglong(NC *ncp, const NC_var *varp,
2509                 const size_t *start, size_t nelems, const ulonglong *value)
2510{
2511        off_t offset = NC_varoffset(ncp, varp, start);
2512        size_t remaining = varp->xsz * nelems;
2513        int status = NC_NOERR;
2514        void *xp;
2515
2516        if(nelems == 0)
2517                return NC_NOERR;
2518
2519        assert(value != NULL);
2520
2521        for(;;)
2522        {
2523                size_t extent = MIN(remaining, ncp->chunk);
2524                size_t nput = ncx_howmany(varp->type, extent);
2525
2526                int lstatus = ncio_get(ncp->nciop, offset, extent,
2527                                 RGN_WRITE, &xp);       
2528                if(lstatus != NC_NOERR)
2529                        return lstatus;
2530               
2531                lstatus = ncx_putn_short_ulonglong(&xp, nput, value);
2532                if(lstatus != NC_NOERR && status == NC_NOERR)
2533                {
2534                        /* not fatal to the loop */
2535                        status = lstatus;
2536                }
2537
2538                (void) ncio_rel(ncp->nciop, offset,
2539                                 RGN_MODIFIED); 
2540
2541                remaining -= extent;
2542                if(remaining == 0)
2543                        break; /* normal loop exit */
2544                offset += extent;
2545                value += nput;
2546
2547        }
2548
2549        return status;
2550}
2551
2552static int
2553putNCvx_int_uint(NC *ncp, const NC_var *varp,
2554                 const size_t *start, size_t nelems, const uint *value)
2555{
2556        off_t offset = NC_varoffset(ncp, varp, start);
2557        size_t remaining = varp->xsz * nelems;
2558        int status = NC_NOERR;
2559        void *xp;
2560
2561        if(nelems == 0)
2562                return NC_NOERR;
2563
2564        assert(value != NULL);
2565
2566        for(;;)
2567        {
2568                size_t extent = MIN(remaining, ncp->chunk);
2569                size_t nput = ncx_howmany(varp->type, extent);
2570
2571                int lstatus = ncio_get(ncp->nciop, offset, extent,
2572                                 RGN_WRITE, &xp);       
2573                if(lstatus != NC_NOERR)
2574                        return lstatus;
2575               
2576                lstatus = ncx_putn_int_uint(&xp, nput, value);
2577                if(lstatus != NC_NOERR && status == NC_NOERR)
2578                {
2579                        /* not fatal to the loop */
2580                        status = lstatus;
2581                }
2582
2583                (void) ncio_rel(ncp->nciop, offset,
2584                                 RGN_MODIFIED); 
2585
2586                remaining -= extent;
2587                if(remaining == 0)
2588                        break; /* normal loop exit */
2589                offset += extent;
2590                value += nput;
2591
2592        }
2593
2594        return status;
2595}
2596
2597static int
2598putNCvx_int_ulonglong(NC *ncp, const NC_var *varp,
2599                 const size_t *start, size_t nelems, const ulonglong *value)
2600{
2601        off_t offset = NC_varoffset(ncp, varp, start);
2602        size_t remaining = varp->xsz * nelems;
2603        int status = NC_NOERR;
2604        void *xp;
2605
2606        if(nelems == 0)
2607                return NC_NOERR;
2608
2609        assert(value != NULL);
2610
2611        for(;;)
2612        {
2613                size_t extent = MIN(remaining, ncp->chunk);
2614                size_t nput = ncx_howmany(varp->type, extent);
2615
2616                int lstatus = ncio_get(ncp->nciop, offset, extent,
2617                                 RGN_WRITE, &xp);       
2618                if(lstatus != NC_NOERR)
2619                        return lstatus;
2620               
2621                lstatus = ncx_putn_int_ulonglong(&xp, nput, value);
2622                if(lstatus != NC_NOERR && status == NC_NOERR)
2623                {
2624                        /* not fatal to the loop */
2625                        status = lstatus;
2626                }
2627
2628                (void) ncio_rel(ncp->nciop, offset,
2629                                 RGN_MODIFIED); 
2630
2631                remaining -= extent;
2632                if(remaining == 0)
2633                        break; /* normal loop exit */
2634                offset += extent;
2635                value += nput;
2636
2637        }
2638
2639        return status;
2640}
2641
2642static int
2643putNCvx_float_uint(NC *ncp, const NC_var *varp,
2644                 const size_t *start, size_t nelems, const uint *value)
2645{
2646        off_t offset = NC_varoffset(ncp, varp, start);
2647        size_t remaining = varp->xsz * nelems;
2648        int status = NC_NOERR;
2649        void *xp;
2650
2651        if(nelems == 0)
2652                return NC_NOERR;
2653
2654        assert(value != NULL);
2655
2656        for(;;)
2657        {
2658                size_t extent = MIN(remaining, ncp->chunk);
2659                size_t nput = ncx_howmany(varp->type, extent);
2660
2661                int lstatus = ncio_get(ncp->nciop, offset, extent,
2662                                 RGN_WRITE, &xp);       
2663                if(lstatus != NC_NOERR)
2664                        return lstatus;
2665               
2666                lstatus = ncx_putn_float_uint(&xp, nput, value);
2667                if(lstatus != NC_NOERR && status == NC_NOERR)
2668                {
2669                        /* not fatal to the loop */
2670                        status = lstatus;
2671                }
2672
2673                (void) ncio_rel(ncp->nciop, offset,
2674                                 RGN_MODIFIED); 
2675
2676                remaining -= extent;
2677                if(remaining == 0)
2678                        break; /* normal loop exit */
2679                offset += extent;
2680                value += nput;
2681
2682        }
2683
2684        return status;
2685}
2686
2687static int
2688putNCvx_float_ulonglong(NC *ncp, const NC_var *varp,
2689                 const size_t *start, size_t nelems, const ulonglong *value)
2690{
2691        off_t offset = NC_varoffset(ncp, varp, start);
2692        size_t remaining = varp->xsz * nelems;
2693        int status = NC_NOERR;
2694        void *xp;
2695
2696        if(nelems == 0)
2697                return NC_NOERR;
2698
2699        assert(value != NULL);
2700
2701        for(;;)
2702        {
2703                size_t extent = MIN(remaining, ncp->chunk);
2704                size_t nput = ncx_howmany(varp->type, extent);
2705
2706                int lstatus = ncio_get(ncp->nciop, offset, extent,
2707                                 RGN_WRITE, &xp);       
2708                if(lstatus != NC_NOERR)
2709                        return lstatus;
2710               
2711                lstatus = ncx_putn_float_ulonglong(&xp, nput, value);
2712                if(lstatus != NC_NOERR && status == NC_NOERR)
2713                {
2714                        /* not fatal to the loop */
2715                        status = lstatus;
2716                }
2717
2718                (void) ncio_rel(ncp->nciop, offset,
2719                                 RGN_MODIFIED); 
2720
2721                remaining -= extent;
2722                if(remaining == 0)
2723                        break; /* normal loop exit */
2724                offset += extent;
2725                value += nput;
2726
2727        }
2728
2729        return status;
2730}
2731
2732static int
2733putNCvx_double_uint(NC *ncp, const NC_var *varp,
2734                 const size_t *start, size_t nelems, const uint *value)
2735{
2736        off_t offset = NC_varoffset(ncp, varp, start);
2737        size_t remaining = varp->xsz * nelems;
2738        int status = NC_NOERR;
2739        void *xp;
2740
2741        if(nelems == 0)
2742                return NC_NOERR;
2743
2744        assert(value != NULL);
2745
2746        for(;;)
2747        {
2748                size_t extent = MIN(remaining, ncp->chunk);
2749                size_t nput = ncx_howmany(varp->type, extent);
2750
2751                int lstatus = ncio_get(ncp->nciop, offset, extent,
2752                                 RGN_WRITE, &xp);       
2753                if(lstatus != NC_NOERR)
2754                        return lstatus;
2755               
2756                lstatus = ncx_putn_double_uint(&xp, nput, value);
2757                if(lstatus != NC_NOERR && status == NC_NOERR)
2758                {
2759                        /* not fatal to the loop */
2760                        status = lstatus;
2761                }
2762
2763                (void) ncio_rel(ncp->nciop, offset,
2764                                 RGN_MODIFIED); 
2765
2766                remaining -= extent;
2767                if(remaining == 0)
2768                        break; /* normal loop exit */
2769                offset += extent;
2770                value += nput;
2771
2772        }
2773
2774        return status;
2775}
2776
2777static int
2778putNCvx_double_ulonglong(NC *ncp, const NC_var *varp,
2779                 const size_t *start, size_t nelems, const ulonglong *value)
2780{
2781        off_t offset = NC_varoffset(ncp, varp, start);
2782        size_t remaining = varp->xsz * nelems;
2783        int status = NC_NOERR;
2784        void *xp;
2785
2786        if(nelems == 0)
2787                return NC_NOERR;
2788
2789        assert(value != NULL);
2790
2791        for(;;)
2792        {
2793                size_t extent = MIN(remaining, ncp->chunk);
2794                size_t nput = ncx_howmany(varp->type, extent);
2795
2796                int lstatus = ncio_get(ncp->nciop, offset, extent,
2797                                 RGN_WRITE, &xp);       
2798                if(lstatus != NC_NOERR)
2799                        return lstatus;
2800               
2801                lstatus = ncx_putn_double_ulonglong(&xp, nput, value);
2802                if(lstatus != NC_NOERR && status == NC_NOERR)
2803                {
2804                        /* not fatal to the loop */
2805                        status = lstatus;
2806                }
2807
2808                (void) ncio_rel(ncp->nciop, offset,
2809                                 RGN_MODIFIED); 
2810
2811                remaining -= extent;
2812                if(remaining == 0)
2813                        break; /* normal loop exit */
2814                offset += extent;
2815                value += nput;
2816
2817        }
2818
2819        return status;
2820}
2821
2822#endif /*NOTUSED*/
2823
2824
2825static int
2826getNCvx_char_char(const NC *ncp, const NC_var *varp,
2827                 const size_t *start, size_t nelems, char *value)
2828{
2829        off_t offset = NC_varoffset(ncp, varp, start);
2830        size_t remaining = varp->xsz * nelems;
2831        int status = NC_NOERR;
2832        const void *xp;
2833
2834        if(nelems == 0)
2835                return NC_NOERR;
2836
2837        assert(value != NULL);
2838
2839        for(;;)
2840        {
2841                size_t extent = MIN(remaining, ncp->chunk);
2842                size_t nget = ncx_howmany(varp->type, extent);
2843
2844                int lstatus = ncio_get(ncp->nciop, offset, extent,
2845                                 0, (void **)&xp);      /* cast away const */
2846                if(lstatus != NC_NOERR)
2847                        return lstatus;
2848               
2849                lstatus = ncx_getn_char_char(&xp, nget, value);
2850                if(lstatus != NC_NOERR && status == NC_NOERR)
2851                        status = lstatus;
2852
2853                (void) ncio_rel(ncp->nciop, offset, 0); 
2854
2855                remaining -= extent;
2856                if(remaining == 0)
2857                        break; /* normal loop exit */
2858                offset += extent;
2859                value += nget;
2860        }
2861
2862        return status;
2863}
2864
2865
2866static int
2867getNCvx_schar_schar(const NC *ncp, const NC_var *varp,
2868                 const size_t *start, size_t nelems, schar *value)
2869{
2870        off_t offset = NC_varoffset(ncp, varp, start);
2871        size_t remaining = varp->xsz * nelems;
2872        int status = NC_NOERR;
2873        const void *xp;
2874
2875        if(nelems == 0)
2876                return NC_NOERR;
2877
2878        assert(value != NULL);
2879
2880        for(;;)
2881        {
2882                size_t extent = MIN(remaining, ncp->chunk);
2883                size_t nget = ncx_howmany(varp->type, extent);
2884
2885                int lstatus = ncio_get(ncp->nciop, offset, extent,
2886                                 0, (void **)&xp);      /* cast away const */
2887                if(lstatus != NC_NOERR)
2888                        return lstatus;
2889               
2890                lstatus = ncx_getn_schar_schar(&xp, nget, value);
2891                if(lstatus != NC_NOERR && status == NC_NOERR)
2892                        status = lstatus;
2893
2894                (void) ncio_rel(ncp->nciop, offset, 0); 
2895
2896                remaining -= extent;
2897                if(remaining == 0)
2898                        break; /* normal loop exit */
2899                offset += extent;
2900                value += nget;
2901        }
2902
2903        return status;
2904}
2905
2906static int
2907getNCvx_schar_short(const NC *ncp, const NC_var *varp,
2908                 const size_t *start, size_t nelems, short *value)
2909{
2910        off_t offset = NC_varoffset(ncp, varp, start);
2911        size_t remaining = varp->xsz * nelems;
2912        int status = NC_NOERR;
2913        const void *xp;
2914
2915        if(nelems == 0)
2916                return NC_NOERR;
2917
2918        assert(value != NULL);
2919
2920        for(;;)
2921        {
2922                size_t extent = MIN(remaining, ncp->chunk);
2923                size_t nget = ncx_howmany(varp->type, extent);
2924
2925                int lstatus = ncio_get(ncp->nciop, offset, extent,
2926                                 0, (void **)&xp);      /* cast away const */
2927                if(lstatus != NC_NOERR)
2928                        return lstatus;
2929               
2930                lstatus = ncx_getn_schar_short(&xp, nget, value);
2931                if(lstatus != NC_NOERR && status == NC_NOERR)
2932                        status = lstatus;
2933
2934                (void) ncio_rel(ncp->nciop, offset, 0); 
2935
2936                remaining -= extent;
2937                if(remaining == 0)
2938                        break; /* normal loop exit */
2939                offset += extent;
2940                value += nget;
2941        }
2942
2943        return status;
2944}
2945
2946static int
2947getNCvx_schar_int(const NC *ncp, const NC_var *varp,
2948                 const size_t *start, size_t nelems, int *value)
2949{
2950        off_t offset = NC_varoffset(ncp, varp, start);
2951        size_t remaining = varp->xsz * nelems;
2952        int status = NC_NOERR;
2953        const void *xp;
2954
2955        if(nelems == 0)
2956                return NC_NOERR;
2957
2958        assert(value != NULL);
2959
2960        for(;;)
2961        {
2962                size_t extent = MIN(remaining, ncp->chunk);
2963                size_t nget = ncx_howmany(varp->type, extent);
2964
2965                int lstatus = ncio_get(ncp->nciop, offset, extent,
2966                                 0, (void **)&xp);      /* cast away const */
2967                if(lstatus != NC_NOERR)
2968                        return lstatus;
2969               
2970                lstatus = ncx_getn_schar_int(&xp, nget, value);
2971                if(lstatus != NC_NOERR && status == NC_NOERR)
2972                        status = lstatus;
2973
2974                (void) ncio_rel(ncp->nciop, offset, 0); 
2975
2976                remaining -= extent;
2977                if(remaining == 0)
2978                        break; /* normal loop exit */
2979                offset += extent;
2980                value += nget;
2981        }
2982
2983        return status;
2984}
2985
2986static int
2987getNCvx_schar_float(const NC *ncp, const NC_var *varp,
2988                 const size_t *start, size_t nelems, float *value)
2989{
2990        off_t offset = NC_varoffset(ncp, varp, start);
2991        size_t remaining = varp->xsz * nelems;
2992        int status = NC_NOERR;
2993        const void *xp;
2994
2995        if(nelems == 0)
2996                return NC_NOERR;
2997
2998        assert(value != NULL);
2999
3000        for(;;)
3001        {
3002                size_t extent = MIN(remaining, ncp->chunk);
3003                size_t nget = ncx_howmany(varp->type, extent);
3004
3005                int lstatus = ncio_get(ncp->nciop, offset, extent,
3006                                 0, (void **)&xp);      /* cast away const */
3007                if(lstatus != NC_NOERR)
3008                        return lstatus;
3009               
3010                lstatus = ncx_getn_schar_float(&xp, nget, value);
3011                if(lstatus != NC_NOERR && status == NC_NOERR)
3012                        status = lstatus;
3013
3014                (void) ncio_rel(ncp->nciop, offset, 0); 
3015
3016                remaining -= extent;
3017                if(remaining == 0)
3018                        break; /* normal loop exit */
3019                offset += extent;
3020                value += nget;
3021        }
3022
3023        return status;
3024}
3025
3026static int
3027getNCvx_schar_double(const NC *ncp, const NC_var *varp,
3028                 const size_t *start, size_t nelems, double *value)
3029{
3030        off_t offset = NC_varoffset(ncp, varp, start);
3031        size_t remaining = varp->xsz * nelems;
3032        int status = NC_NOERR;
3033        const void *xp;
3034
3035        if(nelems == 0)
3036                return NC_NOERR;
3037
3038        assert(value != NULL);
3039
3040        for(;;)
3041        {
3042                size_t extent = MIN(remaining, ncp->chunk);
3043                size_t nget = ncx_howmany(varp->type, extent);
3044
3045                int lstatus = ncio_get(ncp->nciop, offset, extent,
3046                                 0, (void **)&xp);      /* cast away const */
3047                if(lstatus != NC_NOERR)
3048                        return lstatus;
3049               
3050                lstatus = ncx_getn_schar_double(&xp, nget, value);
3051                if(lstatus != NC_NOERR && status == NC_NOERR)
3052                        status = lstatus;
3053
3054                (void) ncio_rel(ncp->nciop, offset, 0); 
3055
3056                remaining -= extent;
3057                if(remaining == 0)
3058                        break; /* normal loop exit */
3059                offset += extent;
3060                value += nget;
3061        }
3062
3063        return status;
3064}
3065
3066static int
3067getNCvx_schar_longlong(const NC *ncp, const NC_var *varp,
3068                 const size_t *start, size_t nelems, longlong *value)
3069{
3070        off_t offset = NC_varoffset(ncp, varp, start);
3071        size_t remaining = varp->xsz * nelems;
3072        int status = NC_NOERR;
3073        const void *xp;
3074
3075        if(nelems == 0)
3076                return NC_NOERR;
3077
3078        assert(value != NULL);
3079
3080        for(;;)
3081        {
3082                size_t extent = MIN(remaining, ncp->chunk);
3083                size_t nget = ncx_howmany(varp->type, extent);
3084
3085                int lstatus = ncio_get(ncp->nciop, offset, extent,
3086                                 0, (void **)&xp);      /* cast away const */
3087                if(lstatus != NC_NOERR)
3088                        return lstatus;
3089               
3090                lstatus = ncx_getn_schar_longlong(&xp, nget, value);
3091                if(lstatus != NC_NOERR && status == NC_NOERR)
3092                        status = lstatus;
3093
3094                (void) ncio_rel(ncp->nciop, offset, 0); 
3095
3096                remaining -= extent;
3097                if(remaining == 0)
3098                        break; /* normal loop exit */
3099                offset += extent;
3100                value += nget;
3101        }
3102
3103        return status;
3104}
3105
3106static int
3107getNCvx_schar_uint(const NC *ncp, const NC_var *varp,
3108                 const size_t *start, size_t nelems, uint *value)
3109{
3110        off_t offset = NC_varoffset(ncp, varp, start);
3111        size_t remaining = varp->xsz * nelems;
3112        int status = NC_NOERR;
3113        const void *xp;
3114
3115        if(nelems == 0)
3116                return NC_NOERR;
3117
3118        assert(value != NULL);
3119
3120        for(;;)
3121        {
3122                size_t extent = MIN(remaining, ncp->chunk);
3123                size_t nget = ncx_howmany(varp->type, extent);
3124
3125                int lstatus = ncio_get(ncp->nciop, offset, extent,
3126                                 0, (void **)&xp);      /* cast away const */
3127                if(lstatus != NC_NOERR)
3128                        return lstatus;
3129               
3130                lstatus = ncx_getn_schar_uint(&xp, nget, value);
3131                if(lstatus != NC_NOERR && status == NC_NOERR)
3132                        status = lstatus;
3133
3134                (void) ncio_rel(ncp->nciop, offset, 0); 
3135
3136                remaining -= extent;
3137                if(remaining == 0)
3138                        break; /* normal loop exit */
3139                offset += extent;
3140                value += nget;
3141        }
3142
3143        return status;
3144}
3145
3146static int
3147getNCvx_schar_ulonglong(const NC *ncp, const NC_var *varp,
3148                 const size_t *start, size_t nelems, ulonglong *value)
3149{
3150        off_t offset = NC_varoffset(ncp, varp, start);
3151        size_t remaining = varp->xsz * nelems;
3152        int status = NC_NOERR;
3153        const void *xp;
3154
3155        if(nelems == 0)
3156                return NC_NOERR;
3157
3158        assert(value != NULL);
3159
3160        for(;;)
3161        {
3162                size_t extent = MIN(remaining, ncp->chunk);
3163                size_t nget = ncx_howmany(varp->type, extent);
3164
3165                int lstatus = ncio_get(ncp->nciop, offset, extent,
3166                                 0, (void **)&xp);      /* cast away const */
3167                if(lstatus != NC_NOERR)
3168                        return lstatus;
3169               
3170                lstatus = ncx_getn_schar_ulonglong(&xp, nget, value);
3171                if(lstatus != NC_NOERR && status == NC_NOERR)
3172                        status = lstatus;
3173
3174                (void) ncio_rel(ncp->nciop, offset, 0); 
3175
3176                remaining -= extent;
3177                if(remaining == 0)
3178                        break; /* normal loop exit */
3179                offset += extent;
3180                value += nget;
3181        }
3182
3183        return status;
3184}
3185
3186
3187static int
3188getNCvx_short_schar(const NC *ncp, const NC_var *varp,
3189                 const size_t *start, size_t nelems, schar *value)
3190{
3191        off_t offset = NC_varoffset(ncp, varp, start);
3192        size_t remaining = varp->xsz * nelems;
3193        int status = NC_NOERR;
3194        const void *xp;
3195
3196        if(nelems == 0)
3197                return NC_NOERR;
3198
3199        assert(value != NULL);
3200
3201        for(;;)
3202        {
3203                size_t extent = MIN(remaining, ncp->chunk);
3204                size_t nget = ncx_howmany(varp->type, extent);
3205
3206                int lstatus = ncio_get(ncp->nciop, offset, extent,
3207                                 0, (void **)&xp);      /* cast away const */
3208                if(lstatus != NC_NOERR)
3209                        return lstatus;
3210               
3211                lstatus = ncx_getn_short_schar(&xp, nget, value);
3212                if(lstatus != NC_NOERR && status == NC_NOERR)
3213                        status = lstatus;
3214
3215                (void) ncio_rel(ncp->nciop, offset, 0); 
3216
3217                remaining -= extent;
3218                if(remaining == 0)
3219                        break; /* normal loop exit */
3220                offset += extent;
3221                value += nget;
3222        }
3223
3224        return status;
3225}
3226
3227static int
3228getNCvx_short_uchar(const NC *ncp, const NC_var *varp,
3229                 const size_t *start, size_t nelems, uchar *value)
3230{
3231        off_t offset = NC_varoffset(ncp, varp, start);
3232        size_t remaining = varp->xsz * nelems;
3233        int status = NC_NOERR;
3234        const void *xp;
3235
3236        if(nelems == 0)
3237                return NC_NOERR;
3238
3239        assert(value != NULL);
3240
3241        for(;;)
3242        {
3243                size_t extent = MIN(remaining, ncp->chunk);
3244                size_t nget = ncx_howmany(varp->type, extent);
3245
3246                int lstatus = ncio_get(ncp->nciop, offset, extent,
3247                                 0, (void **)&xp);      /* cast away const */
3248                if(lstatus != NC_NOERR)
3249                        return lstatus;
3250               
3251                lstatus = ncx_getn_short_uchar(&xp, nget, value);
3252                if(lstatus != NC_NOERR && status == NC_NOERR)
3253                        status = lstatus;
3254
3255                (void) ncio_rel(ncp->nciop, offset, 0); 
3256
3257                remaining -= extent;
3258                if(remaining == 0)
3259                        break; /* normal loop exit */
3260                offset += extent;
3261                value += nget;
3262        }
3263
3264        return status;
3265}
3266
3267static int
3268getNCvx_short_short(const NC *ncp, const NC_var *varp,
3269                 const size_t *start, size_t nelems, short *value)
3270{
3271        off_t offset = NC_varoffset(ncp, varp, start);
3272        size_t remaining = varp->xsz * nelems;
3273        int status = NC_NOERR;
3274        const void *xp;
3275
3276        if(nelems == 0)
3277                return NC_NOERR;
3278
3279        assert(value != NULL);
3280
3281        for(;;)
3282        {
3283                size_t extent = MIN(remaining, ncp->chunk);
3284                size_t nget = ncx_howmany(varp->type, extent);
3285
3286                int lstatus = ncio_get(ncp->nciop, offset, extent,
3287                                 0, (void **)&xp);      /* cast away const */
3288                if(lstatus != NC_NOERR)
3289                        return lstatus;
3290               
3291                lstatus = ncx_getn_short_short(&xp, nget, value);
3292                if(lstatus != NC_NOERR && status == NC_NOERR)
3293                        status = lstatus;
3294
3295                (void) ncio_rel(ncp->nciop, offset, 0); 
3296
3297                remaining -= extent;
3298                if(remaining == 0)
3299                        break; /* normal loop exit */
3300                offset += extent;
3301                value += nget;
3302        }
3303
3304        return status;
3305}
3306
3307static int
3308getNCvx_short_int(const NC *ncp, const NC_var *varp,
3309                 const size_t *start, size_t nelems, int *value)
3310{
3311        off_t offset = NC_varoffset(ncp, varp, start);
3312        size_t remaining = varp->xsz * nelems;
3313        int status = NC_NOERR;
3314        const void *xp;
3315
3316        if(nelems == 0)
3317                return NC_NOERR;
3318
3319        assert(value != NULL);
3320
3321        for(;;)
3322        {
3323                size_t extent = MIN(remaining, ncp->chunk);
3324                size_t nget = ncx_howmany(varp->type, extent);
3325
3326                int lstatus = ncio_get(ncp->nciop, offset, extent,
3327                                 0, (void **)&xp);      /* cast away const */
3328                if(lstatus != NC_NOERR)
3329                        return lstatus;
3330               
3331                lstatus = ncx_getn_short_int(&xp, nget, value);
3332                if(lstatus != NC_NOERR && status == NC_NOERR)
3333                        status = lstatus;
3334
3335                (void) ncio_rel(ncp->nciop, offset, 0); 
3336
3337                remaining -= extent;
3338                if(remaining == 0)
3339                        break; /* normal loop exit */
3340                offset += extent;
3341                value += nget;
3342        }
3343
3344        return status;
3345}
3346
3347static int
3348getNCvx_short_float(const NC *ncp, const NC_var *varp,
3349                 const size_t *start, size_t nelems, float *value)
3350{
3351        off_t offset = NC_varoffset(ncp, varp, start);
3352        size_t remaining = varp->xsz * nelems;
3353        int status = NC_NOERR;
3354        const void *xp;
3355
3356        if(nelems == 0)
3357                return NC_NOERR;
3358
3359        assert(value != NULL);
3360
3361        for(;;)
3362        {
3363                size_t extent = MIN(remaining, ncp->chunk);
3364                size_t nget = ncx_howmany(varp->type, extent);
3365
3366                int lstatus = ncio_get(ncp->nciop, offset, extent,
3367                                 0, (void **)&xp);      /* cast away const */
3368                if(lstatus != NC_NOERR)
3369                        return lstatus;
3370               
3371                lstatus = ncx_getn_short_float(&xp, nget, value);
3372                if(lstatus != NC_NOERR && status == NC_NOERR)
3373                        status = lstatus;
3374
3375                (void) ncio_rel(ncp->nciop, offset, 0); 
3376
3377                remaining -= extent;
3378                if(remaining == 0)
3379                        break; /* normal loop exit */
3380                offset += extent;
3381                value += nget;
3382        }
3383
3384        return status;
3385}
3386
3387static int
3388getNCvx_short_double(const NC *ncp, const NC_var *varp,
3389                 const size_t *start, size_t nelems, double *value)
3390{
3391        off_t offset = NC_varoffset(ncp, varp, start);
3392        size_t remaining = varp->xsz * nelems;
3393        int status = NC_NOERR;
3394        const void *xp;
3395
3396        if(nelems == 0)
3397                return NC_NOERR;
3398
3399        assert(value != NULL);
3400
3401        for(;;)
3402        {
3403                size_t extent = MIN(remaining, ncp->chunk);
3404                size_t nget = ncx_howmany(varp->type, extent);
3405
3406                int lstatus = ncio_get(ncp->nciop, offset, extent,
3407                                 0, (void **)&xp);      /* cast away const */
3408                if(lstatus != NC_NOERR)
3409                        return lstatus;
3410               
3411                lstatus = ncx_getn_short_double(&xp, nget, value);
3412                if(lstatus != NC_NOERR && status == NC_NOERR)
3413                        status = lstatus;
3414
3415                (void) ncio_rel(ncp->nciop, offset, 0); 
3416
3417                remaining -= extent;
3418                if(remaining == 0)
3419                        break; /* normal loop exit */
3420                offset += extent;
3421                value += nget;
3422        }
3423
3424        return status;
3425}
3426
3427static int
3428getNCvx_short_longlong(const NC *ncp, const NC_var *varp,
3429                 const size_t *start, size_t nelems, longlong *value)
3430{
3431        off_t offset = NC_varoffset(ncp, varp, start);
3432        size_t remaining = varp->xsz * nelems;
3433        int status = NC_NOERR;
3434        const void *xp;
3435
3436        if(nelems == 0)
3437                return NC_NOERR;
3438
3439        assert(value != NULL);
3440
3441        for(;;)
3442        {
3443                size_t extent = MIN(remaining, ncp->chunk);
3444                size_t nget = ncx_howmany(varp->type, extent);
3445
3446                int lstatus = ncio_get(ncp->nciop, offset, extent,
3447                                 0, (void **)&xp);      /* cast away const */
3448                if(lstatus != NC_NOERR)
3449                        return lstatus;
3450               
3451                lstatus = ncx_getn_short_longlong(&xp, nget, value);
3452                if(lstatus != NC_NOERR && status == NC_NOERR)
3453                        status = lstatus;
3454
3455                (void) ncio_rel(ncp->nciop, offset, 0); 
3456
3457                remaining -= extent;
3458                if(remaining == 0)
3459                        break; /* normal loop exit */
3460                offset += extent;
3461                value += nget;
3462        }
3463
3464        return status;
3465}
3466
3467static int
3468getNCvx_short_uint(const NC *ncp, const NC_var *varp,
3469                 const size_t *start, size_t nelems, uint *value)
3470{
3471        off_t offset = NC_varoffset(ncp, varp, start);
3472        size_t remaining = varp->xsz * nelems;
3473        int status = NC_NOERR;
3474        const void *xp;
3475
3476        if(nelems == 0)
3477                return NC_NOERR;
3478
3479        assert(value != NULL);
3480
3481        for(;;)
3482        {
3483                size_t extent = MIN(remaining, ncp->chunk);
3484                size_t nget = ncx_howmany(varp->type, extent);
3485
3486                int lstatus = ncio_get(ncp->nciop, offset, extent,
3487                                 0, (void **)&xp);      /* cast away const */
3488                if(lstatus != NC_NOERR)
3489                        return lstatus;
3490               
3491                lstatus = ncx_getn_short_uint(&xp, nget, value);
3492                if(lstatus != NC_NOERR && status == NC_NOERR)
3493                        status = lstatus;
3494
3495                (void) ncio_rel(ncp->nciop, offset, 0); 
3496
3497                remaining -= extent;
3498                if(remaining == 0)
3499                        break; /* normal loop exit */
3500                offset += extent;
3501                value += nget;
3502        }
3503
3504        return status;
3505}
3506
3507static int
3508getNCvx_short_ulonglong(const NC *ncp, const NC_var *varp,
3509                 const size_t *start, size_t nelems, ulonglong *value)
3510{
3511        off_t offset = NC_varoffset(ncp, varp, start);
3512        size_t remaining = varp->xsz * nelems;
3513        int status = NC_NOERR;
3514        const void *xp;
3515
3516        if(nelems == 0)
3517                return NC_NOERR;
3518
3519        assert(value != NULL);
3520
3521        for(;;)
3522        {
3523                size_t extent = MIN(remaining, ncp->chunk);
3524                size_t nget = ncx_howmany(varp->type, extent);
3525
3526                int lstatus = ncio_get(ncp->nciop, offset, extent,
3527                                 0, (void **)&xp);      /* cast away const */
3528                if(lstatus != NC_NOERR)
3529                        return lstatus;
3530               
3531                lstatus = ncx_getn_short_ulonglong(&xp, nget, value);
3532                if(lstatus != NC_NOERR && status == NC_NOERR)
3533                        status = lstatus;
3534
3535                (void) ncio_rel(ncp->nciop, offset, 0); 
3536
3537                remaining -= extent;
3538                if(remaining == 0)
3539                        break; /* normal loop exit */
3540                offset += extent;
3541                value += nget;
3542        }
3543
3544        return status;
3545}
3546
3547
3548static int
3549getNCvx_int_schar(const NC *ncp, const NC_var *varp,
3550                 const size_t *start, size_t nelems, schar *value)
3551{
3552        off_t offset = NC_varoffset(ncp, varp, start);
3553        size_t remaining = varp->xsz * nelems;
3554        int status = NC_NOERR;
3555        const void *xp;
3556
3557        if(nelems == 0)
3558                return NC_NOERR;
3559
3560        assert(value != NULL);
3561
3562        for(;;)
3563        {
3564                size_t extent = MIN(remaining, ncp->chunk);
3565                size_t nget = ncx_howmany(varp->type, extent);
3566
3567                int lstatus = ncio_get(ncp->nciop, offset, extent,
3568                                 0, (void **)&xp);      /* cast away const */
3569                if(lstatus != NC_NOERR)
3570                        return lstatus;
3571               
3572                lstatus = ncx_getn_int_schar(&xp, nget, value);
3573                if(lstatus != NC_NOERR && status == NC_NOERR)
3574                        status = lstatus;
3575
3576                (void) ncio_rel(ncp->nciop, offset, 0); 
3577
3578                remaining -= extent;
3579                if(remaining == 0)
3580                        break; /* normal loop exit */
3581                offset += extent;
3582                value += nget;
3583        }
3584
3585        return status;
3586}
3587
3588static int
3589getNCvx_int_uchar(const NC *ncp, const NC_var *varp,
3590                 const size_t *start, size_t nelems, uchar *value)
3591{
3592        off_t offset = NC_varoffset(ncp, varp, start);
3593        size_t remaining = varp->xsz * nelems;
3594        int status = NC_NOERR;
3595        const void *xp;
3596
3597        if(nelems == 0)
3598                return NC_NOERR;
3599
3600        assert(value != NULL);
3601
3602        for(;;)
3603        {
3604                size_t extent = MIN(remaining, ncp->chunk);
3605                size_t nget = ncx_howmany(varp->type, extent);
3606
3607                int lstatus = ncio_get(ncp->nciop, offset, extent,
3608                                 0, (void **)&xp);      /* cast away const */
3609                if(lstatus != NC_NOERR)
3610                        return lstatus;
3611               
3612                lstatus = ncx_getn_int_uchar(&xp, nget, value);
3613                if(lstatus != NC_NOERR && status == NC_NOERR)
3614                        status = lstatus;
3615
3616                (void) ncio_rel(ncp->nciop, offset, 0); 
3617
3618                remaining -= extent;
3619                if(remaining == 0)
3620                        break; /* normal loop exit */
3621                offset += extent;
3622                value += nget;
3623        }
3624
3625        return status;
3626}
3627
3628static int
3629getNCvx_int_short(const NC *ncp, const NC_var *varp,
3630                 const size_t *start, size_t nelems, short *value)
3631{
3632        off_t offset = NC_varoffset(ncp, varp, start);
3633        size_t remaining = varp->xsz * nelems;
3634        int status = NC_NOERR;
3635        const void *xp;
3636
3637        if(nelems == 0)
3638                return NC_NOERR;
3639
3640        assert(value != NULL);
3641
3642        for(;;)
3643        {
3644                size_t extent = MIN(remaining, ncp->chunk);
3645                size_t nget = ncx_howmany(varp->type, extent);
3646
3647                int lstatus = ncio_get(ncp->nciop, offset, extent,
3648                                 0, (void **)&xp);      /* cast away const */
3649                if(lstatus != NC_NOERR)
3650                        return lstatus;
3651               
3652                lstatus = ncx_getn_int_short(&xp, nget, value);
3653                if(lstatus != NC_NOERR && status == NC_NOERR)
3654                        status = lstatus;
3655
3656                (void) ncio_rel(ncp->nciop, offset, 0); 
3657
3658                remaining -= extent;
3659                if(remaining == 0)
3660                        break; /* normal loop exit */
3661                offset += extent;
3662                value += nget;
3663        }
3664
3665        return status;
3666}
3667
3668static int
3669getNCvx_int_int(const NC *ncp, const NC_var *varp,
3670                 const size_t *start, size_t nelems, int *value)
3671{
3672        off_t offset = NC_varoffset(ncp, varp, start);
3673        size_t remaining = varp->xsz * nelems;
3674        int status = NC_NOERR;
3675        const void *xp;
3676
3677        if(nelems == 0)
3678                return NC_NOERR;
3679
3680        assert(value != NULL);
3681
3682        for(;;)
3683        {
3684                size_t extent = MIN(remaining, ncp->chunk);
3685                size_t nget = ncx_howmany(varp->type, extent);
3686
3687                int lstatus = ncio_get(ncp->nciop, offset, extent,
3688                                 0, (void **)&xp);      /* cast away const */
3689                if(lstatus != NC_NOERR)
3690                        return lstatus;
3691               
3692                lstatus = ncx_getn_int_int(&xp, nget, value);
3693                if(lstatus != NC_NOERR && status == NC_NOERR)
3694                        status = lstatus;
3695
3696                (void) ncio_rel(ncp->nciop, offset, 0); 
3697
3698                remaining -= extent;
3699                if(remaining == 0)
3700                        break; /* normal loop exit */
3701                offset += extent;
3702                value += nget;
3703        }
3704
3705        return status;
3706}
3707
3708static int
3709getNCvx_int_float(const NC *ncp, const NC_var *varp,
3710                 const size_t *start, size_t nelems, float *value)
3711{
3712        off_t offset = NC_varoffset(ncp, varp, start);
3713        size_t remaining = varp->xsz * nelems;
3714        int status = NC_NOERR;
3715        const void *xp;
3716
3717        if(nelems == 0)
3718                return NC_NOERR;
3719
3720        assert(value != NULL);
3721
3722        for(;;)
3723        {
3724                size_t extent = MIN(remaining, ncp->chunk);
3725                size_t nget = ncx_howmany(varp->type, extent);
3726
3727                int lstatus = ncio_get(ncp->nciop, offset, extent,
3728                                 0, (void **)&xp);      /* cast away const */
3729                if(lstatus != NC_NOERR)
3730                        return lstatus;
3731               
3732                lstatus = ncx_getn_int_float(&xp, nget, value);
3733                if(lstatus != NC_NOERR && status == NC_NOERR)
3734                        status = lstatus;
3735
3736                (void) ncio_rel(ncp->nciop, offset, 0); 
3737
3738                remaining -= extent;
3739                if(remaining == 0)
3740                        break; /* normal loop exit */
3741                offset += extent;
3742                value += nget;
3743        }
3744
3745        return status;
3746}
3747
3748static int
3749getNCvx_int_double(const NC *ncp, const NC_var *varp,
3750                 const size_t *start, size_t nelems, double *value)
3751{
3752        off_t offset = NC_varoffset(ncp, varp, start);
3753        size_t remaining = varp->xsz * nelems;
3754        int status = NC_NOERR;
3755        const void *xp;
3756
3757        if(nelems == 0)
3758                return NC_NOERR;
3759
3760        assert(value != NULL);
3761
3762        for(;;)
3763        {
3764                size_t extent = MIN(remaining, ncp->chunk);
3765                size_t nget = ncx_howmany(varp->type, extent);
3766
3767                int lstatus = ncio_get(ncp->nciop, offset, extent,
3768                                 0, (void **)&xp);      /* cast away const */
3769                if(lstatus != NC_NOERR)
3770                        return lstatus;
3771               
3772                lstatus = ncx_getn_int_double(&xp, nget, value);
3773                if(lstatus != NC_NOERR && status == NC_NOERR)
3774                        status = lstatus;
3775
3776                (void) ncio_rel(ncp->nciop, offset, 0); 
3777
3778                remaining -= extent;
3779                if(remaining == 0)
3780                        break; /* normal loop exit */
3781                offset += extent;
3782                value += nget;
3783        }
3784
3785        return status;
3786}
3787
3788static int
3789getNCvx_int_longlong(const NC *ncp, const NC_var *varp,
3790                 const size_t *start, size_t nelems, longlong *value)
3791{
3792        off_t offset = NC_varoffset(ncp, varp, start);
3793        size_t remaining = varp->xsz * nelems;
3794        int status = NC_NOERR;
3795        const void *xp;
3796
3797        if(nelems == 0)
3798                return NC_NOERR;
3799
3800        assert(value != NULL);
3801
3802        for(;;)
3803        {
3804                size_t extent = MIN(remaining, ncp->chunk);
3805                size_t nget = ncx_howmany(varp->type, extent);
3806
3807                int lstatus = ncio_get(ncp->nciop, offset, extent,
3808                                 0, (void **)&xp);      /* cast away const */
3809                if(lstatus != NC_NOERR)
3810                        return lstatus;
3811               
3812                lstatus = ncx_getn_int_longlong(&xp, nget, value);
3813                if(lstatus != NC_NOERR && status == NC_NOERR)
3814                        status = lstatus;
3815
3816                (void) ncio_rel(ncp->nciop, offset, 0); 
3817
3818                remaining -= extent;
3819                if(remaining == 0)
3820                        break; /* normal loop exit */
3821                offset += extent;
3822                value += nget;
3823        }
3824
3825        return status;
3826}
3827
3828static int
3829getNCvx_int_uint(const NC *ncp, const NC_var *varp,
3830                 const size_t *start, size_t nelems, uint *value)
3831{
3832        off_t offset = NC_varoffset(ncp, varp, start);
3833        size_t remaining = varp->xsz * nelems;
3834        int status = NC_NOERR;
3835        const void *xp;
3836
3837        if(nelems == 0)
3838                return NC_NOERR;
3839
3840        assert(value != NULL);
3841
3842        for(;;)
3843        {
3844                size_t extent = MIN(remaining, ncp->chunk);
3845                size_t nget = ncx_howmany(varp->type, extent);
3846
3847                int lstatus = ncio_get(ncp->nciop, offset, extent,
3848                                 0, (void **)&xp);      /* cast away const */
3849                if(lstatus != NC_NOERR)
3850                        return lstatus;
3851               
3852                lstatus = ncx_getn_int_uint(&xp, nget, value);
3853                if(lstatus != NC_NOERR && status == NC_NOERR)
3854                        status = lstatus;
3855
3856                (void) ncio_rel(ncp->nciop, offset, 0); 
3857
3858                remaining -= extent;
3859                if(remaining == 0)
3860                        break; /* normal loop exit */
3861                offset += extent;
3862                value += nget;
3863        }
3864
3865        return status;
3866}
3867
3868static int
3869getNCvx_int_ulonglong(const NC *ncp, const NC_var *varp,
3870                 const size_t *start, size_t nelems, ulonglong *value)
3871{
3872        off_t offset = NC_varoffset(ncp, varp, start);
3873        size_t remaining = varp->xsz * nelems;
3874        int status = NC_NOERR;
3875        const void *xp;
3876
3877        if(nelems == 0)
3878                return NC_NOERR;
3879
3880        assert(value != NULL);
3881
3882        for(;;)
3883        {
3884                size_t extent = MIN(remaining, ncp->chunk);
3885                size_t nget = ncx_howmany(varp->type, extent);
3886
3887                int lstatus = ncio_get(ncp->nciop, offset, extent,
3888                                 0, (void **)&xp);      /* cast away const */
3889                if(lstatus != NC_NOERR)
3890                        return lstatus;
3891               
3892                lstatus = ncx_getn_int_ulonglong(&xp, nget, value);
3893                if(lstatus != NC_NOERR && status == NC_NOERR)
3894                        status = lstatus;
3895
3896                (void) ncio_rel(ncp->nciop, offset, 0); 
3897
3898                remaining -= extent;
3899                if(remaining == 0)
3900                        break; /* normal loop exit */
3901                offset += extent;
3902                value += nget;
3903        }
3904
3905        return status;
3906}
3907
3908
3909static int
3910getNCvx_float_schar(const NC *ncp, const NC_var *varp,
3911                 const size_t *start, size_t nelems, schar *value)
3912{
3913        off_t offset = NC_varoffset(ncp, varp, start);
3914        size_t remaining = varp->xsz * nelems;
3915        int status = NC_NOERR;
3916        const void *xp;
3917
3918        if(nelems == 0)
3919                return NC_NOERR;
3920
3921        assert(value != NULL);
3922
3923        for(;;)
3924        {
3925                size_t extent = MIN(remaining, ncp->chunk);
3926                size_t nget = ncx_howmany(varp->type, extent);
3927
3928                int lstatus = ncio_get(ncp->nciop, offset, extent,
3929                                 0, (void **)&xp);      /* cast away const */
3930                if(lstatus != NC_NOERR)
3931                        return lstatus;
3932               
3933                lstatus = ncx_getn_float_schar(&xp, nget, value);
3934                if(lstatus != NC_NOERR && status == NC_NOERR)
3935                        status = lstatus;
3936
3937                (void) ncio_rel(ncp->nciop, offset, 0); 
3938
3939                remaining -= extent;
3940                if(remaining == 0)
3941                        break; /* normal loop exit */
3942                offset += extent;
3943                value += nget;
3944        }
3945
3946        return status;
3947}
3948
3949static int
3950getNCvx_float_uchar(const NC *ncp, const NC_var *varp,
3951                 const size_t *start, size_t nelems, uchar *value)
3952{
3953        off_t offset = NC_varoffset(ncp, varp, start);
3954        size_t remaining = varp->xsz * nelems;
3955        int status = NC_NOERR;
3956        const void *xp;
3957
3958        if(nelems == 0)
3959                return NC_NOERR;
3960
3961        assert(value != NULL);
3962
3963        for(;;)
3964        {
3965                size_t extent = MIN(remaining, ncp->chunk);
3966                size_t nget = ncx_howmany(varp->type, extent);
3967
3968                int lstatus = ncio_get(ncp->nciop, offset, extent,
3969                                 0, (void **)&xp);      /* cast away const */
3970                if(lstatus != NC_NOERR)
3971                        return lstatus;
3972               
3973                lstatus = ncx_getn_float_uchar(&xp, nget, value);
3974                if(lstatus != NC_NOERR && status == NC_NOERR)
3975                        status = lstatus;
3976
3977                (void) ncio_rel(ncp->nciop, offset, 0); 
3978
3979                remaining -= extent;
3980                if(remaining == 0)
3981                        break; /* normal loop exit */
3982                offset += extent;
3983                value += nget;
3984        }
3985
3986        return status;
3987}
3988
3989static int
3990getNCvx_float_short(const NC *ncp, const NC_var *varp,
3991                 const size_t *start, size_t nelems, short *value)
3992{
3993        off_t offset = NC_varoffset(ncp, varp, start);
3994        size_t remaining = varp->xsz * nelems;
3995        int status = NC_NOERR;
3996        const void *xp;
3997
3998        if(nelems == 0)
3999                return NC_NOERR;
4000
4001        assert(value != NULL);
4002
4003        for(;;)
4004        {
4005                size_t extent = MIN(remaining, ncp->chunk);
4006                size_t nget = ncx_howmany(varp->type, extent);
4007
4008                int lstatus = ncio_get(ncp->nciop, offset, extent,
4009                                 0, (void **)&xp);      /* cast away const */
4010                if(lstatus != NC_NOERR)
4011                        return lstatus;
4012               
4013                lstatus = ncx_getn_float_short(&xp, nget, value);
4014                if(lstatus != NC_NOERR && status == NC_NOERR)
4015                        status = lstatus;
4016
4017                (void) ncio_rel(ncp->nciop, offset, 0); 
4018
4019                remaining -= extent;
4020                if(remaining == 0)
4021                        break; /* normal loop exit */
4022                offset += extent;
4023                value += nget;
4024        }
4025
4026        return status;
4027}
4028
4029static int
4030getNCvx_float_int(const NC *ncp, const NC_var *varp,
4031                 const size_t *start, size_t nelems, int *value)
4032{
4033        off_t offset = NC_varoffset(ncp, varp, start);
4034        size_t remaining = varp->xsz * nelems;
4035        int status = NC_NOERR;
4036        const void *xp;
4037
4038        if(nelems == 0)
4039                return NC_NOERR;
4040
4041        assert(value != NULL);
4042
4043        for(;;)
4044        {
4045                size_t extent = MIN(remaining, ncp->chunk);
4046                size_t nget = ncx_howmany(varp->type, extent);
4047
4048                int lstatus = ncio_get(ncp->nciop, offset, extent,
4049                                 0, (void **)&xp);      /* cast away const */
4050                if(lstatus != NC_NOERR)
4051                        return lstatus;
4052               
4053                lstatus = ncx_getn_float_int(&xp, nget, value);
4054                if(lstatus != NC_NOERR && status == NC_NOERR)
4055                        status = lstatus;
4056
4057                (void) ncio_rel(ncp->nciop, offset, 0); 
4058
4059                remaining -= extent;
4060                if(remaining == 0)
4061                        break; /* normal loop exit */
4062                offset += extent;
4063                value += nget;
4064        }
4065
4066        return status;
4067}
4068
4069static int
4070getNCvx_float_float(const NC *ncp, const NC_var *varp,
4071                 const size_t *start, size_t nelems, float *value)
4072{
4073        off_t offset = NC_varoffset(ncp, varp, start);
4074        size_t remaining = varp->xsz * nelems;
4075        int status = NC_NOERR;
4076        const void *xp;
4077
4078        if(nelems == 0)
4079                return NC_NOERR;
4080
4081        assert(value != NULL);
4082
4083        for(;;)
4084        {
4085                size_t extent = MIN(remaining, ncp->chunk);
4086                size_t nget = ncx_howmany(varp->type, extent);
4087
4088                int lstatus = ncio_get(ncp->nciop, offset, extent,
4089                                 0, (void **)&xp);      /* cast away const */
4090                if(lstatus != NC_NOERR)
4091                        return lstatus;
4092               
4093                lstatus = ncx_getn_float_float(&xp, nget, value);
4094                if(lstatus != NC_NOERR && status == NC_NOERR)
4095                        status = lstatus;
4096
4097                (void) ncio_rel(ncp->nciop, offset, 0); 
4098
4099                remaining -= extent;
4100                if(remaining == 0)
4101                        break; /* normal loop exit */
4102                offset += extent;
4103                value += nget;
4104        }
4105
4106        return status;
4107}
4108
4109static int
4110getNCvx_float_double(const NC *ncp, const NC_var *varp,
4111                 const size_t *start, size_t nelems, double *value)
4112{
4113        off_t offset = NC_varoffset(ncp, varp, start);
4114        size_t remaining = varp->xsz * nelems;
4115        int status = NC_NOERR;
4116        const void *xp;
4117
4118        if(nelems == 0)
4119                return NC_NOERR;
4120
4121        assert(value != NULL);
4122
4123        for(;;)
4124        {
4125                size_t extent = MIN(remaining, ncp->chunk);
4126                size_t nget = ncx_howmany(varp->type, extent);
4127
4128                int lstatus = ncio_get(ncp->nciop, offset, extent,
4129                                 0, (void **)&xp);      /* cast away const */
4130                if(lstatus != NC_NOERR)
4131                        return lstatus;
4132               
4133                lstatus = ncx_getn_float_double(&xp, nget, value);
4134                if(lstatus != NC_NOERR && status == NC_NOERR)
4135                        status = lstatus;
4136
4137                (void) ncio_rel(ncp->nciop, offset, 0); 
4138
4139                remaining -= extent;
4140                if(remaining == 0)
4141                        break; /* normal loop exit */
4142                offset += extent;
4143                value += nget;
4144        }
4145
4146        return status;
4147}
4148
4149static int
4150getNCvx_float_longlong(const NC *ncp, const NC_var *varp,
4151                 const size_t *start, size_t nelems, longlong *value)
4152{
4153        off_t offset = NC_varoffset(ncp, varp, start);
4154        size_t remaining = varp->xsz * nelems;
4155        int status = NC_NOERR;
4156        const void *xp;
4157
4158        if(nelems == 0)
4159                return NC_NOERR;
4160
4161        assert(value != NULL);
4162
4163        for(;;)
4164        {
4165                size_t extent = MIN(remaining, ncp->chunk);
4166                size_t nget = ncx_howmany(varp->type, extent);
4167
4168                int lstatus = ncio_get(ncp->nciop, offset, extent,
4169                                 0, (void **)&xp);      /* cast away const */
4170                if(lstatus != NC_NOERR)
4171                        return lstatus;
4172               
4173                lstatus = ncx_getn_float_longlong(&xp, nget, value);
4174                if(lstatus != NC_NOERR && status == NC_NOERR)
4175                        status = lstatus;
4176
4177                (void) ncio_rel(ncp->nciop, offset, 0); 
4178
4179                remaining -= extent;
4180                if(remaining == 0)
4181                        break; /* normal loop exit */
4182                offset += extent;
4183                value += nget;
4184        }
4185
4186        return status;
4187}
4188
4189static int
4190getNCvx_float_uint(const NC *ncp, const NC_var *varp,
4191                 const size_t *start, size_t nelems, uint *value)
4192{
4193        off_t offset = NC_varoffset(ncp, varp, start);
4194        size_t remaining = varp->xsz * nelems;
4195        int status = NC_NOERR;
4196        const void *xp;
4197
4198        if(nelems == 0)
4199                return NC_NOERR;
4200
4201        assert(value != NULL);
4202
4203        for(;;)
4204        {
4205                size_t extent = MIN(remaining, ncp->chunk);
4206                size_t nget = ncx_howmany(varp->type, extent);
4207
4208                int lstatus = ncio_get(ncp->nciop, offset, extent,
4209                                 0, (void **)&xp);      /* cast away const */
4210                if(lstatus != NC_NOERR)
4211                        return lstatus;
4212               
4213                lstatus = ncx_getn_float_uint(&xp, nget, value);
4214                if(lstatus != NC_NOERR && status == NC_NOERR)
4215                        status = lstatus;
4216
4217                (void) ncio_rel(ncp->nciop, offset, 0); 
4218
4219                remaining -= extent;
4220                if(remaining == 0)
4221                        break; /* normal loop exit */
4222                offset += extent;
4223                value += nget;
4224        }
4225
4226        return status;
4227}
4228
4229static int
4230getNCvx_float_ulonglong(const NC *ncp, const NC_var *varp,
4231                 const size_t *start, size_t nelems, ulonglong *value)
4232{
4233        off_t offset = NC_varoffset(ncp, varp, start);
4234        size_t remaining = varp->xsz * nelems;
4235        int status = NC_NOERR;
4236        const void *xp;
4237
4238        if(nelems == 0)
4239                return NC_NOERR;
4240
4241        assert(value != NULL);
4242
4243        for(;;)
4244        {
4245                size_t extent = MIN(remaining, ncp->chunk);
4246                size_t nget = ncx_howmany(varp->type, extent);
4247
4248                int lstatus = ncio_get(ncp->nciop, offset, extent,
4249                                 0, (void **)&xp);      /* cast away const */
4250                if(lstatus != NC_NOERR)
4251                        return lstatus;
4252               
4253                lstatus = ncx_getn_float_ulonglong(&xp, nget, value);
4254                if(lstatus != NC_NOERR && status == NC_NOERR)
4255                        status = lstatus;
4256
4257                (void) ncio_rel(ncp->nciop, offset, 0); 
4258
4259                remaining -= extent;
4260                if(remaining == 0)
4261                        break; /* normal loop exit */
4262                offset += extent;
4263                value += nget;
4264        }
4265
4266        return status;
4267}
4268
4269
4270static int
4271getNCvx_double_schar(const NC *ncp, const NC_var *varp,
4272                 const size_t *start, size_t nelems, schar *value)
4273{
4274        off_t offset = NC_varoffset(ncp, varp, start);
4275        size_t remaining = varp->xsz * nelems;
4276        int status = NC_NOERR;
4277        const void *xp;
4278
4279        if(nelems == 0)
4280                return NC_NOERR;
4281
4282        assert(value != NULL);
4283
4284        for(;;)
4285        {
4286                size_t extent = MIN(remaining, ncp->chunk);
4287                size_t nget = ncx_howmany(varp->type, extent);
4288
4289                int lstatus = ncio_get(ncp->nciop, offset, extent,
4290                                 0, (void **)&xp);      /* cast away const */
4291                if(lstatus != NC_NOERR)
4292                        return lstatus;
4293               
4294                lstatus = ncx_getn_double_schar(&xp, nget, value);
4295                if(lstatus != NC_NOERR && status == NC_NOERR)
4296                        status = lstatus;
4297
4298                (void) ncio_rel(ncp->nciop, offset, 0); 
4299
4300                remaining -= extent;
4301                if(remaining == 0)
4302                        break; /* normal loop exit */
4303                offset += extent;
4304                value += nget;
4305        }
4306
4307        return status;
4308}
4309
4310static int
4311getNCvx_double_uchar(const NC *ncp, const NC_var *varp,
4312                 const size_t *start, size_t nelems, uchar *value)
4313{
4314        off_t offset = NC_varoffset(ncp, varp, start);
4315        size_t remaining = varp->xsz * nelems;
4316        int status = NC_NOERR;
4317        const void *xp;
4318
4319        if(nelems == 0)
4320                return NC_NOERR;
4321
4322        assert(value != NULL);
4323
4324        for(;;)
4325        {
4326                size_t extent = MIN(remaining, ncp->chunk);
4327                size_t nget = ncx_howmany(varp->type, extent);
4328
4329                int lstatus = ncio_get(ncp->nciop, offset, extent,
4330                                 0, (void **)&xp);      /* cast away const */
4331                if(lstatus != NC_NOERR)
4332                        return lstatus;
4333               
4334                lstatus = ncx_getn_double_uchar(&xp, nget, value);
4335                if(lstatus != NC_NOERR && status == NC_NOERR)
4336                        status = lstatus;
4337
4338                (void) ncio_rel(ncp->nciop, offset, 0); 
4339
4340                remaining -= extent;
4341                if(remaining == 0)
4342                        break; /* normal loop exit */
4343                offset += extent;
4344                value += nget;
4345        }
4346
4347        return status;
4348}
4349
4350static int
4351getNCvx_double_short(const NC *ncp, const NC_var *varp,
4352                 const size_t *start, size_t nelems, short *value)
4353{
4354        off_t offset = NC_varoffset(ncp, varp, start);
4355        size_t remaining = varp->xsz * nelems;
4356        int status = NC_NOERR;
4357        const void *xp;
4358
4359        if(nelems == 0)
4360                return NC_NOERR;
4361
4362        assert(value != NULL);
4363
4364        for(;;)
4365        {
4366                size_t extent = MIN(remaining, ncp->chunk);
4367                size_t nget = ncx_howmany(varp->type, extent);
4368
4369                int lstatus = ncio_get(ncp->nciop, offset, extent,
4370                                 0, (void **)&xp);      /* cast away const */
4371                if(lstatus != NC_NOERR)
4372                        return lstatus;
4373               
4374                lstatus = ncx_getn_double_short(&xp, nget, value);
4375                if(lstatus != NC_NOERR && status == NC_NOERR)
4376                        status = lstatus;
4377
4378                (void) ncio_rel(ncp->nciop, offset, 0); 
4379
4380                remaining -= extent;
4381                if(remaining == 0)
4382                        break; /* normal loop exit */
4383                offset += extent;
4384                value += nget;
4385        }
4386
4387        return status;
4388}
4389
4390static int
4391getNCvx_double_int(const NC *ncp, const NC_var *varp,
4392                 const size_t *start, size_t nelems, int *value)
4393{
4394        off_t offset = NC_varoffset(ncp, varp, start);
4395        size_t remaining = varp->xsz * nelems;
4396        int status = NC_NOERR;
4397        const void *xp;
4398
4399        if(nelems == 0)
4400                return NC_NOERR;
4401
4402        assert(value != NULL);
4403
4404        for(;;)
4405        {
4406                size_t extent = MIN(remaining, ncp->chunk);
4407                size_t nget = ncx_howmany(varp->type, extent);
4408
4409                int lstatus = ncio_get(ncp->nciop, offset, extent,
4410                                 0, (void **)&xp);      /* cast away const */
4411                if(lstatus != NC_NOERR)
4412                        return lstatus;
4413               
4414                lstatus = ncx_getn_double_int(&xp, nget, value);
4415                if(lstatus != NC_NOERR && status == NC_NOERR)
4416                        status = lstatus;
4417
4418                (void) ncio_rel(ncp->nciop, offset, 0); 
4419
4420                remaining -= extent;
4421                if(remaining == 0)
4422                        break; /* normal loop exit */
4423                offset += extent;
4424                value += nget;
4425        }
4426
4427        return status;
4428}
4429
4430static int
4431getNCvx_double_float(const NC *ncp, const NC_var *varp,
4432                 const size_t *start, size_t nelems, float *value)
4433{
4434        off_t offset = NC_varoffset(ncp, varp, start);
4435        size_t remaining = varp->xsz * nelems;
4436        int status = NC_NOERR;
4437        const void *xp;
4438
4439        if(nelems == 0)
4440                return NC_NOERR;
4441
4442        assert(value != NULL);
4443
4444        for(;;)
4445        {
4446                size_t extent = MIN(remaining, ncp->chunk);
4447                size_t nget = ncx_howmany(varp->type, extent);
4448
4449                int lstatus = ncio_get(ncp->nciop, offset, extent,
4450                                 0, (void **)&xp);      /* cast away const */
4451                if(lstatus != NC_NOERR)
4452                        return lstatus;
4453               
4454                lstatus = ncx_getn_double_float(&xp, nget, value);
4455                if(lstatus != NC_NOERR && status == NC_NOERR)
4456                        status = lstatus;
4457
4458                (void) ncio_rel(ncp->nciop, offset, 0); 
4459
4460                remaining -= extent;
4461                if(remaining == 0)
4462                        break; /* normal loop exit */
4463                offset += extent;
4464                value += nget;
4465        }
4466
4467        return status;
4468}
4469
4470static int
4471getNCvx_double_double(const NC *ncp, const NC_var *varp,
4472                 const size_t *start, size_t nelems, double *value)
4473{
4474        off_t offset = NC_varoffset(ncp, varp, start);
4475        size_t remaining = varp->xsz * nelems;
4476        int status = NC_NOERR;
4477        const void *xp;
4478
4479        if(nelems == 0)
4480                return NC_NOERR;
4481
4482        assert(value != NULL);
4483
4484        for(;;)
4485        {
4486                size_t extent = MIN(remaining, ncp->chunk);
4487                size_t nget = ncx_howmany(varp->type, extent);
4488
4489                int lstatus = ncio_get(ncp->nciop, offset, extent,
4490                                 0, (void **)&xp);      /* cast away const */
4491                if(lstatus != NC_NOERR)
4492                        return lstatus;
4493               
4494                lstatus = ncx_getn_double_double(&xp, nget, value);
4495                if(lstatus != NC_NOERR && status == NC_NOERR)
4496                        status = lstatus;
4497
4498                (void) ncio_rel(ncp->nciop, offset, 0); 
4499
4500                remaining -= extent;
4501                if(remaining == 0)
4502                        break; /* normal loop exit */
4503                offset += extent;
4504                value += nget;
4505        }
4506
4507        return status;
4508}
4509
4510static int
4511getNCvx_double_longlong(const NC *ncp, const NC_var *varp,
4512                 const size_t *start, size_t nelems, longlong *value)
4513{
4514        off_t offset = NC_varoffset(ncp, varp, start);
4515        size_t remaining = varp->xsz * nelems;
4516        int status = NC_NOERR;
4517        const void *xp;
4518
4519        if(nelems == 0)
4520                return NC_NOERR;
4521
4522        assert(value != NULL);
4523
4524        for(;;)
4525        {
4526                size_t extent = MIN(remaining, ncp->chunk);
4527                size_t nget = ncx_howmany(varp->type, extent);
4528
4529                int lstatus = ncio_get(ncp->nciop, offset, extent,
4530                                 0, (void **)&xp);      /* cast away const */
4531                if(lstatus != NC_NOERR)
4532                        return lstatus;
4533               
4534                lstatus = ncx_getn_double_longlong(&xp, nget, value);
4535                if(lstatus != NC_NOERR && status == NC_NOERR)
4536                        status = lstatus;
4537
4538                (void) ncio_rel(ncp->nciop, offset, 0); 
4539
4540                remaining -= extent;
4541                if(remaining == 0)
4542                        break; /* normal loop exit */
4543                offset += extent;
4544                value += nget;
4545        }
4546
4547        return status;
4548}
4549
4550static int
4551getNCvx_double_uint(const NC *ncp, const NC_var *varp,
4552                 const size_t *start, size_t nelems, uint *value)
4553{
4554        off_t offset = NC_varoffset(ncp, varp, start);
4555        size_t remaining = varp->xsz * nelems;
4556        int status = NC_NOERR;
4557        const void *xp;
4558
4559        if(nelems == 0)
4560                return NC_NOERR;
4561
4562        assert(value != NULL);
4563
4564        for(;;)
4565        {
4566                size_t extent = MIN(remaining, ncp->chunk);
4567                size_t nget = ncx_howmany(varp->type, extent);
4568
4569                int lstatus = ncio_get(ncp->nciop, offset, extent,
4570                                 0, (void **)&xp);      /* cast away const */
4571                if(lstatus != NC_NOERR)
4572                        return lstatus;
4573               
4574                lstatus = ncx_getn_double_uint(&xp, nget, value);
4575                if(lstatus != NC_NOERR && status == NC_NOERR)
4576                        status = lstatus;
4577
4578                (void) ncio_rel(ncp->nciop, offset, 0); 
4579
4580                remaining -= extent;
4581                if(remaining == 0)
4582                        break; /* normal loop exit */
4583                offset += extent;
4584                value += nget;
4585        }
4586
4587        return status;
4588}
4589
4590static int
4591getNCvx_double_ulonglong(const NC *ncp, const NC_var *varp,
4592                 const size_t *start, size_t nelems, ulonglong *value)
4593{
4594        off_t offset = NC_varoffset(ncp, varp, start);
4595        size_t remaining = varp->xsz * nelems;
4596        int status = NC_NOERR;
4597        const void *xp;
4598
4599        if(nelems == 0)
4600                return NC_NOERR;
4601
4602        assert(value != NULL);
4603
4604        for(;;)
4605        {
4606                size_t extent = MIN(remaining, ncp->chunk);
4607                size_t nget = ncx_howmany(varp->type, extent);
4608
4609                int lstatus = ncio_get(ncp->nciop, offset, extent,
4610                                 0, (void **)&xp);      /* cast away const */
4611                if(lstatus != NC_NOERR)
4612                        return lstatus;
4613               
4614                lstatus = ncx_getn_double_ulonglong(&xp, nget, value);
4615                if(lstatus != NC_NOERR && status == NC_NOERR)
4616                        status = lstatus;
4617
4618                (void) ncio_rel(ncp->nciop, offset, 0); 
4619
4620                remaining -= extent;
4621                if(remaining == 0)
4622                        break; /* normal loop exit */
4623                offset += extent;
4624                value += nget;
4625        }
4626
4627        return status;
4628}
4629
4630
4631#ifdef NOTUSED
4632static int
4633getNCvx_schar_uchar(const NC *ncp, const NC_var *varp,
4634                 const size_t *start, size_t nelems, uchar *value)
4635{
4636        off_t offset = NC_varoffset(ncp, varp, start);
4637        size_t remaining = varp->xsz * nelems;
4638        int status = NC_NOERR;
4639        const void *xp;
4640
4641        if(nelems == 0)
4642                return NC_NOERR;
4643
4644        assert(value != NULL);
4645
4646        for(;;)
4647        {
4648                size_t extent = MIN(remaining, ncp->chunk);
4649                size_t nget = ncx_howmany(varp->type, extent);
4650
4651                int lstatus = ncio_get(ncp->nciop, offset, extent,
4652                                 0, (void **)&xp);      /* cast away const */
4653                if(lstatus != NC_NOERR)
4654                        return lstatus;
4655               
4656                lstatus = ncx_getn_schar_uchar(&xp, nget, value);
4657                if(lstatus != NC_NOERR && status == NC_NOERR)
4658                        status = lstatus;
4659
4660                (void) ncio_rel(ncp->nciop, offset, 0); 
4661
4662                remaining -= extent;
4663                if(remaining == 0)
4664                        break; /* normal loop exit */
4665                offset += extent;
4666                value += nget;
4667        }
4668
4669        return status;
4670}
4671
4672#endif /*NOTUSED*/
4673
4674/*
4675 *  For ncvar{put,get},
4676 *  find the largest contiguous block from within 'edges'.
4677 *  returns the index to the left of this (which may be -1).
4678 *  Compute the number of contiguous elements and return
4679 *  that in *iocountp.
4680 *  The presence of "record" variables makes this routine
4681 *  overly subtle.
4682 */
4683static int
4684NCiocount(const NC *const ncp, const NC_var *const varp,
4685        const size_t *const edges,
4686        size_t *const iocountp)
4687{
4688        const size_t *edp0 = edges;
4689        const size_t *edp = edges + varp->ndims;
4690        const size_t *shp = varp->shape + varp->ndims;
4691
4692        if(IS_RECVAR(varp))
4693        {
4694                if(varp->ndims == 1 && ncp->recsize <= varp->len)
4695                {
4696                        /* one dimensional && the only 'record' variable */
4697                        *iocountp = *edges;
4698                        return(0);
4699                }
4700                /* else */
4701                edp0++;
4702        }
4703
4704        assert(edges != NULL);
4705
4706        /* find max contiguous */
4707        while(edp > edp0)
4708        {
4709                shp--; edp--;
4710                if(*edp < *shp )
4711                {
4712                        const size_t *zedp = edp;
4713                        while(zedp >= edp0)
4714                        {
4715                                if(*zedp == 0)
4716                                {
4717                                        *iocountp = 0;
4718                                        goto done;
4719                                }
4720                                /* Tip of the hat to segmented architectures */
4721                                if(zedp == edp0)
4722                                        break;
4723                                zedp--;
4724                        }
4725                        break;
4726                }
4727                assert(*edp == *shp);
4728        }
4729
4730        /*
4731         * edp, shp reference rightmost index s.t. *(edp +1) == *(shp +1)
4732         *
4733         * Or there is only one dimension.
4734         * If there is only one dimension and it is 'non record' dimension,
4735         *      edp is &edges[0] and we will return -1.
4736         * If there is only one dimension and and it is a "record dimension",
4737         *      edp is &edges[1] (out of bounds) and we will return 0;
4738         */
4739        assert(shp >= varp->shape + varp->ndims -1 
4740                || *(edp +1) == *(shp +1));
4741
4742        /* now accumulate max count for a single io operation */
4743        for(*iocountp = 1, edp0 = edp;
4744                        edp0 < edges + varp->ndims;
4745                        edp0++)
4746        {
4747                *iocountp *= *edp0;
4748        }
4749
4750done:
4751        return((int)(edp - edges) - 1);
4752}
4753
4754
4755/*
4756 * Set the elements of the array 'upp' to
4757 * the sum of the corresponding elements of
4758 * 'stp' and 'edp'. 'end' should be &stp[nelems].
4759 */
4760static void
4761set_upper(size_t *upp, /* modified on return */
4762        const size_t *stp,
4763        const size_t *edp,
4764        const size_t *const end)
4765{
4766        while(upp < end) {
4767                *upp++ = *stp++ + *edp++;
4768        }
4769}
4770
4771
4772/*
4773 * The infamous and oft-discussed odometer code.
4774 *
4775 * 'start[]' is the starting coordinate.
4776 * 'upper[]' is the upper bound s.t. start[ii] < upper[ii].
4777 * 'coord[]' is the register, the current coordinate value.
4778 * For some ii,
4779 * upp == &upper[ii]
4780 * cdp == &coord[ii]
4781 *
4782 * Running this routine increments *cdp.
4783 *
4784 * If after the increment, *cdp is equal to *upp
4785 * (and cdp is not the leftmost dimension),
4786 * *cdp is "zeroed" to the starting value and
4787 * we need to "carry", eg, increment one place to
4788 * the left.
4789 *
4790 * TODO: Some architectures hate recursion?
4791 *      Reimplement non-recursively.
4792 */
4793static void
4794odo1(const size_t *const start, const size_t *const upper,
4795        size_t *const coord, /* modified on return */
4796        const size_t *upp,
4797        size_t *cdp)
4798{
4799        assert(coord <= cdp && cdp <= coord + NC_MAX_VAR_DIMS);
4800        assert(upper <= upp && upp <= upper + NC_MAX_VAR_DIMS);
4801        assert(upp - upper == cdp - coord);
4802       
4803        assert(*cdp <= *upp);
4804
4805        (*cdp)++;
4806        if(cdp != coord && *cdp >= *upp)
4807        {
4808                *cdp = start[cdp - coord];
4809                odo1(start, upper, coord, upp -1, cdp -1);
4810        }
4811}
4812#ifdef _CRAYC
4813#pragma _CRI noinline odo1
4814#endif
4815
4816
4817
4818/* Define a macro to allow hash on two type values */
4819#define CASE(nc1,nc2) (nc1*256+nc2)
4820
4821static int
4822readNCv(const NC* ncp, const NC_var* varp, const size_t* start,
4823        const size_t nelems, void* value, const nc_type memtype)
4824{
4825    int status = NC_NOERR;
4826    switch (CASE(varp->type,memtype)) {
4827    case CASE(NC_CHAR,NC_CHAR):
4828    case CASE(NC_CHAR,NC_UBYTE):
4829        status = getNCvx_char_char(ncp,varp,start,nelems,(char*)value);
4830        break;
4831
4832    case CASE(NC_BYTE,NC_BYTE):
4833    case CASE(NC_BYTE,NC_UBYTE):
4834        status = getNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value);
4835        break;
4836    case CASE(NC_BYTE,NC_SHORT):
4837        status = getNCvx_schar_short(ncp,varp,start,nelems,(short*)value);
4838        break;
4839    case CASE(NC_BYTE,NC_INT):
4840        status = getNCvx_schar_int(ncp,varp,start,nelems,(int*)value);
4841        break;
4842    case CASE(NC_BYTE,NC_FLOAT):
4843        status = getNCvx_schar_float(ncp,varp,start,nelems,(float*)value);
4844        break;
4845    case CASE(NC_BYTE,NC_DOUBLE):
4846        status = getNCvx_schar_double(ncp,varp,start,nelems,(double *)value);
4847        break;
4848    case CASE(NC_BYTE,NC_INT64):
4849        status = getNCvx_schar_longlong(ncp,varp,start,nelems,(long long*)value);
4850        break;
4851    case CASE(NC_BYTE,NC_UINT):
4852        status = getNCvx_schar_uint(ncp,varp,start,nelems,(unsigned int*)value);
4853        break;
4854    case CASE(NC_BYTE,NC_UINT64):
4855        status = getNCvx_schar_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
4856        break;
4857
4858    case CASE(NC_SHORT,NC_BYTE):
4859        status = getNCvx_short_schar(ncp,varp,start,nelems,(signed char*)value);
4860        break;
4861    case CASE(NC_SHORT,NC_UBYTE):
4862        status = getNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value);
4863        break;
4864    case CASE(NC_SHORT,NC_SHORT):
4865        status = getNCvx_short_short(ncp,varp,start,nelems,(short*)value);
4866        break;
4867    case CASE(NC_SHORT,NC_INT):
4868        status = getNCvx_short_int(ncp,varp,start,nelems,(int*)value);
4869        break;
4870    case CASE(NC_SHORT,NC_FLOAT):
4871        status = getNCvx_short_float(ncp,varp,start,nelems,(float*)value);
4872        break;
4873    case CASE(NC_SHORT,NC_DOUBLE):
4874        status = getNCvx_short_double(ncp,varp,start,nelems,(double*)value);
4875        break;
4876    case CASE(NC_SHORT,NC_INT64):
4877        status = getNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value);
4878        break;
4879    case CASE(NC_SHORT,NC_UINT):
4880        status = getNCvx_short_uint(ncp,varp,start,nelems,(unsigned int*)value);
4881        break;
4882    case CASE(NC_SHORT,NC_UINT64):
4883        status = getNCvx_short_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
4884        break;
4885
4886
4887    case CASE(NC_INT,NC_BYTE):
4888        status = getNCvx_int_schar(ncp,varp,start,nelems,(signed char*)value);
4889        break;
4890    case CASE(NC_INT,NC_UBYTE):
4891        status = getNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value);
4892        break;
4893    case CASE(NC_INT,NC_SHORT):
4894        status = getNCvx_int_short(ncp,varp,start,nelems,(short*)value);
4895        break;
4896    case CASE(NC_INT,NC_INT):
4897        status = getNCvx_int_int(ncp,varp,start,nelems,(int*)value);
4898        break;
4899    case CASE(NC_INT,NC_FLOAT):
4900        status = getNCvx_int_float(ncp,varp,start,nelems,(float*)value);
4901        break;
4902    case CASE(NC_INT,NC_DOUBLE):
4903        status = getNCvx_int_double(ncp,varp,start,nelems,(double*)value);
4904        break;
4905    case CASE(NC_INT,NC_INT64):
4906        status = getNCvx_int_longlong(ncp,varp,start,nelems,(long long*)value);
4907        break;
4908    case CASE(NC_INT,NC_UINT):
4909        status = getNCvx_int_uint(ncp,varp,start,nelems,(unsigned int*)value);
4910        break;
4911    case CASE(NC_INT,NC_UINT64):
4912        status = getNCvx_int_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
4913        break;
4914
4915
4916    case CASE(NC_FLOAT,NC_BYTE):
4917        status = getNCvx_float_schar(ncp,varp,start,nelems,(signed char*)value);
4918        break;
4919    case CASE(NC_FLOAT,NC_UBYTE):
4920        status = getNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value);
4921        break;
4922    case CASE(NC_FLOAT,NC_SHORT):
4923        status = getNCvx_float_short(ncp,varp,start,nelems,(short*)value);
4924        break;
4925    case CASE(NC_FLOAT,NC_INT):
4926        status = getNCvx_float_int(ncp,varp,start,nelems,(int*)value);
4927        break;
4928    case CASE(NC_FLOAT,NC_FLOAT):
4929        status = getNCvx_float_float(ncp,varp,start,nelems,(float*)value);
4930        break;
4931    case CASE(NC_FLOAT,NC_DOUBLE):
4932        status = getNCvx_float_double(ncp,varp,start,nelems,(double*)value);
4933        break;
4934    case CASE(NC_FLOAT,NC_INT64):
4935        status = getNCvx_float_longlong(ncp,varp,start,nelems,(long long*)value);
4936        break;
4937    case CASE(NC_FLOAT,NC_UINT):
4938        status = getNCvx_float_uint(ncp,varp,start,nelems,(unsigned int*)value);
4939        break;
4940    case CASE(NC_FLOAT,NC_UINT64):
4941        status = getNCvx_float_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
4942        break;
4943
4944
4945    case CASE(NC_DOUBLE,NC_BYTE):
4946        status = getNCvx_double_schar(ncp,varp,start,nelems,(signed char*)value);
4947        break;
4948    case CASE(NC_DOUBLE,NC_UBYTE):
4949        status = getNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value);
4950        break;
4951    case CASE(NC_DOUBLE,NC_SHORT):
4952        status = getNCvx_double_short(ncp,varp,start,nelems,(short*)value);
4953        break;
4954    case CASE(NC_DOUBLE,NC_INT):
4955        status = getNCvx_double_int(ncp,varp,start,nelems,(int*)value);
4956        break;
4957    case CASE(NC_DOUBLE,NC_FLOAT):
4958        status = getNCvx_double_float(ncp,varp,start,nelems,(float*)value);
4959        break;
4960    case CASE(NC_DOUBLE,NC_DOUBLE):
4961        status = getNCvx_double_double(ncp,varp,start,nelems,(double*)value);
4962        break;
4963    case CASE(NC_DOUBLE,NC_INT64):
4964        status = getNCvx_double_longlong(ncp,varp,start,nelems,(long long*)value);
4965        break;
4966    case CASE(NC_DOUBLE,NC_UINT):
4967        status = getNCvx_double_uint(ncp,varp,start,nelems,(unsigned int*)value);
4968        break;
4969    case CASE(NC_DOUBLE,NC_UINT64):
4970        status = getNCvx_double_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value);
4971        break;
4972
4973    default:
4974        return NC_EBADTYPE;
4975    }
4976    return status;
4977}
4978
4979
4980static int
4981writeNCv(NC* ncp, const NC_var* varp, const size_t* start,
4982         const size_t nelems, const void* value, const nc_type memtype)
4983{
4984    int status = NC_NOERR;
4985    switch (CASE(varp->type,memtype)) {
4986    case CASE(NC_CHAR,NC_CHAR):
4987    case CASE(NC_CHAR,NC_UBYTE):
4988        status = putNCvx_char_char(ncp,varp,start,nelems,(char*)value);
4989        break;
4990
4991    case CASE(NC_BYTE,NC_BYTE):
4992        status = putNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value);
4993        break;
4994    case CASE(NC_BYTE,NC_UBYTE):
4995        status = putNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value);
4996        break;
4997    case CASE(NC_BYTE,NC_SHORT):
4998        status = putNCvx_schar_short(ncp,varp,start,nelems,(short*)value);
4999        break;
5000    case CASE(NC_BYTE,NC_INT):
5001        status = putNCvx_schar_int(ncp,varp,start,nelems,(int*)value);
5002        break;
5003    case CASE(NC_BYTE,NC_FLOAT):
5004        status = putNCvx_schar_float(ncp,varp,start,nelems,(float*)value);
5005        break;
5006    case CASE(NC_BYTE,NC_DOUBLE):
5007        status = putNCvx_schar_double(ncp,varp,start,nelems,(double *)value);
5008        break;
5009    case CASE(NC_BYTE,NC_INT64):
5010        status = putNCvx_schar_longlong(ncp,varp,start,nelems,(long long*)value);
5011        break;
5012
5013    case CASE(NC_SHORT,NC_BYTE):
5014        status = putNCvx_short_schar(ncp,varp,start,nelems,(signed char*)value);
5015        break;
5016    case CASE(NC_SHORT,NC_UBYTE):
5017        status = putNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value);
5018        break;
5019    case CASE(NC_SHORT,NC_SHORT):
5020        status = putNCvx_short_short(ncp,varp,start,nelems,(short*)value);
5021        break;
5022    case CASE(NC_SHORT,NC_INT):
5023        status = putNCvx_short_int(ncp,varp,start,nelems,(int*)value);
5024        break;
5025    case CASE(NC_SHORT,NC_FLOAT):
5026        status = putNCvx_short_float(ncp,varp,start,nelems,(float*)value);
5027        break;
5028    case CASE(NC_SHORT,NC_DOUBLE):
5029        status = putNCvx_short_double(ncp,varp,start,nelems,(double*)value);
5030        break;
5031    case CASE(NC_SHORT,NC_INT64):
5032        status = putNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value);
5033        break;
5034
5035    case CASE(NC_INT,NC_BYTE):
5036        status = putNCvx_int_schar(ncp,varp,start,nelems,(signed char*)value);
5037        break;
5038    case CASE(NC_INT,NC_UBYTE):
5039        status = putNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value);
5040        break;
5041    case CASE(NC_INT,NC_SHORT):
5042        status = putNCvx_int_short(ncp,varp,start,nelems,(short*)value);
5043        break;
5044    case CASE(NC_INT,NC_INT):
5045        status = putNCvx_int_int(ncp,varp,start,nelems,(int*)value);
5046        break;
5047    case CASE(NC_INT,NC_FLOAT):
5048        status = putNCvx_int_float(ncp,varp,start,nelems,(float*)value);
5049        break;
5050    case CASE(NC_INT,NC_DOUBLE):
5051        status = putNCvx_int_double(ncp,varp,start,nelems,(double*)value);
5052        break;
5053    case CASE(NC_INT,NC_INT64):
5054        status = putNCvx_int_longlong(ncp,varp,start,nelems,(long long*)value);
5055        break;
5056
5057    case CASE(NC_FLOAT,NC_BYTE):
5058        status = putNCvx_float_schar(ncp,varp,start,nelems,(signed char*)value);
5059        break;
5060    case CASE(NC_FLOAT,NC_UBYTE):
5061        status = putNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value);
5062        break;
5063    case CASE(NC_FLOAT,NC_SHORT):
5064        status = putNCvx_float_short(ncp,varp,start,nelems,(short*)value);
5065        break;
5066    case CASE(NC_FLOAT,NC_INT):
5067        status = putNCvx_float_int(ncp,varp,start,nelems,(int*)value);
5068        break;
5069    case CASE(NC_FLOAT,NC_FLOAT):
5070        status = putNCvx_float_float(ncp,varp,start,nelems,(float*)value);
5071        break;
5072    case CASE(NC_FLOAT,NC_DOUBLE):
5073        status = putNCvx_float_double(ncp,varp,start,nelems,(double*)value);
5074        break;
5075    case CASE(NC_FLOAT,NC_INT64):
5076        status = putNCvx_float_longlong(ncp,varp,start,nelems,(long long*)value);
5077        break;
5078
5079    case CASE(NC_DOUBLE,NC_BYTE):
5080        status = putNCvx_double_schar(ncp,varp,start,nelems,(signed char*)value);
5081        break;
5082    case CASE(NC_DOUBLE,NC_UBYTE):
5083        status = putNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value);
5084        break;
5085    case CASE(NC_DOUBLE,NC_SHORT):
5086        status = putNCvx_double_short(ncp,varp,start,nelems,(short*)value);
5087        break;
5088    case CASE(NC_DOUBLE,NC_INT):
5089        status = putNCvx_double_int(ncp,varp,start,nelems,(int*)value);
5090        break;
5091    case CASE(NC_DOUBLE,NC_FLOAT):
5092        status = putNCvx_double_float(ncp,varp,start,nelems,(float*)value);
5093        break;
5094    case CASE(NC_DOUBLE,NC_DOUBLE):
5095        status = putNCvx_double_double(ncp,varp,start,nelems,(double*)value);
5096        break;
5097    case CASE(NC_DOUBLE,NC_INT64):
5098        status = putNCvx_double_longlong(ncp,varp,start,nelems,(long long*)value);
5099        break;
5100
5101    default:
5102        return NC_EBADTYPE;
5103    }
5104    return status;
5105}
5106
5107/**************************************************/
5108
5109int
5110NC3_get_vara(int ncid, int varid,
5111            const size_t *start, const size_t *edges0,
5112            void *value0,
5113            nc_type memtype)
5114{
5115    int status = NC_NOERR;
5116    NC* ncp;
5117    NC_var *varp;
5118    int ii;
5119    size_t iocount;
5120    size_t memtypelen;
5121    char* value = (char*) value0; /* legally allow ptr arithmetic */
5122    const size_t* edges = edges0; /* so we can modify for special cases */
5123    size_t modedges[NC_MAX_VAR_DIMS];
5124
5125    status = NC_check_id(ncid, &ncp); 
5126    if(status != NC_NOERR)
5127        return status;
5128
5129    if(NC_indef(ncp))
5130        return NC_EINDEFINE;
5131
5132    varp = NC_lookupvar(ncp, varid);
5133    if(varp == NULL)
5134        return NC_ENOTVAR;
5135
5136    if(memtype == NC_NAT) memtype=varp->type;
5137
5138    if(memtype == NC_CHAR && varp->type != NC_CHAR)
5139        return NC_ECHAR;
5140    else if(memtype != NC_CHAR && varp->type == NC_CHAR) 
5141        return NC_ECHAR;
5142
5143    /* If edges is NULL, then this was called from nc_get_var() */
5144    if(edges == NULL && varp->ndims > 0) {
5145        /* If this is a record variable, then we have to
5146           substitute the number of records into dimension 0. */
5147        if(varp->shape[0] == 0) {
5148            (void*)memcpy((void*)modedges,(void*)varp->shape,
5149                          sizeof(size_t)*varp->ndims);
5150            modedges[0] = NC_get_numrecs(ncp);
5151            edges = modedges;
5152        } else
5153            edges = varp->shape;
5154    }
5155
5156    status = NCcoordck(ncp, varp, start);
5157    if(status != NC_NOERR)
5158        return status;
5159
5160    status = NCedgeck(ncp, varp, start, edges);
5161    if(status != NC_NOERR)
5162        return status;
5163
5164    /* Get the size of the memtype */
5165    memtypelen = nctypelen(memtype);
5166
5167    if(varp->ndims == 0) /* scalar variable */
5168    {
5169        return( readNCv(ncp, varp, start, 1, (void*)value, memtype) );
5170    }
5171
5172    if(IS_RECVAR(varp))
5173    {
5174        if(*start + *edges > NC_get_numrecs(ncp))
5175            return NC_EEDGE;
5176        if(varp->ndims == 1 && ncp->recsize <= varp->len)
5177        {
5178            /* one dimensional && the only record variable  */
5179            return( readNCv(ncp, varp, start, *edges, (void*)value, memtype) );
5180        }
5181    }
5182
5183    /*
5184     * find max contiguous
5185     *   and accumulate max count for a single io operation
5186     */
5187    ii = NCiocount(ncp, varp, edges, &iocount);
5188
5189    if(ii == -1)
5190    {
5191        return( readNCv(ncp, varp, start, iocount, (void*)value, memtype) );
5192    }
5193
5194    assert(ii >= 0);
5195
5196    { /* inline */
5197    ALLOC_ONSTACK(coord, size_t, varp->ndims);
5198    ALLOC_ONSTACK(upper, size_t, varp->ndims);
5199    const size_t index = ii;
5200
5201    /* copy in starting indices */
5202    (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
5203
5204    /* set up in maximum indices */
5205    set_upper(upper, start, edges, &upper[varp->ndims]);
5206
5207    /* ripple counter */
5208    while(*coord < *upper)
5209    {
5210        const int lstatus = readNCv(ncp, varp, coord, iocount, (void*)value, memtype);
5211        if(lstatus != NC_NOERR)
5212        {
5213            if(lstatus != NC_ERANGE)
5214            {
5215                status = lstatus;
5216                /* fatal for the loop */
5217                break;
5218            }
5219            /* else NC_ERANGE, not fatal for the loop */
5220            if(status == NC_NOERR)
5221                status = lstatus;
5222        }
5223        value += (iocount * memtypelen);
5224        odo1(start, upper, coord, &upper[index], &coord[index]);
5225    }
5226
5227    FREE_ONSTACK(upper);
5228    FREE_ONSTACK(coord);
5229    } /* end inline */
5230
5231    return status;
5232}
5233
5234int
5235NC3_put_vara(int ncid, int varid,
5236            const size_t *start, const size_t *edges0,
5237            const void *value0,
5238            nc_type memtype)
5239{
5240    int status = NC_NOERR;
5241    NC *ncp;
5242    NC_var *varp;
5243    int ii;
5244    size_t iocount;
5245    size_t memtypelen;
5246    char* value = (char*) value0; /* legally allow ptr arithmetic */
5247    const size_t* edges = edges0; /* so we can modify for special cases */
5248    size_t modedges[NC_MAX_VAR_DIMS];
5249
5250    status = NC_check_id(ncid, &ncp); 
5251    if(status != NC_NOERR)
5252        return status;
5253
5254    if(NC_readonly(ncp))
5255        return NC_EPERM;
5256
5257    if(NC_indef(ncp))
5258        return NC_EINDEFINE;
5259
5260    varp = NC_lookupvar(ncp, varid);
5261    if(varp == NULL)
5262        return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
5263
5264    if(memtype == NC_NAT) memtype=varp->type;
5265
5266    if(memtype == NC_CHAR && varp->type != NC_CHAR)
5267        return NC_ECHAR;
5268    else if(memtype != NC_CHAR && varp->type == NC_CHAR) 
5269        return NC_ECHAR;
5270
5271    /* Get the size of the memtype */
5272    memtypelen = nctypelen(memtype);
5273
5274    /* If edges is NULL, then this was called from nc_get_var() */
5275    if(edges == NULL && varp->ndims > 0) {
5276        /* If this is a record variable, then we have to
5277           substitute the number of records into dimension 0. */
5278        if(varp->shape[0] == 0) {
5279            (void*)memcpy((void*)modedges,(void*)varp->shape,
5280                          sizeof(size_t)*varp->ndims);
5281            modedges[0] = NC_get_numrecs(ncp);
5282            edges = modedges;
5283        } else
5284            edges = varp->shape;
5285    }
5286
5287    status = NCcoordck(ncp, varp, start);
5288    if(status != NC_NOERR)
5289        return status;
5290    status = NCedgeck(ncp, varp, start, edges);
5291    if(status != NC_NOERR)
5292        return status;
5293
5294    if(varp->ndims == 0) /* scalar variable */
5295    {
5296        return( writeNCv(ncp, varp, start, 1, (void*)value, memtype) );
5297    }
5298
5299    if(IS_RECVAR(varp))
5300    {
5301        status = NCvnrecs(ncp, *start + *edges);
5302        if(status != NC_NOERR)
5303            return status;
5304
5305        if(varp->ndims == 1
5306            && ncp->recsize <= varp->len)
5307        {
5308            /* one dimensional && the only record variable  */
5309            return( writeNCv(ncp, varp, start, *edges, (void*)value, memtype) );
5310        }
5311    }
5312
5313    /*
5314     * find max contiguous
5315     *   and accumulate max count for a single io operation
5316     */
5317    ii = NCiocount(ncp, varp, edges, &iocount);
5318
5319    if(ii == -1)
5320    {
5321        return( writeNCv(ncp, varp, start, iocount, (void*)value, memtype) );
5322    }
5323
5324    assert(ii >= 0);
5325
5326    { /* inline */
5327    ALLOC_ONSTACK(coord, size_t, varp->ndims);
5328    ALLOC_ONSTACK(upper, size_t, varp->ndims);
5329    const size_t index = ii;
5330
5331    /* copy in starting indices */
5332    (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
5333
5334    /* set up in maximum indices */
5335    set_upper(upper, start, edges, &upper[varp->ndims]);
5336
5337    /* ripple counter */
5338    while(*coord < *upper)
5339    {
5340        const int lstatus = writeNCv(ncp, varp, coord, iocount, (void*)value, memtype);
5341        if(lstatus != NC_NOERR)
5342        {
5343            if(lstatus != NC_ERANGE)
5344            {
5345                status = lstatus;
5346                /* fatal for the loop */
5347                break;
5348            }
5349            /* else NC_ERANGE, not fatal for the loop */
5350            if(status == NC_NOERR)
5351                status = lstatus;
5352        }
5353        value += (iocount * memtypelen);
5354        odo1(start, upper, coord, &upper[index], &coord[index]);
5355    }
5356
5357    FREE_ONSTACK(upper);
5358    FREE_ONSTACK(coord);
5359    } /* end inline */
5360
5361    return status;
5362}
Note: See TracBrowser for help on using the repository browser.