ncdf4a13/libsrc/putget.c

Go to the documentation of this file.
00001 /* Do not edit this file. It is produced from the corresponding .m4 source */
00002 /*
00003  *      Copyright 1996, University Corporation for Atmospheric Research
00004  *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
00005  */
00006 /* $Id: putget.m4,v 2.60 2006/01/03 20:20:07 russ Exp $ */
00007 
00008 #include "nc.h"
00009 #include <string.h>
00010 #include <stdlib.h>
00011 #include <assert.h>
00012 #include "ncx.h"
00013 #include "fbits.h"
00014 #include "onstack.h"
00015 #ifdef LOCKNUMREC
00016 #  include <mpp/shmem.h>        /* for SGI/Cray SHMEM routines */
00017 #  ifdef LN_TEST
00018 #    include <stdio.h>
00019 #  endif
00020 #endif
00021 
00022 #undef MIN  /* system may define MIN somewhere and complain */
00023 #define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
00024 
00025 /* #define ODEBUG 1 */
00026 
00027 #if ODEBUG
00028 #include <stdio.h>
00029 /*
00030  * Print the values of an array of size_t
00031  */
00032 void
00033 arrayp(const char *label, size_t count, const size_t *array)
00034 {
00035         (void) fprintf(stderr, "%s", label);
00036         (void) fputc('\t',stderr);      
00037         for(; count > 0; count--, array++)
00038                 (void) fprintf(stderr," %lu", (unsigned long)*array);
00039         (void) fputc('\n',stderr);      
00040 }
00041 #endif /* ODEBUG */
00042 
00043 /*
00044  *  This is how much space is required by the user, as in
00045  *
00046  *   vals = malloc(nel * nctypelen(var.type));
00047  *   ncvarget(cdfid, varid, cor, edg, vals);
00048  */
00049 int
00050 nctypelen(nc_type type) 
00051 {
00052         switch(type){
00053         case NC_BYTE :
00054         case NC_CHAR :
00055                 return((int)sizeof(char));
00056         case NC_SHORT :
00057                 return(int)(sizeof(short));
00058         case NC_INT :
00059                 return((int)sizeof(int));
00060         case NC_FLOAT :
00061                 return((int)sizeof(float));
00062         case NC_DOUBLE : 
00063                 return((int)sizeof(double));
00064         }
00065 
00066         return -1;
00067 }
00068 
00069 
00070 /* Begin fill */
00071 /*
00072  * This is tunable parameter.
00073  * It essentially controls the tradeoff between the number of times
00074  * memcpy() gets called to copy the external data to fill 
00075  * a large buffer vs the number of times its called to
00076  * prepare the external data.
00077  */
00078 #if     _SX
00079 /* NEC SX specific optimization */
00080 #define NFILL   2048
00081 #else
00082 #define NFILL   16
00083 #endif
00084 
00085 
00086 
00087 /*
00088  * Next 6 type specific functions
00089  * Fill a some memory with the default special value.
00090  * Formerly
00091 NC_arrayfill()
00092  */
00093 static int
00094 NC_fill_schar(
00095         void **xpp,
00096         size_t nelems)  /* how many */
00097 {
00098         schar fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];
00099 
00100         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00101 
00102         {
00103                 schar *vp = fillp;      /* lower bound of area to be filled */
00104                 const schar *const end = vp + nelems;
00105                 while(vp < end)
00106                 {
00107                         *vp++ = NC_FILL_BYTE;
00108                 }
00109         }
00110         return ncx_putn_schar_schar(xpp, nelems, fillp);
00111 }
00112 
00113 static int
00114 NC_fill_char(
00115         void **xpp,
00116         size_t nelems)  /* how many */
00117 {
00118         char fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];
00119 
00120         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00121 
00122         {
00123                 char *vp = fillp;       /* lower bound of area to be filled */
00124                 const char *const end = vp + nelems;
00125                 while(vp < end)
00126                 {
00127                         *vp++ = NC_FILL_CHAR;
00128                 }
00129         }
00130         return ncx_putn_char_char(xpp, nelems, fillp);
00131 }
00132 
00133 static int
00134 NC_fill_short(
00135         void **xpp,
00136         size_t nelems)  /* how many */
00137 {
00138         short fillp[NFILL * sizeof(double)/X_SIZEOF_SHORT];
00139 
00140         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00141 
00142         {
00143                 short *vp = fillp;      /* lower bound of area to be filled */
00144                 const short *const end = vp + nelems;
00145                 while(vp < end)
00146                 {
00147                         *vp++ = NC_FILL_SHORT;
00148                 }
00149         }
00150         return ncx_putn_short_short(xpp, nelems, fillp);
00151 }
00152 
00153 
00154 #if (SIZEOF_INT >= X_SIZEOF_INT)
00155 static int
00156 NC_fill_int(
00157         void **xpp,
00158         size_t nelems)  /* how many */
00159 {
00160         int fillp[NFILL * sizeof(double)/X_SIZEOF_INT];
00161 
00162         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00163 
00164         {
00165                 int *vp = fillp;        /* lower bound of area to be filled */
00166                 const int *const end = vp + nelems;
00167                 while(vp < end)
00168                 {
00169                         *vp++ = NC_FILL_INT;
00170                 }
00171         }
00172         return ncx_putn_int_int(xpp, nelems, fillp);
00173 }
00174 
00175 #elif SIZEOF_LONG == X_SIZEOF_INT
00176 static int
00177 NC_fill_int(
00178         void **xpp,
00179         size_t nelems)  /* how many */
00180 {
00181         long fillp[NFILL * sizeof(double)/X_SIZEOF_INT];
00182 
00183         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00184 
00185         {
00186                 long *vp = fillp;       /* lower bound of area to be filled */
00187                 const long *const end = vp + nelems;
00188                 while(vp < end)
00189                 {
00190                         *vp++ = NC_FILL_INT;
00191                 }
00192         }
00193         return ncx_putn_int_long(xpp, nelems, fillp);
00194 }
00195 
00196 #else
00197 #error "NC_fill_int implementation"
00198 #endif
00199 
00200 static int
00201 NC_fill_float(
00202         void **xpp,
00203         size_t nelems)  /* how many */
00204 {
00205         float fillp[NFILL * sizeof(double)/X_SIZEOF_FLOAT];
00206 
00207         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00208 
00209         {
00210                 float *vp = fillp;      /* lower bound of area to be filled */
00211                 const float *const end = vp + nelems;
00212                 while(vp < end)
00213                 {
00214                         *vp++ = NC_FILL_FLOAT;
00215                 }
00216         }
00217         return ncx_putn_float_float(xpp, nelems, fillp);
00218 }
00219 
00220 static int
00221 NC_fill_double(
00222         void **xpp,
00223         size_t nelems)  /* how many */
00224 {
00225         double fillp[NFILL * sizeof(double)/X_SIZEOF_DOUBLE];
00226 
00227         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00228 
00229         {
00230                 double *vp = fillp;     /* lower bound of area to be filled */
00231                 const double *const end = vp + nelems;
00232                 while(vp < end)
00233                 {
00234                         *vp++ = NC_FILL_DOUBLE;
00235                 }
00236         }
00237         return ncx_putn_double_double(xpp, nelems, fillp);
00238 }
00239 
00240 
00241 
00242 /*
00243  * Fill the external space for variable 'varp' values at 'recno'
00244  * with the appropriate value. If 'varp' is not a record
00245  * variable, fill the whole thing.
00246  * Formerly
00247 xdr_NC_fill()
00248  */
00249 int
00250 fill_NC_var(NC *ncp, const NC_var *varp, size_t recno)
00251 {
00252         char xfillp[NFILL * X_SIZEOF_DOUBLE];
00253         const size_t step = varp->xsz;
00254         const size_t nelems = sizeof(xfillp)/step;
00255         const size_t xsz = varp->xsz * nelems;
00256         NC_attr **attrpp = NULL;
00257         off_t offset;
00258         size_t remaining = varp->len;
00259 
00260         void *xp;
00261         int status = NC_NOERR;
00262 
00263         /*
00264          * Set up fill value
00265          */
00266         attrpp = NC_findattr(&varp->attrs, _FillValue);
00267         if( attrpp != NULL )
00268         {
00269                 /* User defined fill value */
00270                 if( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 )
00271                 {
00272                         return NC_EBADTYPE;
00273                 }
00274                 else
00275                 {
00276                         /* Use the user defined value */
00277                         char *cp = xfillp;
00278                         const char *const end = &xfillp[sizeof(xfillp)];
00279 
00280                         assert(step <= (*attrpp)->xsz);
00281 
00282                         for( /*NADA*/; cp < end; cp += step)
00283                         {
00284                                 (void) memcpy(cp, (*attrpp)->xvalue, step);
00285                         }
00286                 }
00287         }
00288         else
00289         {
00290                 /* use the default */
00291                 
00292                 assert(xsz % X_ALIGN == 0);
00293                 assert(xsz <= sizeof(xfillp));
00294         
00295                 xp = xfillp;
00296         
00297                 switch(varp->type){
00298                 case NC_BYTE :
00299                         status = NC_fill_schar(&xp, nelems);
00300                         break;
00301                 case NC_CHAR :
00302                         status = NC_fill_char(&xp, nelems);
00303                         break;
00304                 case NC_SHORT :
00305                         status = NC_fill_short(&xp, nelems);
00306                         break;
00307                 case NC_INT :
00308                         status = NC_fill_int(&xp, nelems);
00309                         break;
00310                 case NC_FLOAT :
00311                         status = NC_fill_float(&xp, nelems);
00312                         break;
00313                 case NC_DOUBLE : 
00314                         status = NC_fill_double(&xp, nelems);
00315                         break;
00316                 default :
00317                         assert("fill_NC_var invalid type" == 0);
00318                         status = NC_EBADTYPE;
00319                         break;
00320                 }
00321                 if(status != NC_NOERR)
00322                         return status;
00323         
00324                 assert(xp == xfillp + xsz);
00325         }
00326 
00327         /*
00328          * copyout:
00329          * xfillp now contains 'nelems' elements of the fill value
00330          * in external representation.
00331          */
00332 
00333         /*
00334          * Copy it out.
00335          */
00336 
00337         offset = varp->begin;
00338         if(IS_RECVAR(varp))
00339         {
00340                 offset += (off_t)ncp->recsize * recno;
00341         }
00342 
00343         assert(remaining > 0);
00344         for(;;)
00345         {
00346                 const size_t chunksz = MIN(remaining, ncp->chunk);
00347                 size_t ii;
00348                 assert(chunksz % X_ALIGN == 0);
00349 
00350                 status = ncp->nciop->get(ncp->nciop, offset, chunksz,
00351                                  RGN_WRITE, &xp);       
00352                 if(status != NC_NOERR)
00353                 {
00354                         return status;
00355                 }
00356 
00357                 /*
00358                  * fill the chunksz buffer in units  of xsz
00359                  */
00360                 for(ii = 0; ii < chunksz/xsz; ii++)
00361                 {
00362                         (void) memcpy(xp, xfillp, xsz);
00363                         xp = (char *)xp + xsz;
00364                 }
00365                 /*
00366                  * Deal with any remainder
00367                  */
00368                 {
00369                         const size_t rem = chunksz % xsz;
00370                         if(rem != 0)
00371                         {
00372                                 (void) memcpy(xp, xfillp, rem);
00373                                 /* xp = (char *)xp + xsz; */
00374                         }
00375 
00376                 }
00377 
00378                 status = ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED);
00379 
00380                 if(status != NC_NOERR)
00381                 {
00382                         break;
00383                 }
00384 
00385                 remaining -= chunksz;
00386                 if(remaining == 0)
00387                         break;  /* normal loop exit */
00388                 offset += chunksz;
00389 
00390         }
00391 
00392         return status;
00393 }
00394 /* End fill */
00395 
00396 
00397 /*
00398  * Add a record containing the fill values.
00399  */
00400 static int
00401 NCfillrecord(NC *ncp, const NC_var *const *varpp, size_t recno)
00402 {
00403         size_t ii = 0;
00404         for(; ii < ncp->vars.nelems; ii++, varpp++)
00405         {
00406                 if( !IS_RECVAR(*varpp) )
00407                 {
00408                         continue;       /* skip non-record variables */
00409                 }
00410                 {
00411                 const int status = fill_NC_var(ncp, *varpp, recno);
00412                 if(status != NC_NOERR)
00413                         return status;
00414                 }
00415         }
00416         return NC_NOERR;
00417 }
00418 
00419 /*
00420  * It is advantageous to
00421  * #define TOUCH_LAST
00422  * when using memory mapped io.
00423  */
00424 #if TOUCH_LAST
00425 /*
00426  * Grow the file to a size which can contain recno
00427  */
00428 static int
00429 NCtouchlast(NC *ncp, const NC_var *const *varpp, size_t recno)
00430 {
00431         int status = NC_NOERR;
00432         const NC_var *varp = NULL;
00433         
00434         {
00435         size_t ii = 0;
00436         for(; ii < ncp->vars.nelems; ii++, varpp++)
00437         {
00438                 if( !IS_RECVAR(*varpp) )
00439                 {
00440                         continue;       /* skip non-record variables */
00441                 }
00442                 varp = *varpp;
00443         }
00444         }
00445         assert(varp != NULL);
00446         assert( IS_RECVAR(varp) );
00447         {
00448                 const off_t offset = varp->begin
00449                                 + (off_t)(recno-1) * (off_t)ncp->recsize
00450                                 + (off_t)(varp->len - varp->xsz);
00451                 void *xp;
00452 
00453 
00454                 status = ncp->nciop->get(ncp->nciop, offset, varp->xsz,
00455                                  RGN_WRITE, &xp);       
00456                 if(status != NC_NOERR)
00457                         return status;
00458                 (void)memset(xp, 0, varp->xsz);
00459                 status = ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED);
00460         }
00461         return status;
00462 }
00463 #endif /* TOUCH_LAST */
00464 
00465 
00466 /*
00467  * Ensure that the netcdf file has 'numrecs' records,
00468  * add records and fill as neccessary.
00469  */
00470 static int
00471 NCvnrecs(NC *ncp, size_t numrecs)
00472 {
00473         int status = NC_NOERR;
00474 #ifdef LOCKNUMREC
00475         ushmem_t myticket = 0, nowserving = 0;
00476         ushmem_t numpe = (ushmem_t) _num_pes();
00477 
00478         /* get ticket and wait */
00479         myticket = shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
00480                 ncp->lock[LOCKNUMREC_BASEPE]);
00481 #ifdef LN_TEST
00482                 fprintf(stderr,"%d of %d : ticket = %hu\n",
00483                         _my_pe(), _num_pes(), myticket);
00484 #endif
00485         do {
00486                 shmem_short_get((shmem_t *) &nowserving,
00487                         (shmem_t *) ncp->lock + LOCKNUMREC_SERVING, 1,
00488                         ncp->lock[LOCKNUMREC_BASEPE]);
00489 #ifdef LN_TEST
00490                 fprintf(stderr,"%d of %d : serving = %hu\n",
00491                         _my_pe(), _num_pes(), nowserving);
00492 #endif
00493                 /* work-around for non-unique tickets */
00494                 if (nowserving > myticket && nowserving < myticket + numpe ) {
00495                         /* get a new ticket ... you've been bypassed */ 
00496                         /* and handle the unlikely wrap-around effect */
00497                         myticket = shmem_short_finc(
00498                                 (shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
00499                                 ncp->lock[LOCKNUMREC_BASEPE]);
00500 #ifdef LN_TEST
00501                                 fprintf(stderr,"%d of %d : new ticket = %hu\n",
00502                                         _my_pe(), _num_pes(), myticket);
00503 #endif
00504                 }
00505         } while(nowserving != myticket);
00506         /* now our turn to check & update value */
00507 #endif
00508 
00509         if(numrecs > NC_get_numrecs(ncp))
00510         {
00511 
00512 
00513 #if TOUCH_LAST
00514                 status = NCtouchlast(ncp,
00515                         (const NC_var *const*)ncp->vars.value,
00516                         numrecs);
00517                 if(status != NC_NOERR)
00518                         goto common_return;
00519 #endif /* TOUCH_LAST */
00520 
00521                 set_NC_ndirty(ncp);
00522 
00523                 if(!NC_dofill(ncp))
00524                 {
00525                         /* Simply set the new numrecs value */
00526                         NC_set_numrecs(ncp, numrecs);
00527                 }
00528                 else
00529                 {
00530                         /* Fill each record out to numrecs */
00531                         size_t cur_nrecs;
00532                         while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs)
00533                         {
00534                                 status = NCfillrecord(ncp,
00535                                         (const NC_var *const*)ncp->vars.value,
00536                                         cur_nrecs);
00537                                 if(status != NC_NOERR)
00538                                 {
00539                                         break;
00540                                 }
00541                                 NC_increase_numrecs(ncp, cur_nrecs +1);
00542                         }
00543                         if(status != NC_NOERR)
00544                                 goto common_return;
00545                 }
00546 
00547                 if(NC_doNsync(ncp))
00548                 {
00549                         status = write_numrecs(ncp);
00550                 }
00551 
00552         }
00553 common_return:
00554 #ifdef LOCKNUMREC
00555         /* finished with our lock - increment serving number */
00556         (void) shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_SERVING,
00557                 ncp->lock[LOCKNUMREC_BASEPE]);
00558 #endif
00559         return status;
00560 }
00561 
00562 
00563 /* 
00564  * Check whether 'coord' values are valid for the variable.
00565  */
00566 static int
00567 NCcoordck(NC *ncp, const NC_var *varp, const size_t *coord)
00568 {
00569         const size_t *ip;
00570         size_t *up;
00571 
00572         if(varp->ndims == 0)
00573                 return NC_NOERR;        /* 'scalar' variable */
00574 
00575         if(IS_RECVAR(varp))
00576         {
00577                 if(*coord > X_INT_MAX)
00578                         return NC_EINVALCOORDS; /* sanity check */
00579                 if(NC_readonly(ncp) && *coord >= NC_get_numrecs(ncp))
00580                 {
00581                         if(!NC_doNsync(ncp))
00582                                 return NC_EINVALCOORDS;
00583                         /* else */
00584                         {
00585                                 /* Update from disk and check again */
00586                                 const int status = read_numrecs(ncp);
00587                                 if(status != NC_NOERR)
00588                                         return status;
00589                                 if(*coord >= NC_get_numrecs(ncp))
00590                                         return NC_EINVALCOORDS;
00591                         }
00592                 }
00593                 ip = coord + 1;
00594                 up = varp->shape + 1;
00595         }
00596         else
00597         {
00598                 ip = coord;
00599                 up = varp->shape;
00600         }
00601         
00602 #ifdef CDEBUG
00603 fprintf(stderr,"        NCcoordck: coord %ld, count %d, ip %ld\n",
00604                 coord, varp->ndims, ip );
00605 #endif /* CDEBUG */
00606 
00607         for(; ip < coord + varp->ndims; ip++, up++)
00608         {
00609 
00610 #ifdef CDEBUG
00611 fprintf(stderr,"        NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n",
00612                         ip, *ip, up, *up );
00613 #endif /* CDEBUG */
00614 
00615                 /* cast needed for braindead systems with signed size_t */
00616                 if((unsigned long) *ip >= (unsigned long) *up )
00617                         return NC_EINVALCOORDS;
00618         }
00619 
00620         return NC_NOERR;
00621 }
00622 
00623 
00624 /* 
00625  * Check whether 'edges' are valid for the variable and 'start'
00626  */
00627 /*ARGSUSED*/
00628 static int
00629 NCedgeck(const NC *ncp, const NC_var *varp,
00630          const size_t *start, const size_t *edges)
00631 {
00632         const size_t *const end = start + varp->ndims;
00633         const size_t *shp = varp->shape;
00634 
00635         if(varp->ndims == 0)
00636                 return NC_NOERR;        /* 'scalar' variable */
00637 
00638         if(IS_RECVAR(varp))
00639         {
00640                 start++;
00641                 edges++;
00642                 shp++;
00643         }
00644 
00645         for(; start < end; start++, edges++, shp++)
00646         {
00647                 /* cast needed for braindead systems with signed size_t */
00648                 if((unsigned long) *edges > *shp ||
00649                         (unsigned long) *start + (unsigned long) *edges > *shp)
00650                 {
00651                         return(NC_EEDGE);
00652                 }
00653         }
00654         return NC_NOERR;
00655 }
00656 
00657 
00658 /* 
00659  * Translate the (variable, coord) pair into a seek index
00660  */
00661 static off_t
00662 NC_varoffset(const NC *ncp, const NC_var *varp, const size_t *coord)
00663 {
00664         if(varp->ndims == 0) /* 'scalar' variable */
00665                 return varp->begin;
00666 
00667         if(varp->ndims == 1)
00668         {
00669                 if(IS_RECVAR(varp))
00670                         return varp->begin +
00671                                  (off_t)(*coord) * (off_t)ncp->recsize;
00672                 /* else */
00673                 return varp->begin + (off_t)(*coord) * (off_t)varp->xsz;
00674         }
00675         /* else */
00676         {
00677                 off_t lcoord = (off_t)coord[varp->ndims -1];
00678 
00679                 size_t *up = varp->dsizes +1;
00680                 const size_t *ip = coord;
00681                 const size_t *const end = varp->dsizes + varp->ndims;
00682                 
00683                 if(IS_RECVAR(varp))
00684                         up++, ip++;
00685 
00686                 for(; up < end; up++, ip++)
00687                         lcoord += *up * *ip;
00688 
00689                 lcoord *= varp->xsz;
00690                 
00691                 if(IS_RECVAR(varp))
00692                         lcoord += (off_t)(*coord) * ncp->recsize;
00693                 
00694                 lcoord += varp->begin;
00695                 return lcoord;
00696         }
00697 }
00698 
00699 
00700 
00701 static int
00702 putNCvx_char_char(NC *ncp, const NC_var *varp,
00703                  const size_t *start, size_t nelems, const char *value)
00704 {
00705         off_t offset = NC_varoffset(ncp, varp, start);
00706         size_t remaining = varp->xsz * nelems;
00707         int status = NC_NOERR;
00708         void *xp;
00709 
00710         if(nelems == 0)
00711                 return NC_NOERR;
00712 
00713         assert(value != NULL);
00714 
00715         for(;;)
00716         {
00717                 size_t extent = MIN(remaining, ncp->chunk);
00718                 size_t nput = ncx_howmany(varp->type, extent);
00719 
00720                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00721                                  RGN_WRITE, &xp);       
00722                 if(lstatus != NC_NOERR)
00723                         return lstatus;
00724                 
00725                 lstatus = ncx_putn_char_char(&xp, nput, value);
00726                 if(lstatus != NC_NOERR && status == NC_NOERR)
00727                 {
00728                         /* not fatal to the loop */
00729                         status = lstatus;
00730                 }
00731 
00732                 (void) ncp->nciop->rel(ncp->nciop, offset,
00733                                  RGN_MODIFIED); 
00734 
00735                 remaining -= extent;
00736                 if(remaining == 0)
00737                         break; /* normal loop exit */
00738                 offset += extent;
00739                 value += nput;
00740 
00741         }
00742 
00743         return status;
00744 }
00745 
00746 
00747 static int
00748 putNCvx_schar_schar(NC *ncp, const NC_var *varp,
00749                  const size_t *start, size_t nelems, const schar *value)
00750 {
00751         off_t offset = NC_varoffset(ncp, varp, start);
00752         size_t remaining = varp->xsz * nelems;
00753         int status = NC_NOERR;
00754         void *xp;
00755 
00756         if(nelems == 0)
00757                 return NC_NOERR;
00758 
00759         assert(value != NULL);
00760 
00761         for(;;)
00762         {
00763                 size_t extent = MIN(remaining, ncp->chunk);
00764                 size_t nput = ncx_howmany(varp->type, extent);
00765 
00766                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00767                                  RGN_WRITE, &xp);       
00768                 if(lstatus != NC_NOERR)
00769                         return lstatus;
00770                 
00771                 lstatus = ncx_putn_schar_schar(&xp, nput, value);
00772                 if(lstatus != NC_NOERR && status == NC_NOERR)
00773                 {
00774                         /* not fatal to the loop */
00775                         status = lstatus;
00776                 }
00777 
00778                 (void) ncp->nciop->rel(ncp->nciop, offset,
00779                                  RGN_MODIFIED); 
00780 
00781                 remaining -= extent;
00782                 if(remaining == 0)
00783                         break; /* normal loop exit */
00784                 offset += extent;
00785                 value += nput;
00786 
00787         }
00788 
00789         return status;
00790 }
00791 
00792 static int
00793 putNCvx_schar_uchar(NC *ncp, const NC_var *varp,
00794                  const size_t *start, size_t nelems, const uchar *value)
00795 {
00796         off_t offset = NC_varoffset(ncp, varp, start);
00797         size_t remaining = varp->xsz * nelems;
00798         int status = NC_NOERR;
00799         void *xp;
00800 
00801         if(nelems == 0)
00802                 return NC_NOERR;
00803 
00804         assert(value != NULL);
00805 
00806         for(;;)
00807         {
00808                 size_t extent = MIN(remaining, ncp->chunk);
00809                 size_t nput = ncx_howmany(varp->type, extent);
00810 
00811                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00812                                  RGN_WRITE, &xp);       
00813                 if(lstatus != NC_NOERR)
00814                         return lstatus;
00815                 
00816                 lstatus = ncx_putn_schar_uchar(&xp, nput, value);
00817                 if(lstatus != NC_NOERR && status == NC_NOERR)
00818                 {
00819                         /* not fatal to the loop */
00820                         status = lstatus;
00821                 }
00822 
00823                 (void) ncp->nciop->rel(ncp->nciop, offset,
00824                                  RGN_MODIFIED); 
00825 
00826                 remaining -= extent;
00827                 if(remaining == 0)
00828                         break; /* normal loop exit */
00829                 offset += extent;
00830                 value += nput;
00831 
00832         }
00833 
00834         return status;
00835 }
00836 
00837 static int
00838 putNCvx_schar_short(NC *ncp, const NC_var *varp,
00839                  const size_t *start, size_t nelems, const short *value)
00840 {
00841         off_t offset = NC_varoffset(ncp, varp, start);
00842         size_t remaining = varp->xsz * nelems;
00843         int status = NC_NOERR;
00844         void *xp;
00845 
00846         if(nelems == 0)
00847                 return NC_NOERR;
00848 
00849         assert(value != NULL);
00850 
00851         for(;;)
00852         {
00853                 size_t extent = MIN(remaining, ncp->chunk);
00854                 size_t nput = ncx_howmany(varp->type, extent);
00855 
00856                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00857                                  RGN_WRITE, &xp);       
00858                 if(lstatus != NC_NOERR)
00859                         return lstatus;
00860                 
00861                 lstatus = ncx_putn_schar_short(&xp, nput, value);
00862                 if(lstatus != NC_NOERR && status == NC_NOERR)
00863                 {
00864                         /* not fatal to the loop */
00865                         status = lstatus;
00866                 }
00867 
00868                 (void) ncp->nciop->rel(ncp->nciop, offset,
00869                                  RGN_MODIFIED); 
00870 
00871                 remaining -= extent;
00872                 if(remaining == 0)
00873                         break; /* normal loop exit */
00874                 offset += extent;
00875                 value += nput;
00876 
00877         }
00878 
00879         return status;
00880 }
00881 
00882 static int
00883 putNCvx_schar_int(NC *ncp, const NC_var *varp,
00884                  const size_t *start, size_t nelems, const int *value)
00885 {
00886         off_t offset = NC_varoffset(ncp, varp, start);
00887         size_t remaining = varp->xsz * nelems;
00888         int status = NC_NOERR;
00889         void *xp;
00890 
00891         if(nelems == 0)
00892                 return NC_NOERR;
00893 
00894         assert(value != NULL);
00895 
00896         for(;;)
00897         {
00898                 size_t extent = MIN(remaining, ncp->chunk);
00899                 size_t nput = ncx_howmany(varp->type, extent);
00900 
00901                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00902                                  RGN_WRITE, &xp);       
00903                 if(lstatus != NC_NOERR)
00904                         return lstatus;
00905                 
00906                 lstatus = ncx_putn_schar_int(&xp, nput, value);
00907                 if(lstatus != NC_NOERR && status == NC_NOERR)
00908                 {
00909                         /* not fatal to the loop */
00910                         status = lstatus;
00911                 }
00912 
00913                 (void) ncp->nciop->rel(ncp->nciop, offset,
00914                                  RGN_MODIFIED); 
00915 
00916                 remaining -= extent;
00917                 if(remaining == 0)
00918                         break; /* normal loop exit */
00919                 offset += extent;
00920                 value += nput;
00921 
00922         }
00923 
00924         return status;
00925 }
00926 
00927 static int
00928 putNCvx_schar_long(NC *ncp, const NC_var *varp,
00929                  const size_t *start, size_t nelems, const long *value)
00930 {
00931         off_t offset = NC_varoffset(ncp, varp, start);
00932         size_t remaining = varp->xsz * nelems;
00933         int status = NC_NOERR;
00934         void *xp;
00935 
00936         if(nelems == 0)
00937                 return NC_NOERR;
00938 
00939         assert(value != NULL);
00940 
00941         for(;;)
00942         {
00943                 size_t extent = MIN(remaining, ncp->chunk);
00944                 size_t nput = ncx_howmany(varp->type, extent);
00945 
00946                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00947                                  RGN_WRITE, &xp);       
00948                 if(lstatus != NC_NOERR)
00949                         return lstatus;
00950                 
00951                 lstatus = ncx_putn_schar_long(&xp, nput, value);
00952                 if(lstatus != NC_NOERR && status == NC_NOERR)
00953                 {
00954                         /* not fatal to the loop */
00955                         status = lstatus;
00956                 }
00957 
00958                 (void) ncp->nciop->rel(ncp->nciop, offset,
00959                                  RGN_MODIFIED); 
00960 
00961                 remaining -= extent;
00962                 if(remaining == 0)
00963                         break; /* normal loop exit */
00964                 offset += extent;
00965                 value += nput;
00966 
00967         }
00968 
00969         return status;
00970 }
00971 
00972 static int
00973 putNCvx_schar_float(NC *ncp, const NC_var *varp,
00974                  const size_t *start, size_t nelems, const float *value)
00975 {
00976         off_t offset = NC_varoffset(ncp, varp, start);
00977         size_t remaining = varp->xsz * nelems;
00978         int status = NC_NOERR;
00979         void *xp;
00980 
00981         if(nelems == 0)
00982                 return NC_NOERR;
00983 
00984         assert(value != NULL);
00985 
00986         for(;;)
00987         {
00988                 size_t extent = MIN(remaining, ncp->chunk);
00989                 size_t nput = ncx_howmany(varp->type, extent);
00990 
00991                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00992                                  RGN_WRITE, &xp);       
00993                 if(lstatus != NC_NOERR)
00994                         return lstatus;
00995                 
00996                 lstatus = ncx_putn_schar_float(&xp, nput, value);
00997                 if(lstatus != NC_NOERR && status == NC_NOERR)
00998                 {
00999                         /* not fatal to the loop */
01000                         status = lstatus;
01001                 }
01002 
01003                 (void) ncp->nciop->rel(ncp->nciop, offset,
01004                                  RGN_MODIFIED); 
01005 
01006                 remaining -= extent;
01007                 if(remaining == 0)
01008                         break; /* normal loop exit */
01009                 offset += extent;
01010                 value += nput;
01011 
01012         }
01013 
01014         return status;
01015 }
01016 
01017 static int
01018 putNCvx_schar_double(NC *ncp, const NC_var *varp,
01019                  const size_t *start, size_t nelems, const double *value)
01020 {
01021         off_t offset = NC_varoffset(ncp, varp, start);
01022         size_t remaining = varp->xsz * nelems;
01023         int status = NC_NOERR;
01024         void *xp;
01025 
01026         if(nelems == 0)
01027                 return NC_NOERR;
01028 
01029         assert(value != NULL);
01030 
01031         for(;;)
01032         {
01033                 size_t extent = MIN(remaining, ncp->chunk);
01034                 size_t nput = ncx_howmany(varp->type, extent);
01035 
01036                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01037                                  RGN_WRITE, &xp);       
01038                 if(lstatus != NC_NOERR)
01039                         return lstatus;
01040                 
01041                 lstatus = ncx_putn_schar_double(&xp, nput, value);
01042                 if(lstatus != NC_NOERR && status == NC_NOERR)
01043                 {
01044                         /* not fatal to the loop */
01045                         status = lstatus;
01046                 }
01047 
01048                 (void) ncp->nciop->rel(ncp->nciop, offset,
01049                                  RGN_MODIFIED); 
01050 
01051                 remaining -= extent;
01052                 if(remaining == 0)
01053                         break; /* normal loop exit */
01054                 offset += extent;
01055                 value += nput;
01056 
01057         }
01058 
01059         return status;
01060 }
01061 
01062 
01063 static int
01064 putNCvx_short_schar(NC *ncp, const NC_var *varp,
01065                  const size_t *start, size_t nelems, const schar *value)
01066 {
01067         off_t offset = NC_varoffset(ncp, varp, start);
01068         size_t remaining = varp->xsz * nelems;
01069         int status = NC_NOERR;
01070         void *xp;
01071 
01072         if(nelems == 0)
01073                 return NC_NOERR;
01074 
01075         assert(value != NULL);
01076 
01077         for(;;)
01078         {
01079                 size_t extent = MIN(remaining, ncp->chunk);
01080                 size_t nput = ncx_howmany(varp->type, extent);
01081 
01082                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01083                                  RGN_WRITE, &xp);       
01084                 if(lstatus != NC_NOERR)
01085                         return lstatus;
01086                 
01087                 lstatus = ncx_putn_short_schar(&xp, nput, value);
01088                 if(lstatus != NC_NOERR && status == NC_NOERR)
01089                 {
01090                         /* not fatal to the loop */
01091                         status = lstatus;
01092                 }
01093 
01094                 (void) ncp->nciop->rel(ncp->nciop, offset,
01095                                  RGN_MODIFIED); 
01096 
01097                 remaining -= extent;
01098                 if(remaining == 0)
01099                         break; /* normal loop exit */
01100                 offset += extent;
01101                 value += nput;
01102 
01103         }
01104 
01105         return status;
01106 }
01107 
01108 static int
01109 putNCvx_short_uchar(NC *ncp, const NC_var *varp,
01110                  const size_t *start, size_t nelems, const uchar *value)
01111 {
01112         off_t offset = NC_varoffset(ncp, varp, start);
01113         size_t remaining = varp->xsz * nelems;
01114         int status = NC_NOERR;
01115         void *xp;
01116 
01117         if(nelems == 0)
01118                 return NC_NOERR;
01119 
01120         assert(value != NULL);
01121 
01122         for(;;)
01123         {
01124                 size_t extent = MIN(remaining, ncp->chunk);
01125                 size_t nput = ncx_howmany(varp->type, extent);
01126 
01127                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01128                                  RGN_WRITE, &xp);       
01129                 if(lstatus != NC_NOERR)
01130                         return lstatus;
01131                 
01132                 lstatus = ncx_putn_short_uchar(&xp, nput, value);
01133                 if(lstatus != NC_NOERR && status == NC_NOERR)
01134                 {
01135                         /* not fatal to the loop */
01136                         status = lstatus;
01137                 }
01138 
01139                 (void) ncp->nciop->rel(ncp->nciop, offset,
01140                                  RGN_MODIFIED); 
01141 
01142                 remaining -= extent;
01143                 if(remaining == 0)
01144                         break; /* normal loop exit */
01145                 offset += extent;
01146                 value += nput;
01147 
01148         }
01149 
01150         return status;
01151 }
01152 
01153 static int
01154 putNCvx_short_short(NC *ncp, const NC_var *varp,
01155                  const size_t *start, size_t nelems, const short *value)
01156 {
01157         off_t offset = NC_varoffset(ncp, varp, start);
01158         size_t remaining = varp->xsz * nelems;
01159         int status = NC_NOERR;
01160         void *xp;
01161 
01162         if(nelems == 0)
01163                 return NC_NOERR;
01164 
01165         assert(value != NULL);
01166 
01167         for(;;)
01168         {
01169                 size_t extent = MIN(remaining, ncp->chunk);
01170                 size_t nput = ncx_howmany(varp->type, extent);
01171 
01172                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01173                                  RGN_WRITE, &xp);       
01174                 if(lstatus != NC_NOERR)
01175                         return lstatus;
01176                 
01177                 lstatus = ncx_putn_short_short(&xp, nput, value);
01178                 if(lstatus != NC_NOERR && status == NC_NOERR)
01179                 {
01180                         /* not fatal to the loop */
01181                         status = lstatus;
01182                 }
01183 
01184                 (void) ncp->nciop->rel(ncp->nciop, offset,
01185                                  RGN_MODIFIED); 
01186 
01187                 remaining -= extent;
01188                 if(remaining == 0)
01189                         break; /* normal loop exit */
01190                 offset += extent;
01191                 value += nput;
01192 
01193         }
01194 
01195         return status;
01196 }
01197 
01198 static int
01199 putNCvx_short_int(NC *ncp, const NC_var *varp,
01200                  const size_t *start, size_t nelems, const int *value)
01201 {
01202         off_t offset = NC_varoffset(ncp, varp, start);
01203         size_t remaining = varp->xsz * nelems;
01204         int status = NC_NOERR;
01205         void *xp;
01206 
01207         if(nelems == 0)
01208                 return NC_NOERR;
01209 
01210         assert(value != NULL);
01211 
01212         for(;;)
01213         {
01214                 size_t extent = MIN(remaining, ncp->chunk);
01215                 size_t nput = ncx_howmany(varp->type, extent);
01216 
01217                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01218                                  RGN_WRITE, &xp);       
01219                 if(lstatus != NC_NOERR)
01220                         return lstatus;
01221                 
01222                 lstatus = ncx_putn_short_int(&xp, nput, value);
01223                 if(lstatus != NC_NOERR && status == NC_NOERR)
01224                 {
01225                         /* not fatal to the loop */
01226                         status = lstatus;
01227                 }
01228 
01229                 (void) ncp->nciop->rel(ncp->nciop, offset,
01230                                  RGN_MODIFIED); 
01231 
01232                 remaining -= extent;
01233                 if(remaining == 0)
01234                         break; /* normal loop exit */
01235                 offset += extent;
01236                 value += nput;
01237 
01238         }
01239 
01240         return status;
01241 }
01242 
01243 static int
01244 putNCvx_short_long(NC *ncp, const NC_var *varp,
01245                  const size_t *start, size_t nelems, const long *value)
01246 {
01247         off_t offset = NC_varoffset(ncp, varp, start);
01248         size_t remaining = varp->xsz * nelems;
01249         int status = NC_NOERR;
01250         void *xp;
01251 
01252         if(nelems == 0)
01253                 return NC_NOERR;
01254 
01255         assert(value != NULL);
01256 
01257         for(;;)
01258         {
01259                 size_t extent = MIN(remaining, ncp->chunk);
01260                 size_t nput = ncx_howmany(varp->type, extent);
01261 
01262                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01263                                  RGN_WRITE, &xp);       
01264                 if(lstatus != NC_NOERR)
01265                         return lstatus;
01266                 
01267                 lstatus = ncx_putn_short_long(&xp, nput, value);
01268                 if(lstatus != NC_NOERR && status == NC_NOERR)
01269                 {
01270                         /* not fatal to the loop */
01271                         status = lstatus;
01272                 }
01273 
01274                 (void) ncp->nciop->rel(ncp->nciop, offset,
01275                                  RGN_MODIFIED); 
01276 
01277                 remaining -= extent;
01278                 if(remaining == 0)
01279                         break; /* normal loop exit */
01280                 offset += extent;
01281                 value += nput;
01282 
01283         }
01284 
01285         return status;
01286 }
01287 
01288 static int
01289 putNCvx_short_float(NC *ncp, const NC_var *varp,
01290                  const size_t *start, size_t nelems, const float *value)
01291 {
01292         off_t offset = NC_varoffset(ncp, varp, start);
01293         size_t remaining = varp->xsz * nelems;
01294         int status = NC_NOERR;
01295         void *xp;
01296 
01297         if(nelems == 0)
01298                 return NC_NOERR;
01299 
01300         assert(value != NULL);
01301 
01302         for(;;)
01303         {
01304                 size_t extent = MIN(remaining, ncp->chunk);
01305                 size_t nput = ncx_howmany(varp->type, extent);
01306 
01307                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01308                                  RGN_WRITE, &xp);       
01309                 if(lstatus != NC_NOERR)
01310                         return lstatus;
01311                 
01312                 lstatus = ncx_putn_short_float(&xp, nput, value);
01313                 if(lstatus != NC_NOERR && status == NC_NOERR)
01314                 {
01315                         /* not fatal to the loop */
01316                         status = lstatus;
01317                 }
01318 
01319                 (void) ncp->nciop->rel(ncp->nciop, offset,
01320                                  RGN_MODIFIED); 
01321 
01322                 remaining -= extent;
01323                 if(remaining == 0)
01324                         break; /* normal loop exit */
01325                 offset += extent;
01326                 value += nput;
01327 
01328         }
01329 
01330         return status;
01331 }
01332 
01333 static int
01334 putNCvx_short_double(NC *ncp, const NC_var *varp,
01335                  const size_t *start, size_t nelems, const double *value)
01336 {
01337         off_t offset = NC_varoffset(ncp, varp, start);
01338         size_t remaining = varp->xsz * nelems;
01339         int status = NC_NOERR;
01340         void *xp;
01341 
01342         if(nelems == 0)
01343                 return NC_NOERR;
01344 
01345         assert(value != NULL);
01346 
01347         for(;;)
01348         {
01349                 size_t extent = MIN(remaining, ncp->chunk);
01350                 size_t nput = ncx_howmany(varp->type, extent);
01351 
01352                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01353                                  RGN_WRITE, &xp);       
01354                 if(lstatus != NC_NOERR)
01355                         return lstatus;
01356                 
01357                 lstatus = ncx_putn_short_double(&xp, nput, value);
01358                 if(lstatus != NC_NOERR && status == NC_NOERR)
01359                 {
01360                         /* not fatal to the loop */
01361                         status = lstatus;
01362                 }
01363 
01364                 (void) ncp->nciop->rel(ncp->nciop, offset,
01365                                  RGN_MODIFIED); 
01366 
01367                 remaining -= extent;
01368                 if(remaining == 0)
01369                         break; /* normal loop exit */
01370                 offset += extent;
01371                 value += nput;
01372 
01373         }
01374 
01375         return status;
01376 }
01377 
01378 
01379 static int
01380 putNCvx_int_schar(NC *ncp, const NC_var *varp,
01381                  const size_t *start, size_t nelems, const schar *value)
01382 {
01383         off_t offset = NC_varoffset(ncp, varp, start);
01384         size_t remaining = varp->xsz * nelems;
01385         int status = NC_NOERR;
01386         void *xp;
01387 
01388         if(nelems == 0)
01389                 return NC_NOERR;
01390 
01391         assert(value != NULL);
01392 
01393         for(;;)
01394         {
01395                 size_t extent = MIN(remaining, ncp->chunk);
01396                 size_t nput = ncx_howmany(varp->type, extent);
01397 
01398                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01399                                  RGN_WRITE, &xp);       
01400                 if(lstatus != NC_NOERR)
01401                         return lstatus;
01402                 
01403                 lstatus = ncx_putn_int_schar(&xp, nput, value);
01404                 if(lstatus != NC_NOERR && status == NC_NOERR)
01405                 {
01406                         /* not fatal to the loop */
01407                         status = lstatus;
01408                 }
01409 
01410                 (void) ncp->nciop->rel(ncp->nciop, offset,
01411                                  RGN_MODIFIED); 
01412 
01413                 remaining -= extent;
01414                 if(remaining == 0)
01415                         break; /* normal loop exit */
01416                 offset += extent;
01417                 value += nput;
01418 
01419         }
01420 
01421         return status;
01422 }
01423 
01424 static int
01425 putNCvx_int_uchar(NC *ncp, const NC_var *varp,
01426                  const size_t *start, size_t nelems, const uchar *value)
01427 {
01428         off_t offset = NC_varoffset(ncp, varp, start);
01429         size_t remaining = varp->xsz * nelems;
01430         int status = NC_NOERR;
01431         void *xp;
01432 
01433         if(nelems == 0)
01434                 return NC_NOERR;
01435 
01436         assert(value != NULL);
01437 
01438         for(;;)
01439         {
01440                 size_t extent = MIN(remaining, ncp->chunk);
01441                 size_t nput = ncx_howmany(varp->type, extent);
01442 
01443                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01444                                  RGN_WRITE, &xp);       
01445                 if(lstatus != NC_NOERR)
01446                         return lstatus;
01447                 
01448                 lstatus = ncx_putn_int_uchar(&xp, nput, value);
01449                 if(lstatus != NC_NOERR && status == NC_NOERR)
01450                 {
01451                         /* not fatal to the loop */
01452                         status = lstatus;
01453                 }
01454 
01455                 (void) ncp->nciop->rel(ncp->nciop, offset,
01456                                  RGN_MODIFIED); 
01457 
01458                 remaining -= extent;
01459                 if(remaining == 0)
01460                         break; /* normal loop exit */
01461                 offset += extent;
01462                 value += nput;
01463 
01464         }
01465 
01466         return status;
01467 }
01468 
01469 static int
01470 putNCvx_int_short(NC *ncp, const NC_var *varp,
01471                  const size_t *start, size_t nelems, const short *value)
01472 {
01473         off_t offset = NC_varoffset(ncp, varp, start);
01474         size_t remaining = varp->xsz * nelems;
01475         int status = NC_NOERR;
01476         void *xp;
01477 
01478         if(nelems == 0)
01479                 return NC_NOERR;
01480 
01481         assert(value != NULL);
01482 
01483         for(;;)
01484         {
01485                 size_t extent = MIN(remaining, ncp->chunk);
01486                 size_t nput = ncx_howmany(varp->type, extent);
01487 
01488                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01489                                  RGN_WRITE, &xp);       
01490                 if(lstatus != NC_NOERR)
01491                         return lstatus;
01492                 
01493                 lstatus = ncx_putn_int_short(&xp, nput, value);
01494                 if(lstatus != NC_NOERR && status == NC_NOERR)
01495                 {
01496                         /* not fatal to the loop */
01497                         status = lstatus;
01498                 }
01499 
01500                 (void) ncp->nciop->rel(ncp->nciop, offset,
01501                                  RGN_MODIFIED); 
01502 
01503                 remaining -= extent;
01504                 if(remaining == 0)
01505                         break; /* normal loop exit */
01506                 offset += extent;
01507                 value += nput;
01508 
01509         }
01510 
01511         return status;
01512 }
01513 
01514 static int
01515 putNCvx_int_int(NC *ncp, const NC_var *varp,
01516                  const size_t *start, size_t nelems, const int *value)
01517 {
01518         off_t offset = NC_varoffset(ncp, varp, start);
01519         size_t remaining = varp->xsz * nelems;
01520         int status = NC_NOERR;
01521         void *xp;
01522 
01523         if(nelems == 0)
01524                 return NC_NOERR;
01525 
01526         assert(value != NULL);
01527 
01528         for(;;)
01529         {
01530                 size_t extent = MIN(remaining, ncp->chunk);
01531                 size_t nput = ncx_howmany(varp->type, extent);
01532 
01533                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01534                                  RGN_WRITE, &xp);       
01535                 if(lstatus != NC_NOERR)
01536                         return lstatus;
01537                 
01538                 lstatus = ncx_putn_int_int(&xp, nput, value);
01539                 if(lstatus != NC_NOERR && status == NC_NOERR)
01540                 {
01541                         /* not fatal to the loop */
01542                         status = lstatus;
01543                 }
01544 
01545                 (void) ncp->nciop->rel(ncp->nciop, offset,
01546                                  RGN_MODIFIED); 
01547 
01548                 remaining -= extent;
01549                 if(remaining == 0)
01550                         break; /* normal loop exit */
01551                 offset += extent;
01552                 value += nput;
01553 
01554         }
01555 
01556         return status;
01557 }
01558 
01559 static int
01560 putNCvx_int_long(NC *ncp, const NC_var *varp,
01561                  const size_t *start, size_t nelems, const long *value)
01562 {
01563         off_t offset = NC_varoffset(ncp, varp, start);
01564         size_t remaining = varp->xsz * nelems;
01565         int status = NC_NOERR;
01566         void *xp;
01567 
01568         if(nelems == 0)
01569                 return NC_NOERR;
01570 
01571         assert(value != NULL);
01572 
01573         for(;;)
01574         {
01575                 size_t extent = MIN(remaining, ncp->chunk);
01576                 size_t nput = ncx_howmany(varp->type, extent);
01577 
01578                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01579                                  RGN_WRITE, &xp);       
01580                 if(lstatus != NC_NOERR)
01581                         return lstatus;
01582                 
01583                 lstatus = ncx_putn_int_long(&xp, nput, value);
01584                 if(lstatus != NC_NOERR && status == NC_NOERR)
01585                 {
01586                         /* not fatal to the loop */
01587                         status = lstatus;
01588                 }
01589 
01590                 (void) ncp->nciop->rel(ncp->nciop, offset,
01591                                  RGN_MODIFIED); 
01592 
01593                 remaining -= extent;
01594                 if(remaining == 0)
01595                         break; /* normal loop exit */
01596                 offset += extent;
01597                 value += nput;
01598 
01599         }
01600 
01601         return status;
01602 }
01603 
01604 static int
01605 putNCvx_int_float(NC *ncp, const NC_var *varp,
01606                  const size_t *start, size_t nelems, const float *value)
01607 {
01608         off_t offset = NC_varoffset(ncp, varp, start);
01609         size_t remaining = varp->xsz * nelems;
01610         int status = NC_NOERR;
01611         void *xp;
01612 
01613         if(nelems == 0)
01614                 return NC_NOERR;
01615 
01616         assert(value != NULL);
01617 
01618         for(;;)
01619         {
01620                 size_t extent = MIN(remaining, ncp->chunk);
01621                 size_t nput = ncx_howmany(varp->type, extent);
01622 
01623                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01624                                  RGN_WRITE, &xp);       
01625                 if(lstatus != NC_NOERR)
01626                         return lstatus;
01627                 
01628                 lstatus = ncx_putn_int_float(&xp, nput, value);
01629                 if(lstatus != NC_NOERR && status == NC_NOERR)
01630                 {
01631                         /* not fatal to the loop */
01632                         status = lstatus;
01633                 }
01634 
01635                 (void) ncp->nciop->rel(ncp->nciop, offset,
01636                                  RGN_MODIFIED); 
01637 
01638                 remaining -= extent;
01639                 if(remaining == 0)
01640                         break; /* normal loop exit */
01641                 offset += extent;
01642                 value += nput;
01643 
01644         }
01645 
01646         return status;
01647 }
01648 
01649 static int
01650 putNCvx_int_double(NC *ncp, const NC_var *varp,
01651                  const size_t *start, size_t nelems, const double *value)
01652 {
01653         off_t offset = NC_varoffset(ncp, varp, start);
01654         size_t remaining = varp->xsz * nelems;
01655         int status = NC_NOERR;
01656         void *xp;
01657 
01658         if(nelems == 0)
01659                 return NC_NOERR;
01660 
01661         assert(value != NULL);
01662 
01663         for(;;)
01664         {
01665                 size_t extent = MIN(remaining, ncp->chunk);
01666                 size_t nput = ncx_howmany(varp->type, extent);
01667 
01668                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01669                                  RGN_WRITE, &xp);       
01670                 if(lstatus != NC_NOERR)
01671                         return lstatus;
01672                 
01673                 lstatus = ncx_putn_int_double(&xp, nput, value);
01674                 if(lstatus != NC_NOERR && status == NC_NOERR)
01675                 {
01676                         /* not fatal to the loop */
01677                         status = lstatus;
01678                 }
01679 
01680                 (void) ncp->nciop->rel(ncp->nciop, offset,
01681                                  RGN_MODIFIED); 
01682 
01683                 remaining -= extent;
01684                 if(remaining == 0)
01685                         break; /* normal loop exit */
01686                 offset += extent;
01687                 value += nput;
01688 
01689         }
01690 
01691         return status;
01692 }
01693 
01694 
01695 static int
01696 putNCvx_float_schar(NC *ncp, const NC_var *varp,
01697                  const size_t *start, size_t nelems, const schar *value)
01698 {
01699         off_t offset = NC_varoffset(ncp, varp, start);
01700         size_t remaining = varp->xsz * nelems;
01701         int status = NC_NOERR;
01702         void *xp;
01703 
01704         if(nelems == 0)
01705                 return NC_NOERR;
01706 
01707         assert(value != NULL);
01708 
01709         for(;;)
01710         {
01711                 size_t extent = MIN(remaining, ncp->chunk);
01712                 size_t nput = ncx_howmany(varp->type, extent);
01713 
01714                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01715                                  RGN_WRITE, &xp);       
01716                 if(lstatus != NC_NOERR)
01717                         return lstatus;
01718                 
01719                 lstatus = ncx_putn_float_schar(&xp, nput, value);
01720                 if(lstatus != NC_NOERR && status == NC_NOERR)
01721                 {
01722                         /* not fatal to the loop */
01723                         status = lstatus;
01724                 }
01725 
01726                 (void) ncp->nciop->rel(ncp->nciop, offset,
01727                                  RGN_MODIFIED); 
01728 
01729                 remaining -= extent;
01730                 if(remaining == 0)
01731                         break; /* normal loop exit */
01732                 offset += extent;
01733                 value += nput;
01734 
01735         }
01736 
01737         return status;
01738 }
01739 
01740 static int
01741 putNCvx_float_uchar(NC *ncp, const NC_var *varp,
01742                  const size_t *start, size_t nelems, const uchar *value)
01743 {
01744         off_t offset = NC_varoffset(ncp, varp, start);
01745         size_t remaining = varp->xsz * nelems;
01746         int status = NC_NOERR;
01747         void *xp;
01748 
01749         if(nelems == 0)
01750                 return NC_NOERR;
01751 
01752         assert(value != NULL);
01753 
01754         for(;;)
01755         {
01756                 size_t extent = MIN(remaining, ncp->chunk);
01757                 size_t nput = ncx_howmany(varp->type, extent);
01758 
01759                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01760                                  RGN_WRITE, &xp);       
01761                 if(lstatus != NC_NOERR)
01762                         return lstatus;
01763                 
01764                 lstatus = ncx_putn_float_uchar(&xp, nput, value);
01765                 if(lstatus != NC_NOERR && status == NC_NOERR)
01766                 {
01767                         /* not fatal to the loop */
01768                         status = lstatus;
01769                 }
01770 
01771                 (void) ncp->nciop->rel(ncp->nciop, offset,
01772                                  RGN_MODIFIED); 
01773 
01774                 remaining -= extent;
01775                 if(remaining == 0)
01776                         break; /* normal loop exit */
01777                 offset += extent;
01778                 value += nput;
01779 
01780         }
01781 
01782         return status;
01783 }
01784 
01785 static int
01786 putNCvx_float_short(NC *ncp, const NC_var *varp,
01787                  const size_t *start, size_t nelems, const short *value)
01788 {
01789         off_t offset = NC_varoffset(ncp, varp, start);
01790         size_t remaining = varp->xsz * nelems;
01791         int status = NC_NOERR;
01792         void *xp;
01793 
01794         if(nelems == 0)
01795                 return NC_NOERR;
01796 
01797         assert(value != NULL);
01798 
01799         for(;;)
01800         {
01801                 size_t extent = MIN(remaining, ncp->chunk);
01802                 size_t nput = ncx_howmany(varp->type, extent);
01803 
01804                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01805                                  RGN_WRITE, &xp);       
01806                 if(lstatus != NC_NOERR)
01807                         return lstatus;
01808                 
01809                 lstatus = ncx_putn_float_short(&xp, nput, value);
01810                 if(lstatus != NC_NOERR && status == NC_NOERR)
01811                 {
01812                         /* not fatal to the loop */
01813                         status = lstatus;
01814                 }
01815 
01816                 (void) ncp->nciop->rel(ncp->nciop, offset,
01817                                  RGN_MODIFIED); 
01818 
01819                 remaining -= extent;
01820                 if(remaining == 0)
01821                         break; /* normal loop exit */
01822                 offset += extent;
01823                 value += nput;
01824 
01825         }
01826 
01827         return status;
01828 }
01829 
01830 static int
01831 putNCvx_float_int(NC *ncp, const NC_var *varp,
01832                  const size_t *start, size_t nelems, const int *value)
01833 {
01834         off_t offset = NC_varoffset(ncp, varp, start);
01835         size_t remaining = varp->xsz * nelems;
01836         int status = NC_NOERR;
01837         void *xp;
01838 
01839         if(nelems == 0)
01840                 return NC_NOERR;
01841 
01842         assert(value != NULL);
01843 
01844         for(;;)
01845         {
01846                 size_t extent = MIN(remaining, ncp->chunk);
01847                 size_t nput = ncx_howmany(varp->type, extent);
01848 
01849                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01850                                  RGN_WRITE, &xp);       
01851                 if(lstatus != NC_NOERR)
01852                         return lstatus;
01853                 
01854                 lstatus = ncx_putn_float_int(&xp, nput, value);
01855                 if(lstatus != NC_NOERR && status == NC_NOERR)
01856                 {
01857                         /* not fatal to the loop */
01858                         status = lstatus;
01859                 }
01860 
01861                 (void) ncp->nciop->rel(ncp->nciop, offset,
01862                                  RGN_MODIFIED); 
01863 
01864                 remaining -= extent;
01865                 if(remaining == 0)
01866                         break; /* normal loop exit */
01867                 offset += extent;
01868                 value += nput;
01869 
01870         }
01871 
01872         return status;
01873 }
01874 
01875 static int
01876 putNCvx_float_long(NC *ncp, const NC_var *varp,
01877                  const size_t *start, size_t nelems, const long *value)
01878 {
01879         off_t offset = NC_varoffset(ncp, varp, start);
01880         size_t remaining = varp->xsz * nelems;
01881         int status = NC_NOERR;
01882         void *xp;
01883 
01884         if(nelems == 0)
01885                 return NC_NOERR;
01886 
01887         assert(value != NULL);
01888 
01889         for(;;)
01890         {
01891                 size_t extent = MIN(remaining, ncp->chunk);
01892                 size_t nput = ncx_howmany(varp->type, extent);
01893 
01894                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01895                                  RGN_WRITE, &xp);       
01896                 if(lstatus != NC_NOERR)
01897                         return lstatus;
01898                 
01899                 lstatus = ncx_putn_float_long(&xp, nput, value);
01900                 if(lstatus != NC_NOERR && status == NC_NOERR)
01901                 {
01902                         /* not fatal to the loop */
01903                         status = lstatus;
01904                 }
01905 
01906                 (void) ncp->nciop->rel(ncp->nciop, offset,
01907                                  RGN_MODIFIED); 
01908 
01909                 remaining -= extent;
01910                 if(remaining == 0)
01911                         break; /* normal loop exit */
01912                 offset += extent;
01913                 value += nput;
01914 
01915         }
01916 
01917         return status;
01918 }
01919 
01920 static int
01921 putNCvx_float_float(NC *ncp, const NC_var *varp,
01922                  const size_t *start, size_t nelems, const float *value)
01923 {
01924         off_t offset = NC_varoffset(ncp, varp, start);
01925         size_t remaining = varp->xsz * nelems;
01926         int status = NC_NOERR;
01927         void *xp;
01928 
01929         if(nelems == 0)
01930                 return NC_NOERR;
01931 
01932         assert(value != NULL);
01933 
01934         for(;;)
01935         {
01936                 size_t extent = MIN(remaining, ncp->chunk);
01937                 size_t nput = ncx_howmany(varp->type, extent);
01938 
01939                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01940                                  RGN_WRITE, &xp);       
01941                 if(lstatus != NC_NOERR)
01942                         return lstatus;
01943                 
01944                 lstatus = ncx_putn_float_float(&xp, nput, value);
01945                 if(lstatus != NC_NOERR && status == NC_NOERR)
01946                 {
01947                         /* not fatal to the loop */
01948                         status = lstatus;
01949                 }
01950 
01951                 (void) ncp->nciop->rel(ncp->nciop, offset,
01952                                  RGN_MODIFIED); 
01953 
01954                 remaining -= extent;
01955                 if(remaining == 0)
01956                         break; /* normal loop exit */
01957                 offset += extent;
01958                 value += nput;
01959 
01960         }
01961 
01962         return status;
01963 }
01964 
01965 static int
01966 putNCvx_float_double(NC *ncp, const NC_var *varp,
01967                  const size_t *start, size_t nelems, const double *value)
01968 {
01969         off_t offset = NC_varoffset(ncp, varp, start);
01970         size_t remaining = varp->xsz * nelems;
01971         int status = NC_NOERR;
01972         void *xp;
01973 
01974         if(nelems == 0)
01975                 return NC_NOERR;
01976 
01977         assert(value != NULL);
01978 
01979         for(;;)
01980         {
01981                 size_t extent = MIN(remaining, ncp->chunk);
01982                 size_t nput = ncx_howmany(varp->type, extent);
01983 
01984                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01985                                  RGN_WRITE, &xp);       
01986                 if(lstatus != NC_NOERR)
01987                         return lstatus;
01988                 
01989                 lstatus = ncx_putn_float_double(&xp, nput, value);
01990                 if(lstatus != NC_NOERR && status == NC_NOERR)
01991                 {
01992                         /* not fatal to the loop */
01993                         status = lstatus;
01994                 }
01995 
01996                 (void) ncp->nciop->rel(ncp->nciop, offset,
01997                                  RGN_MODIFIED); 
01998 
01999                 remaining -= extent;
02000                 if(remaining == 0)
02001                         break; /* normal loop exit */
02002                 offset += extent;
02003                 value += nput;
02004 
02005         }
02006 
02007         return status;
02008 }
02009 
02010 
02011 static int
02012 putNCvx_double_schar(NC *ncp, const NC_var *varp,
02013                  const size_t *start, size_t nelems, const schar *value)
02014 {
02015         off_t offset = NC_varoffset(ncp, varp, start);
02016         size_t remaining = varp->xsz * nelems;
02017         int status = NC_NOERR;
02018         void *xp;
02019 
02020         if(nelems == 0)
02021                 return NC_NOERR;
02022 
02023         assert(value != NULL);
02024 
02025         for(;;)
02026         {
02027                 size_t extent = MIN(remaining, ncp->chunk);
02028                 size_t nput = ncx_howmany(varp->type, extent);
02029 
02030                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02031                                  RGN_WRITE, &xp);       
02032                 if(lstatus != NC_NOERR)
02033                         return lstatus;
02034                 
02035                 lstatus = ncx_putn_double_schar(&xp, nput, value);
02036                 if(lstatus != NC_NOERR && status == NC_NOERR)
02037                 {
02038                         /* not fatal to the loop */
02039                         status = lstatus;
02040                 }
02041 
02042                 (void) ncp->nciop->rel(ncp->nciop, offset,
02043                                  RGN_MODIFIED); 
02044 
02045                 remaining -= extent;
02046                 if(remaining == 0)
02047                         break; /* normal loop exit */
02048                 offset += extent;
02049                 value += nput;
02050 
02051         }
02052 
02053         return status;
02054 }
02055 
02056 static int
02057 putNCvx_double_uchar(NC *ncp, const NC_var *varp,
02058                  const size_t *start, size_t nelems, const uchar *value)
02059 {
02060         off_t offset = NC_varoffset(ncp, varp, start);
02061         size_t remaining = varp->xsz * nelems;
02062         int status = NC_NOERR;
02063         void *xp;
02064 
02065         if(nelems == 0)
02066                 return NC_NOERR;
02067 
02068         assert(value != NULL);
02069 
02070         for(;;)
02071         {
02072                 size_t extent = MIN(remaining, ncp->chunk);
02073                 size_t nput = ncx_howmany(varp->type, extent);
02074 
02075                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02076                                  RGN_WRITE, &xp);       
02077                 if(lstatus != NC_NOERR)
02078                         return lstatus;
02079                 
02080                 lstatus = ncx_putn_double_uchar(&xp, nput, value);
02081                 if(lstatus != NC_NOERR && status == NC_NOERR)
02082                 {
02083                         /* not fatal to the loop */
02084                         status = lstatus;
02085                 }
02086 
02087                 (void) ncp->nciop->rel(ncp->nciop, offset,
02088                                  RGN_MODIFIED); 
02089 
02090                 remaining -= extent;
02091                 if(remaining == 0)
02092                         break; /* normal loop exit */
02093                 offset += extent;
02094                 value += nput;
02095 
02096         }
02097 
02098         return status;
02099 }
02100 
02101 static int
02102 putNCvx_double_short(NC *ncp, const NC_var *varp,
02103                  const size_t *start, size_t nelems, const short *value)
02104 {
02105         off_t offset = NC_varoffset(ncp, varp, start);
02106         size_t remaining = varp->xsz * nelems;
02107         int status = NC_NOERR;
02108         void *xp;
02109 
02110         if(nelems == 0)
02111                 return NC_NOERR;
02112 
02113         assert(value != NULL);
02114 
02115         for(;;)
02116         {
02117                 size_t extent = MIN(remaining, ncp->chunk);
02118                 size_t nput = ncx_howmany(varp->type, extent);
02119 
02120                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02121                                  RGN_WRITE, &xp);       
02122                 if(lstatus != NC_NOERR)
02123                         return lstatus;
02124                 
02125                 lstatus = ncx_putn_double_short(&xp, nput, value);
02126                 if(lstatus != NC_NOERR && status == NC_NOERR)
02127                 {
02128                         /* not fatal to the loop */
02129                         status = lstatus;
02130                 }
02131 
02132                 (void) ncp->nciop->rel(ncp->nciop, offset,
02133                                  RGN_MODIFIED); 
02134 
02135                 remaining -= extent;
02136                 if(remaining == 0)
02137                         break; /* normal loop exit */
02138                 offset += extent;
02139                 value += nput;
02140 
02141         }
02142 
02143         return status;
02144 }
02145 
02146 static int
02147 putNCvx_double_int(NC *ncp, const NC_var *varp,
02148                  const size_t *start, size_t nelems, const int *value)
02149 {
02150         off_t offset = NC_varoffset(ncp, varp, start);
02151         size_t remaining = varp->xsz * nelems;
02152         int status = NC_NOERR;
02153         void *xp;
02154 
02155         if(nelems == 0)
02156                 return NC_NOERR;
02157 
02158         assert(value != NULL);
02159 
02160         for(;;)
02161         {
02162                 size_t extent = MIN(remaining, ncp->chunk);
02163                 size_t nput = ncx_howmany(varp->type, extent);
02164 
02165                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02166                                  RGN_WRITE, &xp);       
02167                 if(lstatus != NC_NOERR)
02168                         return lstatus;
02169                 
02170                 lstatus = ncx_putn_double_int(&xp, nput, value);
02171                 if(lstatus != NC_NOERR && status == NC_NOERR)
02172                 {
02173                         /* not fatal to the loop */
02174                         status = lstatus;
02175                 }
02176 
02177                 (void) ncp->nciop->rel(ncp->nciop, offset,
02178                                  RGN_MODIFIED); 
02179 
02180                 remaining -= extent;
02181                 if(remaining == 0)
02182                         break; /* normal loop exit */
02183                 offset += extent;
02184                 value += nput;
02185 
02186         }
02187 
02188         return status;
02189 }
02190 
02191 static int
02192 putNCvx_double_long(NC *ncp, const NC_var *varp,
02193                  const size_t *start, size_t nelems, const long *value)
02194 {
02195         off_t offset = NC_varoffset(ncp, varp, start);
02196         size_t remaining = varp->xsz * nelems;
02197         int status = NC_NOERR;
02198         void *xp;
02199 
02200         if(nelems == 0)
02201                 return NC_NOERR;
02202 
02203         assert(value != NULL);
02204 
02205         for(;;)
02206         {
02207                 size_t extent = MIN(remaining, ncp->chunk);
02208                 size_t nput = ncx_howmany(varp->type, extent);
02209 
02210                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02211                                  RGN_WRITE, &xp);       
02212                 if(lstatus != NC_NOERR)
02213                         return lstatus;
02214                 
02215                 lstatus = ncx_putn_double_long(&xp, nput, value);
02216                 if(lstatus != NC_NOERR && status == NC_NOERR)
02217                 {
02218                         /* not fatal to the loop */
02219                         status = lstatus;
02220                 }
02221 
02222                 (void) ncp->nciop->rel(ncp->nciop, offset,
02223                                  RGN_MODIFIED); 
02224 
02225                 remaining -= extent;
02226                 if(remaining == 0)
02227                         break; /* normal loop exit */
02228                 offset += extent;
02229                 value += nput;
02230 
02231         }
02232 
02233         return status;
02234 }
02235 
02236 static int
02237 putNCvx_double_float(NC *ncp, const NC_var *varp,
02238                  const size_t *start, size_t nelems, const float *value)
02239 {
02240         off_t offset = NC_varoffset(ncp, varp, start);
02241         size_t remaining = varp->xsz * nelems;
02242         int status = NC_NOERR;
02243         void *xp;
02244 
02245         if(nelems == 0)
02246                 return NC_NOERR;
02247 
02248         assert(value != NULL);
02249 
02250         for(;;)
02251         {
02252                 size_t extent = MIN(remaining, ncp->chunk);
02253                 size_t nput = ncx_howmany(varp->type, extent);
02254 
02255                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02256                                  RGN_WRITE, &xp);       
02257                 if(lstatus != NC_NOERR)
02258                         return lstatus;
02259                 
02260                 lstatus = ncx_putn_double_float(&xp, nput, value);
02261                 if(lstatus != NC_NOERR && status == NC_NOERR)
02262                 {
02263                         /* not fatal to the loop */
02264                         status = lstatus;
02265                 }
02266 
02267                 (void) ncp->nciop->rel(ncp->nciop, offset,
02268                                  RGN_MODIFIED); 
02269 
02270                 remaining -= extent;
02271                 if(remaining == 0)
02272                         break; /* normal loop exit */
02273                 offset += extent;
02274                 value += nput;
02275 
02276         }
02277 
02278         return status;
02279 }
02280 
02281 static int
02282 putNCvx_double_double(NC *ncp, const NC_var *varp,
02283                  const size_t *start, size_t nelems, const double *value)
02284 {
02285         off_t offset = NC_varoffset(ncp, varp, start);
02286         size_t remaining = varp->xsz * nelems;
02287         int status = NC_NOERR;
02288         void *xp;
02289 
02290         if(nelems == 0)
02291                 return NC_NOERR;
02292 
02293         assert(value != NULL);
02294 
02295         for(;;)
02296         {
02297                 size_t extent = MIN(remaining, ncp->chunk);
02298                 size_t nput = ncx_howmany(varp->type, extent);
02299 
02300                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02301                                  RGN_WRITE, &xp);       
02302                 if(lstatus != NC_NOERR)
02303                         return lstatus;
02304                 
02305                 lstatus = ncx_putn_double_double(&xp, nput, value);
02306                 if(lstatus != NC_NOERR && status == NC_NOERR)
02307                 {
02308                         /* not fatal to the loop */
02309                         status = lstatus;
02310                 }
02311 
02312                 (void) ncp->nciop->rel(ncp->nciop, offset,
02313                                  RGN_MODIFIED); 
02314 
02315                 remaining -= extent;
02316                 if(remaining == 0)
02317                         break; /* normal loop exit */
02318                 offset += extent;
02319                 value += nput;
02320 
02321         }
02322 
02323         return status;
02324 }
02325 
02326 
02327 
02328 
02329 static int
02330 putNCv_text(NC *ncp, const NC_var *varp,
02331                  const size_t *start, size_t nelems, const char *value)
02332 {
02333         if(varp->type != NC_CHAR)
02334                 return NC_ECHAR;
02335         return putNCvx_char_char(ncp, varp, start, nelems, value);
02336 }
02337 
02338 static int
02339 putNCv_schar(NC *ncp, const NC_var *varp,
02340                  const size_t *start, size_t nelems, const schar *value)
02341 {
02342         switch(varp->type){
02343         case NC_CHAR:
02344                 return NC_ECHAR;
02345         case NC_BYTE:
02346                 return putNCvx_schar_schar(ncp, varp, start, nelems,
02347                         value);
02348         case NC_SHORT:
02349                 return putNCvx_short_schar(ncp, varp, start, nelems,
02350                         value);
02351         case NC_INT:
02352                 return putNCvx_int_schar(ncp, varp, start, nelems,
02353                         value);
02354         case NC_FLOAT:
02355                 return putNCvx_float_schar(ncp, varp, start, nelems,
02356                         value);
02357         case NC_DOUBLE: 
02358                 return putNCvx_double_schar(ncp, varp, start, nelems,
02359                         value);
02360         }
02361         return NC_EBADTYPE;
02362 }
02363 
02364 static int
02365 putNCv_uchar(NC *ncp, const NC_var *varp,
02366                  const size_t *start, size_t nelems, const uchar *value)
02367 {
02368         switch(varp->type){
02369         case NC_CHAR:
02370                 return NC_ECHAR;
02371         case NC_BYTE:
02372                 return putNCvx_schar_uchar(ncp, varp, start, nelems,
02373                         value);
02374         case NC_SHORT:
02375                 return putNCvx_short_uchar(ncp, varp, start, nelems,
02376                         value);
02377         case NC_INT:
02378                 return putNCvx_int_uchar(ncp, varp, start, nelems,
02379                         value);
02380         case NC_FLOAT:
02381                 return putNCvx_float_uchar(ncp, varp, start, nelems,
02382                         value);
02383         case NC_DOUBLE: 
02384                 return putNCvx_double_uchar(ncp, varp, start, nelems,
02385                         value);
02386         }
02387         return NC_EBADTYPE;
02388 }
02389 
02390 static int
02391 putNCv_short(NC *ncp, const NC_var *varp,
02392                  const size_t *start, size_t nelems, const short *value)
02393 {
02394         switch(varp->type){
02395         case NC_CHAR:
02396                 return NC_ECHAR;
02397         case NC_BYTE:
02398                 return putNCvx_schar_short(ncp, varp, start, nelems,
02399                         value);
02400         case NC_SHORT:
02401                 return putNCvx_short_short(ncp, varp, start, nelems,
02402                         value);
02403         case NC_INT:
02404                 return putNCvx_int_short(ncp, varp, start, nelems,
02405                         value);
02406         case NC_FLOAT:
02407                 return putNCvx_float_short(ncp, varp, start, nelems,
02408                         value);
02409         case NC_DOUBLE: 
02410                 return putNCvx_double_short(ncp, varp, start, nelems,
02411                         value);
02412         }
02413         return NC_EBADTYPE;
02414 }
02415 
02416 static int
02417 putNCv_int(NC *ncp, const NC_var *varp,
02418                  const size_t *start, size_t nelems, const int *value)
02419 {
02420         switch(varp->type){
02421         case NC_CHAR:
02422                 return NC_ECHAR;
02423         case NC_BYTE:
02424                 return putNCvx_schar_int(ncp, varp, start, nelems,
02425                         value);
02426         case NC_SHORT:
02427                 return putNCvx_short_int(ncp, varp, start, nelems,
02428                         value);
02429         case NC_INT:
02430                 return putNCvx_int_int(ncp, varp, start, nelems,
02431                         value);
02432         case NC_FLOAT:
02433                 return putNCvx_float_int(ncp, varp, start, nelems,
02434                         value);
02435         case NC_DOUBLE: 
02436                 return putNCvx_double_int(ncp, varp, start, nelems,
02437                         value);
02438         }
02439         return NC_EBADTYPE;
02440 }
02441 
02442 static int
02443 putNCv_long(NC *ncp, const NC_var *varp,
02444                  const size_t *start, size_t nelems, const long *value)
02445 {
02446         switch(varp->type){
02447         case NC_CHAR:
02448                 return NC_ECHAR;
02449         case NC_BYTE:
02450                 return putNCvx_schar_long(ncp, varp, start, nelems,
02451                         value);
02452         case NC_SHORT:
02453                 return putNCvx_short_long(ncp, varp, start, nelems,
02454                         value);
02455         case NC_INT:
02456                 return putNCvx_int_long(ncp, varp, start, nelems,
02457                         value);
02458         case NC_FLOAT:
02459                 return putNCvx_float_long(ncp, varp, start, nelems,
02460                         value);
02461         case NC_DOUBLE: 
02462                 return putNCvx_double_long(ncp, varp, start, nelems,
02463                         value);
02464         }
02465         return NC_EBADTYPE;
02466 }
02467 
02468 static int
02469 putNCv_float(NC *ncp, const NC_var *varp,
02470                  const size_t *start, size_t nelems, const float *value)
02471 {
02472         switch(varp->type){
02473         case NC_CHAR:
02474                 return NC_ECHAR;
02475         case NC_BYTE:
02476                 return putNCvx_schar_float(ncp, varp, start, nelems,
02477                         value);
02478         case NC_SHORT:
02479                 return putNCvx_short_float(ncp, varp, start, nelems,
02480                         value);
02481         case NC_INT:
02482                 return putNCvx_int_float(ncp, varp, start, nelems,
02483                         value);
02484         case NC_FLOAT:
02485                 return putNCvx_float_float(ncp, varp, start, nelems,
02486                         value);
02487         case NC_DOUBLE: 
02488                 return putNCvx_double_float(ncp, varp, start, nelems,
02489                         value);
02490         }
02491         return NC_EBADTYPE;
02492 }
02493 
02494 static int
02495 putNCv_double(NC *ncp, const NC_var *varp,
02496                  const size_t *start, size_t nelems, const double *value)
02497 {
02498         switch(varp->type){
02499         case NC_CHAR:
02500                 return NC_ECHAR;
02501         case NC_BYTE:
02502                 return putNCvx_schar_double(ncp, varp, start, nelems,
02503                         value);
02504         case NC_SHORT:
02505                 return putNCvx_short_double(ncp, varp, start, nelems,
02506                         value);
02507         case NC_INT:
02508                 return putNCvx_int_double(ncp, varp, start, nelems,
02509                         value);
02510         case NC_FLOAT:
02511                 return putNCvx_float_double(ncp, varp, start, nelems,
02512                         value);
02513         case NC_DOUBLE: 
02514                 return putNCvx_double_double(ncp, varp, start, nelems,
02515                         value);
02516         }
02517         return NC_EBADTYPE;
02518 }
02519 
02520 
02521 
02522 
02523 static int
02524 getNCvx_char_char(const NC *ncp, const NC_var *varp,
02525                  const size_t *start, size_t nelems, char *value)
02526 {
02527         off_t offset = NC_varoffset(ncp, varp, start);
02528         size_t remaining = varp->xsz * nelems;
02529         int status = NC_NOERR;
02530         const void *xp;
02531 
02532         if(nelems == 0)
02533                 return NC_NOERR;
02534 
02535         assert(value != NULL);
02536 
02537         for(;;)
02538         {
02539                 size_t extent = MIN(remaining, ncp->chunk);
02540                 size_t nget = ncx_howmany(varp->type, extent);
02541 
02542                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02543                                  0, (void **)&xp);      /* cast away const */
02544                 if(lstatus != NC_NOERR)
02545                         return lstatus;
02546                 
02547                 lstatus = ncx_getn_char_char(&xp, nget, value);
02548                 if(lstatus != NC_NOERR && status == NC_NOERR)
02549                         status = lstatus;
02550 
02551                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02552 
02553                 remaining -= extent;
02554                 if(remaining == 0)
02555                         break; /* normal loop exit */
02556                 offset += extent;
02557                 value += nget;
02558         }
02559 
02560         return status;
02561 }
02562 
02563 
02564 static int
02565 getNCvx_schar_schar(const NC *ncp, const NC_var *varp,
02566                  const size_t *start, size_t nelems, schar *value)
02567 {
02568         off_t offset = NC_varoffset(ncp, varp, start);
02569         size_t remaining = varp->xsz * nelems;
02570         int status = NC_NOERR;
02571         const void *xp;
02572 
02573         if(nelems == 0)
02574                 return NC_NOERR;
02575 
02576         assert(value != NULL);
02577 
02578         for(;;)
02579         {
02580                 size_t extent = MIN(remaining, ncp->chunk);
02581                 size_t nget = ncx_howmany(varp->type, extent);
02582 
02583                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02584                                  0, (void **)&xp);      /* cast away const */
02585                 if(lstatus != NC_NOERR)
02586                         return lstatus;
02587                 
02588                 lstatus = ncx_getn_schar_schar(&xp, nget, value);
02589                 if(lstatus != NC_NOERR && status == NC_NOERR)
02590                         status = lstatus;
02591 
02592                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02593 
02594                 remaining -= extent;
02595                 if(remaining == 0)
02596                         break; /* normal loop exit */
02597                 offset += extent;
02598                 value += nget;
02599         }
02600 
02601         return status;
02602 }
02603 
02604 static int
02605 getNCvx_schar_uchar(const NC *ncp, const NC_var *varp,
02606                  const size_t *start, size_t nelems, uchar *value)
02607 {
02608         off_t offset = NC_varoffset(ncp, varp, start);
02609         size_t remaining = varp->xsz * nelems;
02610         int status = NC_NOERR;
02611         const void *xp;
02612 
02613         if(nelems == 0)
02614                 return NC_NOERR;
02615 
02616         assert(value != NULL);
02617 
02618         for(;;)
02619         {
02620                 size_t extent = MIN(remaining, ncp->chunk);
02621                 size_t nget = ncx_howmany(varp->type, extent);
02622 
02623                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02624                                  0, (void **)&xp);      /* cast away const */
02625                 if(lstatus != NC_NOERR)
02626                         return lstatus;
02627                 
02628                 lstatus = ncx_getn_schar_uchar(&xp, nget, value);
02629                 if(lstatus != NC_NOERR && status == NC_NOERR)
02630                         status = lstatus;
02631 
02632                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02633 
02634                 remaining -= extent;
02635                 if(remaining == 0)
02636                         break; /* normal loop exit */
02637                 offset += extent;
02638                 value += nget;
02639         }
02640 
02641         return status;
02642 }
02643 
02644 static int
02645 getNCvx_schar_short(const NC *ncp, const NC_var *varp,
02646                  const size_t *start, size_t nelems, short *value)
02647 {
02648         off_t offset = NC_varoffset(ncp, varp, start);
02649         size_t remaining = varp->xsz * nelems;
02650         int status = NC_NOERR;
02651         const void *xp;
02652 
02653         if(nelems == 0)
02654                 return NC_NOERR;
02655 
02656         assert(value != NULL);
02657 
02658         for(;;)
02659         {
02660                 size_t extent = MIN(remaining, ncp->chunk);
02661                 size_t nget = ncx_howmany(varp->type, extent);
02662 
02663                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02664                                  0, (void **)&xp);      /* cast away const */
02665                 if(lstatus != NC_NOERR)
02666                         return lstatus;
02667                 
02668                 lstatus = ncx_getn_schar_short(&xp, nget, value);
02669                 if(lstatus != NC_NOERR && status == NC_NOERR)
02670                         status = lstatus;
02671 
02672                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02673 
02674                 remaining -= extent;
02675                 if(remaining == 0)
02676                         break; /* normal loop exit */
02677                 offset += extent;
02678                 value += nget;
02679         }
02680 
02681         return status;
02682 }
02683 
02684 static int
02685 getNCvx_schar_int(const NC *ncp, const NC_var *varp,
02686                  const size_t *start, size_t nelems, int *value)
02687 {
02688         off_t offset = NC_varoffset(ncp, varp, start);
02689         size_t remaining = varp->xsz * nelems;
02690         int status = NC_NOERR;
02691         const void *xp;
02692 
02693         if(nelems == 0)
02694                 return NC_NOERR;
02695 
02696         assert(value != NULL);
02697 
02698         for(;;)
02699         {
02700                 size_t extent = MIN(remaining, ncp->chunk);
02701                 size_t nget = ncx_howmany(varp->type, extent);
02702 
02703                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02704                                  0, (void **)&xp);      /* cast away const */
02705                 if(lstatus != NC_NOERR)
02706                         return lstatus;
02707                 
02708                 lstatus = ncx_getn_schar_int(&xp, nget, value);
02709                 if(lstatus != NC_NOERR && status == NC_NOERR)
02710                         status = lstatus;
02711 
02712                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02713 
02714                 remaining -= extent;
02715                 if(remaining == 0)
02716                         break; /* normal loop exit */
02717                 offset += extent;
02718                 value += nget;
02719         }
02720 
02721         return status;
02722 }
02723 
02724 static int
02725 getNCvx_schar_long(const NC *ncp, const NC_var *varp,
02726                  const size_t *start, size_t nelems, long *value)
02727 {
02728         off_t offset = NC_varoffset(ncp, varp, start);
02729         size_t remaining = varp->xsz * nelems;
02730         int status = NC_NOERR;
02731         const void *xp;
02732 
02733         if(nelems == 0)
02734                 return NC_NOERR;
02735 
02736         assert(value != NULL);
02737 
02738         for(;;)
02739         {
02740                 size_t extent = MIN(remaining, ncp->chunk);
02741                 size_t nget = ncx_howmany(varp->type, extent);
02742 
02743                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02744                                  0, (void **)&xp);      /* cast away const */
02745                 if(lstatus != NC_NOERR)
02746                         return lstatus;
02747                 
02748                 lstatus = ncx_getn_schar_long(&xp, nget, value);
02749                 if(lstatus != NC_NOERR && status == NC_NOERR)
02750                         status = lstatus;
02751 
02752                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02753 
02754                 remaining -= extent;
02755                 if(remaining == 0)
02756                         break; /* normal loop exit */
02757                 offset += extent;
02758                 value += nget;
02759         }
02760 
02761         return status;
02762 }
02763 
02764 static int
02765 getNCvx_schar_float(const NC *ncp, const NC_var *varp,
02766                  const size_t *start, size_t nelems, float *value)
02767 {
02768         off_t offset = NC_varoffset(ncp, varp, start);
02769         size_t remaining = varp->xsz * nelems;
02770         int status = NC_NOERR;
02771         const void *xp;
02772 
02773         if(nelems == 0)
02774                 return NC_NOERR;
02775 
02776         assert(value != NULL);
02777 
02778         for(;;)
02779         {
02780                 size_t extent = MIN(remaining, ncp->chunk);
02781                 size_t nget = ncx_howmany(varp->type, extent);
02782 
02783                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02784                                  0, (void **)&xp);      /* cast away const */
02785                 if(lstatus != NC_NOERR)
02786                         return lstatus;
02787                 
02788                 lstatus = ncx_getn_schar_float(&xp, nget, value);
02789                 if(lstatus != NC_NOERR && status == NC_NOERR)
02790                         status = lstatus;
02791 
02792                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02793 
02794                 remaining -= extent;
02795                 if(remaining == 0)
02796                         break; /* normal loop exit */
02797                 offset += extent;
02798                 value += nget;
02799         }
02800 
02801         return status;
02802 }
02803 
02804 static int
02805 getNCvx_schar_double(const NC *ncp, const NC_var *varp,
02806                  const size_t *start, size_t nelems, double *value)
02807 {
02808         off_t offset = NC_varoffset(ncp, varp, start);
02809         size_t remaining = varp->xsz * nelems;
02810         int status = NC_NOERR;
02811         const void *xp;
02812 
02813         if(nelems == 0)
02814                 return NC_NOERR;
02815 
02816         assert(value != NULL);
02817 
02818         for(;;)
02819         {
02820                 size_t extent = MIN(remaining, ncp->chunk);
02821                 size_t nget = ncx_howmany(varp->type, extent);
02822 
02823                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02824                                  0, (void **)&xp);      /* cast away const */
02825                 if(lstatus != NC_NOERR)
02826                         return lstatus;
02827                 
02828                 lstatus = ncx_getn_schar_double(&xp, nget, value);
02829                 if(lstatus != NC_NOERR && status == NC_NOERR)
02830                         status = lstatus;
02831 
02832                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02833 
02834                 remaining -= extent;
02835                 if(remaining == 0)
02836                         break; /* normal loop exit */
02837                 offset += extent;
02838                 value += nget;
02839         }
02840 
02841         return status;
02842 }
02843 
02844 
02845 static int
02846 getNCvx_short_schar(const NC *ncp, const NC_var *varp,
02847                  const size_t *start, size_t nelems, schar *value)
02848 {
02849         off_t offset = NC_varoffset(ncp, varp, start);
02850         size_t remaining = varp->xsz * nelems;
02851         int status = NC_NOERR;
02852         const void *xp;
02853 
02854         if(nelems == 0)
02855                 return NC_NOERR;
02856 
02857         assert(value != NULL);
02858 
02859         for(;;)
02860         {
02861                 size_t extent = MIN(remaining, ncp->chunk);
02862                 size_t nget = ncx_howmany(varp->type, extent);
02863 
02864                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02865                                  0, (void **)&xp);      /* cast away const */
02866                 if(lstatus != NC_NOERR)
02867                         return lstatus;
02868                 
02869                 lstatus = ncx_getn_short_schar(&xp, nget, value);
02870                 if(lstatus != NC_NOERR && status == NC_NOERR)
02871                         status = lstatus;
02872 
02873                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02874 
02875                 remaining -= extent;
02876                 if(remaining == 0)
02877                         break; /* normal loop exit */
02878                 offset += extent;
02879                 value += nget;
02880         }
02881 
02882         return status;
02883 }
02884 
02885 static int
02886 getNCvx_short_uchar(const NC *ncp, const NC_var *varp,
02887                  const size_t *start, size_t nelems, uchar *value)
02888 {
02889         off_t offset = NC_varoffset(ncp, varp, start);
02890         size_t remaining = varp->xsz * nelems;
02891         int status = NC_NOERR;
02892         const void *xp;
02893 
02894         if(nelems == 0)
02895                 return NC_NOERR;
02896 
02897         assert(value != NULL);
02898 
02899         for(;;)
02900         {
02901                 size_t extent = MIN(remaining, ncp->chunk);
02902                 size_t nget = ncx_howmany(varp->type, extent);
02903 
02904                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02905                                  0, (void **)&xp);      /* cast away const */
02906                 if(lstatus != NC_NOERR)
02907                         return lstatus;
02908                 
02909                 lstatus = ncx_getn_short_uchar(&xp, nget, value);
02910                 if(lstatus != NC_NOERR && status == NC_NOERR)
02911                         status = lstatus;
02912 
02913                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02914 
02915                 remaining -= extent;
02916                 if(remaining == 0)
02917                         break; /* normal loop exit */
02918                 offset += extent;
02919                 value += nget;
02920         }
02921 
02922         return status;
02923 }
02924 
02925 static int
02926 getNCvx_short_short(const NC *ncp, const NC_var *varp,
02927                  const size_t *start, size_t nelems, short *value)
02928 {
02929         off_t offset = NC_varoffset(ncp, varp, start);
02930         size_t remaining = varp->xsz * nelems;
02931         int status = NC_NOERR;
02932         const void *xp;
02933 
02934         if(nelems == 0)
02935                 return NC_NOERR;
02936 
02937         assert(value != NULL);
02938 
02939         for(;;)
02940         {
02941                 size_t extent = MIN(remaining, ncp->chunk);
02942                 size_t nget = ncx_howmany(varp->type, extent);
02943 
02944                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02945                                  0, (void **)&xp);      /* cast away const */
02946                 if(lstatus != NC_NOERR)
02947                         return lstatus;
02948                 
02949                 lstatus = ncx_getn_short_short(&xp, nget, value);
02950                 if(lstatus != NC_NOERR && status == NC_NOERR)
02951                         status = lstatus;
02952 
02953                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02954 
02955                 remaining -= extent;
02956                 if(remaining == 0)
02957                         break; /* normal loop exit */
02958                 offset += extent;
02959                 value += nget;
02960         }
02961 
02962         return status;
02963 }
02964 
02965 static int
02966 getNCvx_short_int(const NC *ncp, const NC_var *varp,
02967                  const size_t *start, size_t nelems, int *value)
02968 {
02969         off_t offset = NC_varoffset(ncp, varp, start);
02970         size_t remaining = varp->xsz * nelems;
02971         int status = NC_NOERR;
02972         const void *xp;
02973 
02974         if(nelems == 0)
02975                 return NC_NOERR;
02976 
02977         assert(value != NULL);
02978 
02979         for(;;)
02980         {
02981                 size_t extent = MIN(remaining, ncp->chunk);
02982                 size_t nget = ncx_howmany(varp->type, extent);
02983 
02984                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02985                                  0, (void **)&xp);      /* cast away const */
02986                 if(lstatus != NC_NOERR)
02987                         return lstatus;
02988                 
02989                 lstatus = ncx_getn_short_int(&xp, nget, value);
02990                 if(lstatus != NC_NOERR && status == NC_NOERR)
02991                         status = lstatus;
02992 
02993                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02994 
02995                 remaining -= extent;
02996                 if(remaining == 0)
02997                         break; /* normal loop exit */
02998                 offset += extent;
02999                 value += nget;
03000         }
03001 
03002         return status;
03003 }
03004 
03005 static int
03006 getNCvx_short_long(const NC *ncp, const NC_var *varp,
03007                  const size_t *start, size_t nelems, long *value)
03008 {
03009         off_t offset = NC_varoffset(ncp, varp, start);
03010         size_t remaining = varp->xsz * nelems;
03011         int status = NC_NOERR;
03012         const void *xp;
03013 
03014         if(nelems == 0)
03015                 return NC_NOERR;
03016 
03017         assert(value != NULL);
03018 
03019         for(;;)
03020         {
03021                 size_t extent = MIN(remaining, ncp->chunk);
03022                 size_t nget = ncx_howmany(varp->type, extent);
03023 
03024                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03025                                  0, (void **)&xp);      /* cast away const */
03026                 if(lstatus != NC_NOERR)
03027                         return lstatus;
03028                 
03029                 lstatus = ncx_getn_short_long(&xp, nget, value);
03030                 if(lstatus != NC_NOERR && status == NC_NOERR)
03031                         status = lstatus;
03032 
03033                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03034 
03035                 remaining -= extent;
03036                 if(remaining == 0)
03037                         break; /* normal loop exit */
03038                 offset += extent;
03039                 value += nget;
03040         }
03041 
03042         return status;
03043 }
03044 
03045 static int
03046 getNCvx_short_float(const NC *ncp, const NC_var *varp,
03047                  const size_t *start, size_t nelems, float *value)
03048 {
03049         off_t offset = NC_varoffset(ncp, varp, start);
03050         size_t remaining = varp->xsz * nelems;
03051         int status = NC_NOERR;
03052         const void *xp;
03053 
03054         if(nelems == 0)
03055                 return NC_NOERR;
03056 
03057         assert(value != NULL);
03058 
03059         for(;;)
03060         {
03061                 size_t extent = MIN(remaining, ncp->chunk);
03062                 size_t nget = ncx_howmany(varp->type, extent);
03063 
03064                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03065                                  0, (void **)&xp);      /* cast away const */
03066                 if(lstatus != NC_NOERR)
03067                         return lstatus;
03068                 
03069                 lstatus = ncx_getn_short_float(&xp, nget, value);
03070                 if(lstatus != NC_NOERR && status == NC_NOERR)
03071                         status = lstatus;
03072 
03073                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03074 
03075                 remaining -= extent;
03076                 if(remaining == 0)
03077                         break; /* normal loop exit */
03078                 offset += extent;
03079                 value += nget;
03080         }
03081 
03082         return status;
03083 }
03084 
03085 static int
03086 getNCvx_short_double(const NC *ncp, const NC_var *varp,
03087                  const size_t *start, size_t nelems, double *value)
03088 {
03089         off_t offset = NC_varoffset(ncp, varp, start);
03090         size_t remaining = varp->xsz * nelems;
03091         int status = NC_NOERR;
03092         const void *xp;
03093 
03094         if(nelems == 0)
03095                 return NC_NOERR;
03096 
03097         assert(value != NULL);
03098 
03099         for(;;)
03100         {
03101                 size_t extent = MIN(remaining, ncp->chunk);
03102                 size_t nget = ncx_howmany(varp->type, extent);
03103 
03104                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03105                                  0, (void **)&xp);      /* cast away const */
03106                 if(lstatus != NC_NOERR)
03107                         return lstatus;
03108                 
03109                 lstatus = ncx_getn_short_double(&xp, nget, value);
03110                 if(lstatus != NC_NOERR && status == NC_NOERR)
03111                         status = lstatus;
03112 
03113                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03114 
03115                 remaining -= extent;
03116                 if(remaining == 0)
03117                         break; /* normal loop exit */
03118                 offset += extent;
03119                 value += nget;
03120         }
03121 
03122         return status;
03123 }
03124 
03125 
03126 static int
03127 getNCvx_int_schar(const NC *ncp, const NC_var *varp,
03128                  const size_t *start, size_t nelems, schar *value)
03129 {
03130         off_t offset = NC_varoffset(ncp, varp, start);
03131         size_t remaining = varp->xsz * nelems;
03132         int status = NC_NOERR;
03133         const void *xp;
03134 
03135         if(nelems == 0)
03136                 return NC_NOERR;
03137 
03138         assert(value != NULL);
03139 
03140         for(;;)
03141         {
03142                 size_t extent = MIN(remaining, ncp->chunk);
03143                 size_t nget = ncx_howmany(varp->type, extent);
03144 
03145                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03146                                  0, (void **)&xp);      /* cast away const */
03147                 if(lstatus != NC_NOERR)
03148                         return lstatus;
03149                 
03150                 lstatus = ncx_getn_int_schar(&xp, nget, value);
03151                 if(lstatus != NC_NOERR && status == NC_NOERR)
03152                         status = lstatus;
03153 
03154                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03155 
03156                 remaining -= extent;
03157                 if(remaining == 0)
03158                         break; /* normal loop exit */
03159                 offset += extent;
03160                 value += nget;
03161         }
03162 
03163         return status;
03164 }
03165 
03166 static int
03167 getNCvx_int_uchar(const NC *ncp, const NC_var *varp,
03168                  const size_t *start, size_t nelems, uchar *value)
03169 {
03170         off_t offset = NC_varoffset(ncp, varp, start);
03171         size_t remaining = varp->xsz * nelems;
03172         int status = NC_NOERR;
03173         const void *xp;
03174 
03175         if(nelems == 0)
03176                 return NC_NOERR;
03177 
03178         assert(value != NULL);
03179 
03180         for(;;)
03181         {
03182                 size_t extent = MIN(remaining, ncp->chunk);
03183                 size_t nget = ncx_howmany(varp->type, extent);
03184 
03185                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03186                                  0, (void **)&xp);      /* cast away const */
03187                 if(lstatus != NC_NOERR)
03188                         return lstatus;
03189                 
03190                 lstatus = ncx_getn_int_uchar(&xp, nget, value);
03191                 if(lstatus != NC_NOERR && status == NC_NOERR)
03192                         status = lstatus;
03193 
03194                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03195 
03196                 remaining -= extent;
03197                 if(remaining == 0)
03198                         break; /* normal loop exit */
03199                 offset += extent;
03200                 value += nget;
03201         }
03202 
03203         return status;
03204 }
03205 
03206 static int
03207 getNCvx_int_short(const NC *ncp, const NC_var *varp,
03208                  const size_t *start, size_t nelems, short *value)
03209 {
03210         off_t offset = NC_varoffset(ncp, varp, start);
03211         size_t remaining = varp->xsz * nelems;
03212         int status = NC_NOERR;
03213         const void *xp;
03214 
03215         if(nelems == 0)
03216                 return NC_NOERR;
03217 
03218         assert(value != NULL);
03219 
03220         for(;;)
03221         {
03222                 size_t extent = MIN(remaining, ncp->chunk);
03223                 size_t nget = ncx_howmany(varp->type, extent);
03224 
03225                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03226                                  0, (void **)&xp);      /* cast away const */
03227                 if(lstatus != NC_NOERR)
03228                         return lstatus;
03229                 
03230                 lstatus = ncx_getn_int_short(&xp, nget, value);
03231                 if(lstatus != NC_NOERR && status == NC_NOERR)
03232                         status = lstatus;
03233 
03234                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03235 
03236                 remaining -= extent;
03237                 if(remaining == 0)
03238                         break; /* normal loop exit */
03239                 offset += extent;
03240                 value += nget;
03241         }
03242 
03243         return status;
03244 }
03245 
03246 static int
03247 getNCvx_int_int(const NC *ncp, const NC_var *varp,
03248                  const size_t *start, size_t nelems, int *value)
03249 {
03250         off_t offset = NC_varoffset(ncp, varp, start);
03251         size_t remaining = varp->xsz * nelems;
03252         int status = NC_NOERR;
03253         const void *xp;
03254 
03255         if(nelems == 0)
03256                 return NC_NOERR;
03257 
03258         assert(value != NULL);
03259 
03260         for(;;)
03261         {
03262                 size_t extent = MIN(remaining, ncp->chunk);
03263                 size_t nget = ncx_howmany(varp->type, extent);
03264 
03265                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03266                                  0, (void **)&xp);      /* cast away const */
03267                 if(lstatus != NC_NOERR)
03268                         return lstatus;
03269                 
03270                 lstatus = ncx_getn_int_int(&xp, nget, value);
03271                 if(lstatus != NC_NOERR && status == NC_NOERR)
03272                         status = lstatus;
03273 
03274                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03275 
03276                 remaining -= extent;
03277                 if(remaining == 0)
03278                         break; /* normal loop exit */
03279                 offset += extent;
03280                 value += nget;
03281         }
03282 
03283         return status;
03284 }
03285 
03286 static int
03287 getNCvx_int_long(const NC *ncp, const NC_var *varp,
03288                  const size_t *start, size_t nelems, long *value)
03289 {
03290         off_t offset = NC_varoffset(ncp, varp, start);
03291         size_t remaining = varp->xsz * nelems;
03292         int status = NC_NOERR;
03293         const void *xp;
03294 
03295         if(nelems == 0)
03296                 return NC_NOERR;
03297 
03298         assert(value != NULL);
03299 
03300         for(;;)
03301         {
03302                 size_t extent = MIN(remaining, ncp->chunk);
03303                 size_t nget = ncx_howmany(varp->type, extent);
03304 
03305                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03306                                  0, (void **)&xp);      /* cast away const */
03307                 if(lstatus != NC_NOERR)
03308                         return lstatus;
03309                 
03310                 lstatus = ncx_getn_int_long(&xp, nget, value);
03311                 if(lstatus != NC_NOERR && status == NC_NOERR)
03312                         status = lstatus;
03313 
03314                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03315 
03316                 remaining -= extent;
03317                 if(remaining == 0)
03318                         break; /* normal loop exit */
03319                 offset += extent;
03320                 value += nget;
03321         }
03322 
03323         return status;
03324 }
03325 
03326 static int
03327 getNCvx_int_float(const NC *ncp, const NC_var *varp,
03328                  const size_t *start, size_t nelems, float *value)
03329 {
03330         off_t offset = NC_varoffset(ncp, varp, start);
03331         size_t remaining = varp->xsz * nelems;
03332         int status = NC_NOERR;
03333         const void *xp;
03334 
03335         if(nelems == 0)
03336                 return NC_NOERR;
03337 
03338         assert(value != NULL);
03339 
03340         for(;;)
03341         {
03342                 size_t extent = MIN(remaining, ncp->chunk);
03343                 size_t nget = ncx_howmany(varp->type, extent);
03344 
03345                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03346                                  0, (void **)&xp);      /* cast away const */
03347                 if(lstatus != NC_NOERR)
03348                         return lstatus;
03349                 
03350                 lstatus = ncx_getn_int_float(&xp, nget, value);
03351                 if(lstatus != NC_NOERR && status == NC_NOERR)
03352                         status = lstatus;
03353 
03354                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03355 
03356                 remaining -= extent;
03357                 if(remaining == 0)
03358                         break; /* normal loop exit */
03359                 offset += extent;
03360                 value += nget;
03361         }
03362 
03363         return status;
03364 }
03365 
03366 static int
03367 getNCvx_int_double(const NC *ncp, const NC_var *varp,
03368                  const size_t *start, size_t nelems, double *value)
03369 {
03370         off_t offset = NC_varoffset(ncp, varp, start);
03371         size_t remaining = varp->xsz * nelems;
03372         int status = NC_NOERR;
03373         const void *xp;
03374 
03375         if(nelems == 0)
03376                 return NC_NOERR;
03377 
03378         assert(value != NULL);
03379 
03380         for(;;)
03381         {
03382                 size_t extent = MIN(remaining, ncp->chunk);
03383                 size_t nget = ncx_howmany(varp->type, extent);
03384 
03385                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03386                                  0, (void **)&xp);      /* cast away const */
03387                 if(lstatus != NC_NOERR)
03388                         return lstatus;
03389                 
03390                 lstatus = ncx_getn_int_double(&xp, nget, value);
03391                 if(lstatus != NC_NOERR && status == NC_NOERR)
03392                         status = lstatus;
03393 
03394                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03395 
03396                 remaining -= extent;
03397                 if(remaining == 0)
03398                         break; /* normal loop exit */
03399                 offset += extent;
03400                 value += nget;
03401         }
03402 
03403         return status;
03404 }
03405 
03406 
03407 static int
03408 getNCvx_float_schar(const NC *ncp, const NC_var *varp,
03409                  const size_t *start, size_t nelems, schar *value)
03410 {
03411         off_t offset = NC_varoffset(ncp, varp, start);
03412         size_t remaining = varp->xsz * nelems;
03413         int status = NC_NOERR;
03414         const void *xp;
03415 
03416         if(nelems == 0)
03417                 return NC_NOERR;
03418 
03419         assert(value != NULL);
03420 
03421         for(;;)
03422         {
03423                 size_t extent = MIN(remaining, ncp->chunk);
03424                 size_t nget = ncx_howmany(varp->type, extent);
03425 
03426                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03427                                  0, (void **)&xp);      /* cast away const */
03428                 if(lstatus != NC_NOERR)
03429                         return lstatus;
03430                 
03431                 lstatus = ncx_getn_float_schar(&xp, nget, value);
03432                 if(lstatus != NC_NOERR && status == NC_NOERR)
03433                         status = lstatus;
03434 
03435                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03436 
03437                 remaining -= extent;
03438                 if(remaining == 0)
03439                         break; /* normal loop exit */
03440                 offset += extent;
03441                 value += nget;
03442         }
03443 
03444         return status;
03445 }
03446 
03447 static int
03448 getNCvx_float_uchar(const NC *ncp, const NC_var *varp,
03449                  const size_t *start, size_t nelems, uchar *value)
03450 {
03451         off_t offset = NC_varoffset(ncp, varp, start);
03452         size_t remaining = varp->xsz * nelems;
03453         int status = NC_NOERR;
03454         const void *xp;
03455 
03456         if(nelems == 0)
03457                 return NC_NOERR;
03458 
03459         assert(value != NULL);
03460 
03461         for(;;)
03462         {
03463                 size_t extent = MIN(remaining, ncp->chunk);
03464                 size_t nget = ncx_howmany(varp->type, extent);
03465 
03466                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03467                                  0, (void **)&xp);      /* cast away const */
03468                 if(lstatus != NC_NOERR)
03469                         return lstatus;
03470                 
03471                 lstatus = ncx_getn_float_uchar(&xp, nget, value);
03472                 if(lstatus != NC_NOERR && status == NC_NOERR)
03473                         status = lstatus;
03474 
03475                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03476 
03477                 remaining -= extent;
03478                 if(remaining == 0)
03479                         break; /* normal loop exit */
03480                 offset += extent;
03481                 value += nget;
03482         }
03483 
03484         return status;
03485 }
03486 
03487 static int
03488 getNCvx_float_short(const NC *ncp, const NC_var *varp,
03489                  const size_t *start, size_t nelems, short *value)
03490 {
03491         off_t offset = NC_varoffset(ncp, varp, start);
03492         size_t remaining = varp->xsz * nelems;
03493         int status = NC_NOERR;
03494         const void *xp;
03495 
03496         if(nelems == 0)
03497                 return NC_NOERR;
03498 
03499         assert(value != NULL);
03500 
03501         for(;;)
03502         {
03503                 size_t extent = MIN(remaining, ncp->chunk);
03504                 size_t nget = ncx_howmany(varp->type, extent);
03505 
03506                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03507                                  0, (void **)&xp);      /* cast away const */
03508                 if(lstatus != NC_NOERR)
03509                         return lstatus;
03510                 
03511                 lstatus = ncx_getn_float_short(&xp, nget, value);
03512                 if(lstatus != NC_NOERR && status == NC_NOERR)
03513                         status = lstatus;
03514 
03515                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03516 
03517                 remaining -= extent;
03518                 if(remaining == 0)
03519                         break; /* normal loop exit */
03520                 offset += extent;
03521                 value += nget;
03522         }
03523 
03524         return status;
03525 }
03526 
03527 static int
03528 getNCvx_float_int(const NC *ncp, const NC_var *varp,
03529                  const size_t *start, size_t nelems, int *value)
03530 {
03531         off_t offset = NC_varoffset(ncp, varp, start);
03532         size_t remaining = varp->xsz * nelems;
03533         int status = NC_NOERR;
03534         const void *xp;
03535 
03536         if(nelems == 0)
03537                 return NC_NOERR;
03538 
03539         assert(value != NULL);
03540 
03541         for(;;)
03542         {
03543                 size_t extent = MIN(remaining, ncp->chunk);
03544                 size_t nget = ncx_howmany(varp->type, extent);
03545 
03546                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03547                                  0, (void **)&xp);      /* cast away const */
03548                 if(lstatus != NC_NOERR)
03549                         return lstatus;
03550                 
03551                 lstatus = ncx_getn_float_int(&xp, nget, value);
03552                 if(lstatus != NC_NOERR && status == NC_NOERR)
03553                         status = lstatus;
03554 
03555                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03556 
03557                 remaining -= extent;
03558                 if(remaining == 0)
03559                         break; /* normal loop exit */
03560                 offset += extent;
03561                 value += nget;
03562         }
03563 
03564         return status;
03565 }
03566 
03567 static int
03568 getNCvx_float_long(const NC *ncp, const NC_var *varp,
03569                  const size_t *start, size_t nelems, long *value)
03570 {
03571         off_t offset = NC_varoffset(ncp, varp, start);
03572         size_t remaining = varp->xsz * nelems;
03573         int status = NC_NOERR;
03574         const void *xp;
03575 
03576         if(nelems == 0)
03577                 return NC_NOERR;
03578 
03579         assert(value != NULL);
03580 
03581         for(;;)
03582         {
03583                 size_t extent = MIN(remaining, ncp->chunk);
03584                 size_t nget = ncx_howmany(varp->type, extent);
03585 
03586                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03587                                  0, (void **)&xp);      /* cast away const */
03588                 if(lstatus != NC_NOERR)
03589                         return lstatus;
03590                 
03591                 lstatus = ncx_getn_float_long(&xp, nget, value);
03592                 if(lstatus != NC_NOERR && status == NC_NOERR)
03593                         status = lstatus;
03594 
03595                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03596 
03597                 remaining -= extent;
03598                 if(remaining == 0)
03599                         break; /* normal loop exit */
03600                 offset += extent;
03601                 value += nget;
03602         }
03603 
03604         return status;
03605 }
03606 
03607 static int
03608 getNCvx_float_float(const NC *ncp, const NC_var *varp,
03609                  const size_t *start, size_t nelems, float *value)
03610 {
03611         off_t offset = NC_varoffset(ncp, varp, start);
03612         size_t remaining = varp->xsz * nelems;
03613         int status = NC_NOERR;
03614         const void *xp;
03615 
03616         if(nelems == 0)
03617                 return NC_NOERR;
03618 
03619         assert(value != NULL);
03620 
03621         for(;;)
03622         {
03623                 size_t extent = MIN(remaining, ncp->chunk);
03624                 size_t nget = ncx_howmany(varp->type, extent);
03625 
03626                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03627                                  0, (void **)&xp);      /* cast away const */
03628                 if(lstatus != NC_NOERR)
03629                         return lstatus;
03630                 
03631                 lstatus = ncx_getn_float_float(&xp, nget, value);
03632                 if(lstatus != NC_NOERR && status == NC_NOERR)
03633                         status = lstatus;
03634 
03635                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03636 
03637                 remaining -= extent;
03638                 if(remaining == 0)
03639                         break; /* normal loop exit */
03640                 offset += extent;
03641                 value += nget;
03642         }
03643 
03644         return status;
03645 }
03646 
03647 static int
03648 getNCvx_float_double(const NC *ncp, const NC_var *varp,
03649                  const size_t *start, size_t nelems, double *value)
03650 {
03651         off_t offset = NC_varoffset(ncp, varp, start);
03652         size_t remaining = varp->xsz * nelems;
03653         int status = NC_NOERR;
03654         const void *xp;
03655 
03656         if(nelems == 0)
03657                 return NC_NOERR;
03658 
03659         assert(value != NULL);
03660 
03661         for(;;)
03662         {
03663                 size_t extent = MIN(remaining, ncp->chunk);
03664                 size_t nget = ncx_howmany(varp->type, extent);
03665 
03666                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03667                                  0, (void **)&xp);      /* cast away const */
03668                 if(lstatus != NC_NOERR)
03669                         return lstatus;
03670                 
03671                 lstatus = ncx_getn_float_double(&xp, nget, value);
03672                 if(lstatus != NC_NOERR && status == NC_NOERR)
03673                         status = lstatus;
03674 
03675                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03676 
03677                 remaining -= extent;
03678                 if(remaining == 0)
03679                         break; /* normal loop exit */
03680                 offset += extent;
03681                 value += nget;
03682         }
03683 
03684         return status;
03685 }
03686 
03687 
03688 static int
03689 getNCvx_double_schar(const NC *ncp, const NC_var *varp,
03690                  const size_t *start, size_t nelems, schar *value)
03691 {
03692         off_t offset = NC_varoffset(ncp, varp, start);
03693         size_t remaining = varp->xsz * nelems;
03694         int status = NC_NOERR;
03695         const void *xp;
03696 
03697         if(nelems == 0)
03698                 return NC_NOERR;
03699 
03700         assert(value != NULL);
03701 
03702         for(;;)
03703         {
03704                 size_t extent = MIN(remaining, ncp->chunk);
03705                 size_t nget = ncx_howmany(varp->type, extent);
03706 
03707                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03708                                  0, (void **)&xp);      /* cast away const */
03709                 if(lstatus != NC_NOERR)
03710                         return lstatus;
03711                 
03712                 lstatus = ncx_getn_double_schar(&xp, nget, value);
03713                 if(lstatus != NC_NOERR && status == NC_NOERR)
03714                         status = lstatus;
03715 
03716                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03717 
03718                 remaining -= extent;
03719                 if(remaining == 0)
03720                         break; /* normal loop exit */
03721                 offset += extent;
03722                 value += nget;
03723         }
03724 
03725         return status;
03726 }
03727 
03728 static int
03729 getNCvx_double_uchar(const NC *ncp, const NC_var *varp,
03730                  const size_t *start, size_t nelems, uchar *value)
03731 {
03732         off_t offset = NC_varoffset(ncp, varp, start);
03733         size_t remaining = varp->xsz * nelems;
03734         int status = NC_NOERR;
03735         const void *xp;
03736 
03737         if(nelems == 0)
03738                 return NC_NOERR;
03739 
03740         assert(value != NULL);
03741 
03742         for(;;)
03743         {
03744                 size_t extent = MIN(remaining, ncp->chunk);
03745                 size_t nget = ncx_howmany(varp->type, extent);
03746 
03747                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03748                                  0, (void **)&xp);      /* cast away const */
03749                 if(lstatus != NC_NOERR)
03750                         return lstatus;
03751                 
03752                 lstatus = ncx_getn_double_uchar(&xp, nget, value);
03753                 if(lstatus != NC_NOERR && status == NC_NOERR)
03754                         status = lstatus;
03755 
03756                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03757 
03758                 remaining -= extent;
03759                 if(remaining == 0)
03760                         break; /* normal loop exit */
03761                 offset += extent;
03762                 value += nget;
03763         }
03764 
03765         return status;
03766 }
03767 
03768 static int
03769 getNCvx_double_short(const NC *ncp, const NC_var *varp,
03770                  const size_t *start, size_t nelems, short *value)
03771 {
03772         off_t offset = NC_varoffset(ncp, varp, start);
03773         size_t remaining = varp->xsz * nelems;
03774         int status = NC_NOERR;
03775         const void *xp;
03776 
03777         if(nelems == 0)
03778                 return NC_NOERR;
03779 
03780         assert(value != NULL);
03781 
03782         for(;;)
03783         {
03784                 size_t extent = MIN(remaining, ncp->chunk);
03785                 size_t nget = ncx_howmany(varp->type, extent);
03786 
03787                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03788                                  0, (void **)&xp);      /* cast away const */
03789                 if(lstatus != NC_NOERR)
03790                         return lstatus;
03791                 
03792                 lstatus = ncx_getn_double_short(&xp, nget, value);
03793                 if(lstatus != NC_NOERR && status == NC_NOERR)
03794                         status = lstatus;
03795 
03796                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03797 
03798                 remaining -= extent;
03799                 if(remaining == 0)
03800                         break; /* normal loop exit */
03801                 offset += extent;
03802                 value += nget;
03803         }
03804 
03805         return status;
03806 }
03807 
03808 static int
03809 getNCvx_double_int(const NC *ncp, const NC_var *varp,
03810                  const size_t *start, size_t nelems, int *value)
03811 {
03812         off_t offset = NC_varoffset(ncp, varp, start);
03813         size_t remaining = varp->xsz * nelems;
03814         int status = NC_NOERR;
03815         const void *xp;
03816 
03817         if(nelems == 0)
03818                 return NC_NOERR;
03819 
03820         assert(value != NULL);
03821 
03822         for(;;)
03823         {
03824                 size_t extent = MIN(remaining, ncp->chunk);
03825                 size_t nget = ncx_howmany(varp->type, extent);
03826 
03827                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03828                                  0, (void **)&xp);      /* cast away const */
03829                 if(lstatus != NC_NOERR)
03830                         return lstatus;
03831                 
03832                 lstatus = ncx_getn_double_int(&xp, nget, value);
03833                 if(lstatus != NC_NOERR && status == NC_NOERR)
03834                         status = lstatus;
03835 
03836                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03837 
03838                 remaining -= extent;
03839                 if(remaining == 0)
03840                         break; /* normal loop exit */
03841                 offset += extent;
03842                 value += nget;
03843         }
03844 
03845         return status;
03846 }
03847 
03848 static int
03849 getNCvx_double_long(const NC *ncp, const NC_var *varp,
03850                  const size_t *start, size_t nelems, long *value)
03851 {
03852         off_t offset = NC_varoffset(ncp, varp, start);
03853         size_t remaining = varp->xsz * nelems;
03854         int status = NC_NOERR;
03855         const void *xp;
03856 
03857         if(nelems == 0)
03858                 return NC_NOERR;
03859 
03860         assert(value != NULL);
03861 
03862         for(;;)
03863         {
03864                 size_t extent = MIN(remaining, ncp->chunk);
03865                 size_t nget = ncx_howmany(varp->type, extent);
03866 
03867                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03868                                  0, (void **)&xp);      /* cast away const */
03869                 if(lstatus != NC_NOERR)
03870                         return lstatus;
03871                 
03872                 lstatus = ncx_getn_double_long(&xp, nget, value);
03873                 if(lstatus != NC_NOERR && status == NC_NOERR)
03874                         status = lstatus;
03875 
03876                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03877 
03878                 remaining -= extent;
03879                 if(remaining == 0)
03880                         break; /* normal loop exit */
03881                 offset += extent;
03882                 value += nget;
03883         }
03884 
03885         return status;
03886 }
03887 
03888 static int
03889 getNCvx_double_float(const NC *ncp, const NC_var *varp,
03890                  const size_t *start, size_t nelems, float *value)
03891 {
03892         off_t offset = NC_varoffset(ncp, varp, start);
03893         size_t remaining = varp->xsz * nelems;
03894         int status = NC_NOERR;
03895         const void *xp;
03896 
03897         if(nelems == 0)
03898                 return NC_NOERR;
03899 
03900         assert(value != NULL);
03901 
03902         for(;;)
03903         {
03904                 size_t extent = MIN(remaining, ncp->chunk);
03905                 size_t nget = ncx_howmany(varp->type, extent);
03906 
03907                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03908                                  0, (void **)&xp);      /* cast away const */
03909                 if(lstatus != NC_NOERR)
03910                         return lstatus;
03911                 
03912                 lstatus = ncx_getn_double_float(&xp, nget, value);
03913                 if(lstatus != NC_NOERR && status == NC_NOERR)
03914                         status = lstatus;
03915 
03916                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03917 
03918                 remaining -= extent;
03919                 if(remaining == 0)
03920                         break; /* normal loop exit */
03921                 offset += extent;
03922                 value += nget;
03923         }
03924 
03925         return status;
03926 }
03927 
03928 static int
03929 getNCvx_double_double(const NC *ncp, const NC_var *varp,
03930                  const size_t *start, size_t nelems, double *value)
03931 {
03932         off_t offset = NC_varoffset(ncp, varp, start);
03933         size_t remaining = varp->xsz * nelems;
03934         int status = NC_NOERR;
03935         const void *xp;
03936 
03937         if(nelems == 0)
03938                 return NC_NOERR;
03939 
03940         assert(value != NULL);
03941 
03942         for(;;)
03943         {
03944                 size_t extent = MIN(remaining, ncp->chunk);
03945                 size_t nget = ncx_howmany(varp->type, extent);
03946 
03947                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03948                                  0, (void **)&xp);      /* cast away const */
03949                 if(lstatus != NC_NOERR)
03950                         return lstatus;
03951                 
03952                 lstatus = ncx_getn_double_double(&xp, nget, value);
03953                 if(lstatus != NC_NOERR && status == NC_NOERR)
03954                         status = lstatus;
03955 
03956                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03957 
03958                 remaining -= extent;
03959                 if(remaining == 0)
03960                         break; /* normal loop exit */
03961                 offset += extent;
03962                 value += nget;
03963         }
03964 
03965         return status;
03966 }
03967 
03968 
03969 
03970 
03971 static int
03972 getNCv_schar(const NC *ncp, const NC_var *varp,
03973                  const size_t *start, size_t nelems, schar *value)
03974 {
03975         switch(varp->type){
03976         case NC_CHAR:
03977                 return NC_ECHAR;
03978         case NC_BYTE:
03979                 return getNCvx_schar_schar(ncp, varp, start, nelems,
03980                         value);
03981         case NC_SHORT:
03982                 return getNCvx_short_schar(ncp, varp, start, nelems,
03983                         value);
03984         case NC_INT:
03985                 return getNCvx_int_schar(ncp, varp, start, nelems,
03986                         value);
03987         case NC_FLOAT:
03988                 return getNCvx_float_schar(ncp, varp, start, nelems,
03989                         value);
03990         case NC_DOUBLE: 
03991                 return getNCvx_double_schar(ncp, varp, start, nelems,
03992                         value);
03993         }
03994         return NC_EBADTYPE;
03995 }
03996 
03997 static int
03998 getNCv_uchar(const NC *ncp, const NC_var *varp,
03999                  const size_t *start, size_t nelems, uchar *value)
04000 {
04001         switch(varp->type){
04002         case NC_CHAR:
04003                 return NC_ECHAR;
04004         case NC_BYTE:
04005                 return getNCvx_schar_uchar(ncp, varp, start, nelems,
04006                         value);
04007         case NC_SHORT:
04008                 return getNCvx_short_uchar(ncp, varp, start, nelems,
04009                         value);
04010         case NC_INT:
04011                 return getNCvx_int_uchar(ncp, varp, start, nelems,
04012                         value);
04013         case NC_FLOAT:
04014                 return getNCvx_float_uchar(ncp, varp, start, nelems,
04015                         value);
04016         case NC_DOUBLE: 
04017                 return getNCvx_double_uchar(ncp, varp, start, nelems,
04018                         value);
04019         }
04020         return NC_EBADTYPE;
04021 }
04022 
04023 static int
04024 getNCv_short(const NC *ncp, const NC_var *varp,
04025                  const size_t *start, size_t nelems, short *value)
04026 {
04027         switch(varp->type){
04028         case NC_CHAR:
04029                 return NC_ECHAR;
04030         case NC_BYTE:
04031                 return getNCvx_schar_short(ncp, varp, start, nelems,
04032                         value);
04033         case NC_SHORT:
04034                 return getNCvx_short_short(ncp, varp, start, nelems,
04035                         value);
04036         case NC_INT:
04037                 return getNCvx_int_short(ncp, varp, start, nelems,
04038                         value);
04039         case NC_FLOAT:
04040                 return getNCvx_float_short(ncp, varp, start, nelems,
04041                         value);
04042         case NC_DOUBLE: 
04043                 return getNCvx_double_short(ncp, varp, start, nelems,
04044                         value);
04045         }
04046         return NC_EBADTYPE;
04047 }
04048 
04049 static int
04050 getNCv_int(const NC *ncp, const NC_var *varp,
04051                  const size_t *start, size_t nelems, int *value)
04052 {
04053         switch(varp->type){
04054         case NC_CHAR:
04055                 return NC_ECHAR;
04056         case NC_BYTE:
04057                 return getNCvx_schar_int(ncp, varp, start, nelems,
04058                         value);
04059         case NC_SHORT:
04060                 return getNCvx_short_int(ncp, varp, start, nelems,
04061                         value);
04062         case NC_INT:
04063                 return getNCvx_int_int(ncp, varp, start, nelems,
04064                         value);
04065         case NC_FLOAT:
04066                 return getNCvx_float_int(ncp, varp, start, nelems,
04067                         value);
04068         case NC_DOUBLE: 
04069                 return getNCvx_double_int(ncp, varp, start, nelems,
04070                         value);
04071         }
04072         return NC_EBADTYPE;
04073 }
04074 
04075 static int
04076 getNCv_long(const NC *ncp, const NC_var *varp,
04077                  const size_t *start, size_t nelems, long *value)
04078 {
04079         switch(varp->type){
04080         case NC_CHAR:
04081                 return NC_ECHAR;
04082         case NC_BYTE:
04083                 return getNCvx_schar_long(ncp, varp, start, nelems,
04084                         value);
04085         case NC_SHORT:
04086                 return getNCvx_short_long(ncp, varp, start, nelems,
04087                         value);
04088         case NC_INT:
04089                 return getNCvx_int_long(ncp, varp, start, nelems,
04090                         value);
04091         case NC_FLOAT:
04092                 return getNCvx_float_long(ncp, varp, start, nelems,
04093                         value);
04094         case NC_DOUBLE: 
04095                 return getNCvx_double_long(ncp, varp, start, nelems,
04096                         value);
04097         }
04098         return NC_EBADTYPE;
04099 }
04100 
04101 static int
04102 getNCv_float(const NC *ncp, const NC_var *varp,
04103                  const size_t *start, size_t nelems, float *value)
04104 {
04105         switch(varp->type){
04106         case NC_CHAR:
04107                 return NC_ECHAR;
04108         case NC_BYTE:
04109                 return getNCvx_schar_float(ncp, varp, start, nelems,
04110                         value);
04111         case NC_SHORT:
04112                 return getNCvx_short_float(ncp, varp, start, nelems,
04113                         value);
04114         case NC_INT:
04115                 return getNCvx_int_float(ncp, varp, start, nelems,
04116                         value);
04117         case NC_FLOAT:
04118                 return getNCvx_float_float(ncp, varp, start, nelems,
04119                         value);
04120         case NC_DOUBLE: 
04121                 return getNCvx_double_float(ncp, varp, start, nelems,
04122                         value);
04123         }
04124         return NC_EBADTYPE;
04125 }
04126 
04127 static int
04128 getNCv_double(const NC *ncp, const NC_var *varp,
04129                  const size_t *start, size_t nelems, double *value)
04130 {
04131         switch(varp->type){
04132         case NC_CHAR:
04133                 return NC_ECHAR;
04134         case NC_BYTE:
04135                 return getNCvx_schar_double(ncp, varp, start, nelems,
04136                         value);
04137         case NC_SHORT:
04138                 return getNCvx_short_double(ncp, varp, start, nelems,
04139                         value);
04140         case NC_INT:
04141                 return getNCvx_int_double(ncp, varp, start, nelems,
04142                         value);
04143         case NC_FLOAT:
04144                 return getNCvx_float_double(ncp, varp, start, nelems,
04145                         value);
04146         case NC_DOUBLE: 
04147                 return getNCvx_double_double(ncp, varp, start, nelems,
04148                         value);
04149         }
04150         return NC_EBADTYPE;
04151 }
04152 
04153 
04154 
04155 static int
04156 getNCv_text(const NC *ncp, const NC_var *varp,
04157                  const size_t *start, size_t nelems, char *value)
04158 {
04159         if(varp->type != NC_CHAR)
04160                 return NC_ECHAR;
04161         return getNCvx_char_char(ncp, varp, start, nelems, value);
04162 }
04163 
04164 
04165 /*
04166  * Copy 'nbytes' contiguous external values
04167  * from ('inncp', invp', inncoord')
04168  * to   ('outncp', 'outvp', 'outcoord')
04169  * 'inncp' shouldn't be the same as 'outncp'.
04170  * Used only by ncvarcopy()
04171  */
04172 static int
04173 NCxvarcpy(NC *inncp, NC_var *invp, size_t *incoord,
04174         NC *outncp, NC_var *outvp, size_t *outcoord, size_t nbytes)
04175 {
04176         int status;
04177         off_t inoffset = NC_varoffset(inncp, invp, incoord);
04178         off_t outoffset = NC_varoffset(outncp, outvp, outcoord);
04179         void *inxp;
04180         void *outxp;
04181         const size_t chunk = MIN(inncp->chunk, outncp->chunk);
04182 
04183         do {
04184                 const size_t extent = MIN(nbytes, chunk);
04185 
04186                 status = inncp->nciop->get(inncp->nciop, inoffset, extent,
04187                                  0, &inxp);     
04188                 if(status != NC_NOERR)
04189                         return status;
04190 
04191                 status = outncp->nciop->get(outncp->nciop, outoffset, extent,
04192                                  RGN_WRITE, &outxp);    
04193                 if(status != NC_NOERR)
04194                 {
04195                         (void) inncp->nciop->rel(inncp->nciop, inoffset, 0);    
04196                         break;
04197                 }
04198 
04199                 (void) memcpy(outxp, inxp, extent);
04200 
04201                 status = outncp->nciop->rel(outncp->nciop, outoffset,
04202                          RGN_MODIFIED);
04203                 (void) inncp->nciop->rel(inncp->nciop, inoffset, 0);    
04204 
04205                 nbytes -= extent;
04206                 if(nbytes == 0)
04207                         break; /* normal loop exit */
04208                 inoffset += extent;
04209                 outoffset += extent;
04210                 
04211         } while (status == NC_NOERR);
04212 
04213         return status;
04214 }
04215 
04216 
04217 /*
04218  *  For ncvar{put,get},
04219  *  find the largest contiguous block from within 'edges'.
04220  *  returns the index to the left of this (which may be -1).
04221  *  Compute the number of contiguous elements and return
04222  *  that in *iocountp.
04223  *  The presence of "record" variables makes this routine
04224  *  overly subtle.
04225  */
04226 static int
04227 NCiocount(const NC *const ncp, const NC_var *const varp,
04228         const size_t *const edges,
04229         size_t *const iocountp)
04230 {
04231         const size_t *edp0 = edges;
04232         const size_t *edp = edges + varp->ndims;
04233         const size_t *shp = varp->shape + varp->ndims;
04234 
04235         if(IS_RECVAR(varp))
04236         {
04237                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
04238                 {
04239                         /* one dimensional && the only 'record' variable */
04240                         *iocountp = *edges;
04241                         return(0);
04242                 }
04243                 /* else */
04244                 edp0++;
04245         }
04246 
04247         assert(edges != NULL);
04248 
04249         /* find max contiguous */
04250         while(edp > edp0)
04251         {
04252                 shp--; edp--;
04253                 if(*edp < *shp )
04254                 {
04255                         const size_t *zedp = edp;
04256                         while(zedp >= edp0)
04257                         {
04258                                 if(*zedp == 0)
04259                                 {
04260                                         *iocountp = 0;
04261                                         goto done;
04262                                 }
04263                                 /* Tip of the hat to segmented architectures */
04264                                 if(zedp == edp0)
04265                                         break;
04266                                 zedp--;
04267                         }
04268                         break;
04269                 }
04270                 assert(*edp == *shp);
04271         }
04272 
04273         /*
04274          * edp, shp reference rightmost index s.t. *(edp +1) == *(shp +1)
04275          *
04276          * Or there is only one dimension.
04277          * If there is only one dimension and it is 'non record' dimension,
04278          *      edp is &edges[0] and we will return -1.
04279          * If there is only one dimension and and it is a "record dimension",
04280          *      edp is &edges[1] (out of bounds) and we will return 0;
04281          */
04282         assert(shp >= varp->shape + varp->ndims -1 
04283                 || *(edp +1) == *(shp +1));
04284 
04285         /* now accumulate max count for a single io operation */
04286         for(*iocountp = 1, edp0 = edp;
04287                         edp0 < edges + varp->ndims;
04288                         edp0++)
04289         {
04290                 *iocountp *= *edp0;
04291         }
04292 
04293 done:
04294         return((int)(edp - edges) - 1);
04295 }
04296 
04297 
04298 /*
04299  * Set the elements of the array 'upp' to
04300  * the sum of the corresponding elements of
04301  * 'stp' and 'edp'. 'end' should be &stp[nelems].
04302  */
04303 static void
04304 set_upper(size_t *upp, /* modified on return */
04305         const size_t *stp,
04306         const size_t *edp,
04307         const size_t *const end)
04308 {
04309         while(upp < end) {
04310                 *upp++ = *stp++ + *edp++;
04311         }
04312 }
04313 
04314 
04315 /*
04316  * The infamous and oft-discussed odometer code.
04317  *
04318  * 'start[]' is the starting coordinate.
04319  * 'upper[]' is the upper bound s.t. start[ii] < upper[ii].
04320  * 'coord[]' is the register, the current coordinate value.
04321  * For some ii,
04322  * upp == &upper[ii]
04323  * cdp == &coord[ii]
04324  * 
04325  * Running this routine increments *cdp.
04326  *
04327  * If after the increment, *cdp is equal to *upp
04328  * (and cdp is not the leftmost dimension),
04329  * *cdp is "zeroed" to the starting value and
04330  * we need to "carry", eg, increment one place to
04331  * the left.
04332  * 
04333  * TODO: Some architectures hate recursion?
04334  *      Reimplement non-recursively.
04335  */
04336 static void
04337 odo1(const size_t *const start, const size_t *const upper,
04338         size_t *const coord, /* modified on return */
04339         const size_t *upp,
04340         size_t *cdp)
04341 {
04342         assert(coord <= cdp && cdp <= coord + NC_MAX_VAR_DIMS);
04343         assert(upper <= upp && upp <= upper + NC_MAX_VAR_DIMS);
04344         assert(upp - upper == cdp - coord);
04345         
04346         assert(*cdp <= *upp);
04347 
04348         (*cdp)++;
04349         if(cdp != coord && *cdp >= *upp)
04350         {
04351                 *cdp = start[cdp - coord];
04352                 odo1(start, upper, coord, upp -1, cdp -1);
04353         }
04354 }
04355 #ifdef _CRAYC
04356 #pragma _CRI noinline odo1
04357 #endif
04358 
04359 
04360 
04361 
04362 /* Public */
04363 
04364 
04365 int
04366 nc_put_var1_text(int ncid, int varid, const size_t *coord,
04367         const char *value)
04368 {
04369         int status;
04370         NC *ncp;
04371         const NC_var *varp;
04372 
04373         status = NC_check_id(ncid, &ncp); 
04374         if(status != NC_NOERR)
04375                 return status;
04376 
04377         if(NC_readonly(ncp))
04378                 return NC_EPERM;
04379 
04380         if(NC_indef(ncp))
04381                 return NC_EINDEFINE;
04382 
04383         varp = NC_lookupvar(ncp, varid);
04384         if(varp == NULL)
04385                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04386 
04387         if(varp->type != NC_CHAR)
04388                 return NC_ECHAR;
04389 
04390         status = NCcoordck(ncp, varp, coord);
04391         if(status != NC_NOERR)
04392                 return status;
04393 
04394         if(IS_RECVAR(varp))
04395         {
04396                 status = NCvnrecs(ncp, *coord +1);
04397                 if(status != NC_NOERR)
04398                         return status;
04399         }
04400 
04401         return putNCv_text(ncp, varp, coord, 1, value);
04402 }
04403 
04404 
04405 int
04406 nc_put_var1_uchar(int ncid, int varid, const size_t *coord,
04407         const uchar *value)
04408 {
04409         int status;
04410         NC *ncp;
04411         const NC_var *varp;
04412 
04413         status = NC_check_id(ncid, &ncp); 
04414         if(status != NC_NOERR)
04415                 return status;
04416 
04417         if(NC_readonly(ncp))
04418                 return NC_EPERM;
04419 
04420         if(NC_indef(ncp))
04421                 return NC_EINDEFINE;
04422 
04423         varp = NC_lookupvar(ncp, varid);
04424         if(varp == NULL)
04425                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04426 
04427         if(varp->type == NC_CHAR)
04428                 return NC_ECHAR;
04429 
04430         status = NCcoordck(ncp, varp, coord);
04431         if(status != NC_NOERR)
04432                 return status;
04433 
04434         if(IS_RECVAR(varp))
04435         {
04436                 status = NCvnrecs(ncp, *coord +1);
04437                 if(status != NC_NOERR)
04438                         return status;
04439         }
04440 
04441         return putNCv_uchar(ncp, varp, coord, 1, value);
04442 }
04443 
04444 int
04445 nc_put_var1_schar(int ncid, int varid, const size_t *coord,
04446         const schar *value)
04447 {
04448         int status;
04449         NC *ncp;
04450         const NC_var *varp;
04451 
04452         status = NC_check_id(ncid, &ncp); 
04453         if(status != NC_NOERR)
04454                 return status;
04455 
04456         if(NC_readonly(ncp))
04457                 return NC_EPERM;
04458 
04459         if(NC_indef(ncp))
04460                 return NC_EINDEFINE;
04461 
04462         varp = NC_lookupvar(ncp, varid);
04463         if(varp == NULL)
04464                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04465 
04466         if(varp->type == NC_CHAR)
04467                 return NC_ECHAR;
04468 
04469         status = NCcoordck(ncp, varp, coord);
04470         if(status != NC_NOERR)
04471                 return status;
04472 
04473         if(IS_RECVAR(varp))
04474         {
04475                 status = NCvnrecs(ncp, *coord +1);
04476                 if(status != NC_NOERR)
04477                         return status;
04478         }
04479 
04480         return putNCv_schar(ncp, varp, coord, 1, value);
04481 }
04482 
04483 int
04484 nc_put_var1_short(int ncid, int varid, const size_t *coord,
04485         const short *value)
04486 {
04487         int status;
04488         NC *ncp;
04489         const NC_var *varp;
04490 
04491         status = NC_check_id(ncid, &ncp); 
04492         if(status != NC_NOERR)
04493                 return status;
04494 
04495         if(NC_readonly(ncp))
04496                 return NC_EPERM;
04497 
04498         if(NC_indef(ncp))
04499                 return NC_EINDEFINE;
04500 
04501         varp = NC_lookupvar(ncp, varid);
04502         if(varp == NULL)
04503                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04504 
04505         if(varp->type == NC_CHAR)
04506                 return NC_ECHAR;
04507 
04508         status = NCcoordck(ncp, varp, coord);
04509         if(status != NC_NOERR)
04510                 return status;
04511 
04512         if(IS_RECVAR(varp))
04513         {
04514                 status = NCvnrecs(ncp, *coord +1);
04515                 if(status != NC_NOERR)
04516                         return status;
04517         }
04518 
04519         return putNCv_short(ncp, varp, coord, 1, value);
04520 }
04521 
04522 int
04523 nc_put_var1_int(int ncid, int varid, const size_t *coord,
04524         const int *value)
04525 {
04526         int status;
04527         NC *ncp;
04528         const NC_var *varp;
04529 
04530         status = NC_check_id(ncid, &ncp); 
04531         if(status != NC_NOERR)
04532                 return status;
04533 
04534         if(NC_readonly(ncp))
04535                 return NC_EPERM;
04536 
04537         if(NC_indef(ncp))
04538                 return NC_EINDEFINE;
04539 
04540         varp = NC_lookupvar(ncp, varid);
04541         if(varp == NULL)
04542                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04543 
04544         if(varp->type == NC_CHAR)
04545                 return NC_ECHAR;
04546 
04547         status = NCcoordck(ncp, varp, coord);
04548         if(status != NC_NOERR)
04549                 return status;
04550 
04551         if(IS_RECVAR(varp))
04552         {
04553                 status = NCvnrecs(ncp, *coord +1);
04554                 if(status != NC_NOERR)
04555                         return status;
04556         }
04557 
04558         return putNCv_int(ncp, varp, coord, 1, value);
04559 }
04560 
04561 int
04562 nc_put_var1_long(int ncid, int varid, const size_t *coord,
04563         const long *value)
04564 {
04565         int status;
04566         NC *ncp;
04567         const NC_var *varp;
04568 
04569         status = NC_check_id(ncid, &ncp); 
04570         if(status != NC_NOERR)
04571                 return status;
04572 
04573         if(NC_readonly(ncp))
04574                 return NC_EPERM;
04575 
04576         if(NC_indef(ncp))
04577                 return NC_EINDEFINE;
04578 
04579         varp = NC_lookupvar(ncp, varid);
04580         if(varp == NULL)
04581                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04582 
04583         if(varp->type == NC_CHAR)
04584                 return NC_ECHAR;
04585 
04586         status = NCcoordck(ncp, varp, coord);
04587         if(status != NC_NOERR)
04588                 return status;
04589 
04590         if(IS_RECVAR(varp))
04591         {
04592                 status = NCvnrecs(ncp, *coord +1);
04593                 if(status != NC_NOERR)
04594                         return status;
04595         }
04596 
04597         return putNCv_long(ncp, varp, coord, 1, value);
04598 }
04599 
04600 int
04601 nc_put_var1_float(int ncid, int varid, const size_t *coord,
04602         const float *value)
04603 {
04604         int status;
04605         NC *ncp;
04606         const NC_var *varp;
04607 
04608         status = NC_check_id(ncid, &ncp); 
04609         if(status != NC_NOERR)
04610                 return status;
04611 
04612         if(NC_readonly(ncp))
04613                 return NC_EPERM;
04614 
04615         if(NC_indef(ncp))
04616                 return NC_EINDEFINE;
04617 
04618         varp = NC_lookupvar(ncp, varid);
04619         if(varp == NULL)
04620                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04621 
04622         if(varp->type == NC_CHAR)
04623                 return NC_ECHAR;
04624 
04625         status = NCcoordck(ncp, varp, coord);
04626         if(status != NC_NOERR)
04627                 return status;
04628 
04629         if(IS_RECVAR(varp))
04630         {
04631                 status = NCvnrecs(ncp, *coord +1);
04632                 if(status != NC_NOERR)
04633                         return status;
04634         }
04635 
04636         return putNCv_float(ncp, varp, coord, 1, value);
04637 }
04638 
04639 int
04640 nc_put_var1_double(int ncid, int varid, const size_t *coord,
04641         const double *value)
04642 {
04643         int status;
04644         NC *ncp;
04645         const NC_var *varp;
04646 
04647         status = NC_check_id(ncid, &ncp); 
04648         if(status != NC_NOERR)
04649                 return status;
04650 
04651         if(NC_readonly(ncp))
04652                 return NC_EPERM;
04653 
04654         if(NC_indef(ncp))
04655                 return NC_EINDEFINE;
04656 
04657         varp = NC_lookupvar(ncp, varid);
04658         if(varp == NULL)
04659                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04660 
04661         if(varp->type == NC_CHAR)
04662                 return NC_ECHAR;
04663 
04664         status = NCcoordck(ncp, varp, coord);
04665         if(status != NC_NOERR)
04666                 return status;
04667 
04668         if(IS_RECVAR(varp))
04669         {
04670                 status = NCvnrecs(ncp, *coord +1);
04671                 if(status != NC_NOERR)
04672                         return status;
04673         }
04674 
04675         return putNCv_double(ncp, varp, coord, 1, value);
04676 }
04677 
04678 
04679 
04680 int
04681 nc_get_var1_text(int ncid, int varid, const size_t *coord, char *value)
04682 {
04683         int status;
04684         NC *ncp;
04685         const NC_var *varp;
04686 
04687         status = NC_check_id(ncid, &ncp); 
04688         if(status != NC_NOERR)
04689                 return status;
04690 
04691         if(NC_indef(ncp))
04692                 return NC_EINDEFINE;
04693 
04694         varp = NC_lookupvar(ncp, varid);
04695         if(varp == NULL)
04696                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04697 
04698         if(varp->type != NC_CHAR)
04699                 return NC_ECHAR;
04700 
04701         status = NCcoordck(ncp, varp, coord);
04702         if(status != NC_NOERR)
04703                 return status;
04704 
04705         return getNCv_text(ncp, varp, coord, 1, value);
04706 }
04707 
04708 
04709 int
04710 nc_get_var1_uchar(int ncid, int varid, const size_t *coord, uchar *value)
04711 {
04712         int status;
04713         NC *ncp;
04714         const NC_var *varp;
04715 
04716         status = NC_check_id(ncid, &ncp); 
04717         if(status != NC_NOERR)
04718                 return status;
04719 
04720         if(NC_indef(ncp))
04721                 return NC_EINDEFINE;
04722 
04723         varp = NC_lookupvar(ncp, varid);
04724         if(varp == NULL)
04725                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04726 
04727         if(varp->type == NC_CHAR)
04728                 return NC_ECHAR;
04729 
04730         status = NCcoordck(ncp, varp, coord);
04731         if(status != NC_NOERR)
04732                 return status;
04733 
04734         return getNCv_uchar(ncp, varp, coord, 1, value);
04735 }
04736 
04737 int
04738 nc_get_var1_schar(int ncid, int varid, const size_t *coord, schar *value)
04739 {
04740         int status;
04741         NC *ncp;
04742         const NC_var *varp;
04743 
04744         status = NC_check_id(ncid, &ncp); 
04745         if(status != NC_NOERR)
04746                 return status;
04747 
04748         if(NC_indef(ncp))
04749                 return NC_EINDEFINE;
04750 
04751         varp = NC_lookupvar(ncp, varid);
04752         if(varp == NULL)
04753                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04754 
04755         if(varp->type == NC_CHAR)
04756                 return NC_ECHAR;
04757 
04758         status = NCcoordck(ncp, varp, coord);
04759         if(status != NC_NOERR)
04760                 return status;
04761 
04762         return getNCv_schar(ncp, varp, coord, 1, value);
04763 }
04764 
04765 int
04766 nc_get_var1_short(int ncid, int varid, const size_t *coord, short *value)
04767 {
04768         int status;
04769         NC *ncp;
04770         const NC_var *varp;
04771 
04772         status = NC_check_id(ncid, &ncp); 
04773         if(status != NC_NOERR)
04774                 return status;
04775 
04776         if(NC_indef(ncp))
04777                 return NC_EINDEFINE;
04778 
04779         varp = NC_lookupvar(ncp, varid);
04780         if(varp == NULL)
04781                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04782 
04783         if(varp->type == NC_CHAR)
04784                 return NC_ECHAR;
04785 
04786         status = NCcoordck(ncp, varp, coord);
04787         if(status != NC_NOERR)
04788                 return status;
04789 
04790         return getNCv_short(ncp, varp, coord, 1, value);
04791 }
04792 
04793 int
04794 nc_get_var1_int(int ncid, int varid, const size_t *coord, int *value)
04795 {
04796         int status;
04797         NC *ncp;
04798         const NC_var *varp;
04799 
04800         status = NC_check_id(ncid, &ncp); 
04801         if(status != NC_NOERR)
04802                 return status;
04803 
04804         if(NC_indef(ncp))
04805                 return NC_EINDEFINE;
04806 
04807         varp = NC_lookupvar(ncp, varid);
04808         if(varp == NULL)
04809                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04810 
04811         if(varp->type == NC_CHAR)
04812                 return NC_ECHAR;
04813 
04814         status = NCcoordck(ncp, varp, coord);
04815         if(status != NC_NOERR)
04816                 return status;
04817 
04818         return getNCv_int(ncp, varp, coord, 1, value);
04819 }
04820 
04821 int
04822 nc_get_var1_long(int ncid, int varid, const size_t *coord, long *value)
04823 {
04824         int status;
04825         NC *ncp;
04826         const NC_var *varp;
04827 
04828         status = NC_check_id(ncid, &ncp); 
04829         if(status != NC_NOERR)
04830                 return status;
04831 
04832         if(NC_indef(ncp))
04833                 return NC_EINDEFINE;
04834 
04835         varp = NC_lookupvar(ncp, varid);
04836         if(varp == NULL)
04837                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04838 
04839         if(varp->type == NC_CHAR)
04840                 return NC_ECHAR;
04841 
04842         status = NCcoordck(ncp, varp, coord);
04843         if(status != NC_NOERR)
04844                 return status;
04845 
04846         return getNCv_long(ncp, varp, coord, 1, value);
04847 }
04848 
04849 int
04850 nc_get_var1_float(int ncid, int varid, const size_t *coord, float *value)
04851 {
04852         int status;
04853         NC *ncp;
04854         const NC_var *varp;
04855 
04856         status = NC_check_id(ncid, &ncp); 
04857         if(status != NC_NOERR)
04858                 return status;
04859 
04860         if(NC_indef(ncp))
04861                 return NC_EINDEFINE;
04862 
04863         varp = NC_lookupvar(ncp, varid);
04864         if(varp == NULL)
04865                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04866 
04867         if(varp->type == NC_CHAR)
04868                 return NC_ECHAR;
04869 
04870         status = NCcoordck(ncp, varp, coord);
04871         if(status != NC_NOERR)
04872                 return status;
04873 
04874         return getNCv_float(ncp, varp, coord, 1, value);
04875 }
04876 
04877 int
04878 nc_get_var1_double(int ncid, int varid, const size_t *coord, double *value)
04879 {
04880         int status;
04881         NC *ncp;
04882         const NC_var *varp;
04883 
04884         status = NC_check_id(ncid, &ncp); 
04885         if(status != NC_NOERR)
04886                 return status;
04887 
04888         if(NC_indef(ncp))
04889                 return NC_EINDEFINE;
04890 
04891         varp = NC_lookupvar(ncp, varid);
04892         if(varp == NULL)
04893                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04894 
04895         if(varp->type == NC_CHAR)
04896                 return NC_ECHAR;
04897 
04898         status = NCcoordck(ncp, varp, coord);
04899         if(status != NC_NOERR)
04900                 return status;
04901 
04902         return getNCv_double(ncp, varp, coord, 1, value);
04903 }
04904 
04905 
04906 
04907 int
04908 nc_put_vara_text(int ncid, int varid,
04909          const size_t *start, const size_t *edges, const char *value)
04910 {
04911         int status = NC_NOERR;
04912         NC *ncp;
04913         const NC_var *varp;
04914         int ii;
04915         size_t iocount;
04916 
04917         status = NC_check_id(ncid, &ncp); 
04918         if(status != NC_NOERR)
04919                 return status;
04920 
04921         if(NC_readonly(ncp))
04922                 return NC_EPERM;
04923 
04924         if(NC_indef(ncp))
04925                 return NC_EINDEFINE;
04926 
04927         varp = NC_lookupvar(ncp, varid);
04928         if(varp == NULL)
04929                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04930 
04931         if(varp->type != NC_CHAR)
04932                 return NC_ECHAR;
04933 
04934         status = NCcoordck(ncp, varp, start);
04935         if(status != NC_NOERR)
04936                 return status;
04937         status = NCedgeck(ncp, varp, start, edges);
04938         if(status != NC_NOERR)
04939                 return status;
04940 
04941         if(varp->ndims == 0) /* scalar variable */
04942         {
04943                 return( putNCv_text(ncp, varp, start, 1, value) );
04944         }
04945 
04946         if(IS_RECVAR(varp))
04947         {
04948                 status = NCvnrecs(ncp, *start + *edges);
04949                 if(status != NC_NOERR)
04950                         return status;
04951 
04952                 if(varp->ndims == 1
04953                         && ncp->recsize <= varp->len)
04954                 {
04955                         /* one dimensional && the only record variable  */
04956                         return( putNCv_text(ncp, varp, start, *edges, value) );
04957                 }
04958         }
04959 
04960         /*
04961          * find max contiguous
04962          *   and accumulate max count for a single io operation
04963          */
04964         ii = NCiocount(ncp, varp, edges, &iocount);
04965 
04966         if(ii == -1)
04967         {
04968                 return( putNCv_text(ncp, varp, start, iocount, value) );
04969         }
04970 
04971         assert(ii >= 0);
04972 
04973 
04974         { /* inline */
04975         ALLOC_ONSTACK(coord, size_t, varp->ndims);
04976         ALLOC_ONSTACK(upper, size_t, varp->ndims);
04977         const size_t index = ii;
04978 
04979         /* copy in starting indices */
04980         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
04981 
04982         /* set up in maximum indices */
04983         set_upper(upper, start, edges, &upper[varp->ndims]);
04984 
04985         /* ripple counter */
04986         while(*coord < *upper)
04987         {
04988                 const int lstatus = putNCv_text(ncp, varp, coord, iocount,
04989                                  value);
04990                 if(lstatus != NC_NOERR)
04991                 {
04992                         if(lstatus != NC_ERANGE)
04993                         {
04994                                 status = lstatus;
04995                                 /* fatal for the loop */
04996                                 break;
04997                         }
04998                         /* else NC_ERANGE, not fatal for the loop */
04999                         if(status == NC_NOERR)
05000                                 status = lstatus;
05001                 }
05002                 value += iocount;
05003                 odo1(start, upper, coord, &upper[index], &coord[index]);
05004         }
05005 
05006         FREE_ONSTACK(upper);
05007         FREE_ONSTACK(coord);
05008         } /* end inline */
05009 
05010         return status;
05011 }
05012 
05013 
05014 int
05015 nc_put_vara_uchar(int ncid, int varid,
05016          const size_t *start, const size_t *edges, const uchar *value)
05017 {
05018         int status = NC_NOERR;
05019         NC *ncp;
05020         const NC_var *varp;
05021         int ii;
05022         size_t iocount;
05023 
05024         status = NC_check_id(ncid, &ncp); 
05025         if(status != NC_NOERR)
05026                 return status;
05027 
05028         if(NC_readonly(ncp))
05029                 return NC_EPERM;
05030 
05031         if(NC_indef(ncp))
05032                 return NC_EINDEFINE;
05033 
05034         varp = NC_lookupvar(ncp, varid);
05035         if(varp == NULL)
05036                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05037 
05038         if(varp->type == NC_CHAR)
05039                 return NC_ECHAR;
05040 
05041         status = NCcoordck(ncp, varp, start);
05042         if(status != NC_NOERR)
05043                 return status;
05044         status = NCedgeck(ncp, varp, start, edges);
05045         if(status != NC_NOERR)
05046                 return status;
05047 
05048         if(varp->ndims == 0) /* scalar variable */
05049         {
05050                 return( putNCv_uchar(ncp, varp, start, 1, value) );
05051         }
05052 
05053         if(IS_RECVAR(varp))
05054         {
05055                 status = NCvnrecs(ncp, *start + *edges);
05056                 if(status != NC_NOERR)
05057                         return status;
05058 
05059                 if(varp->ndims == 1
05060                         && ncp->recsize <= varp->len)
05061                 {
05062                         /* one dimensional && the only record variable  */
05063                         return( putNCv_uchar(ncp, varp, start, *edges, value) );
05064                 }
05065         }
05066 
05067         /*
05068          * find max contiguous
05069          *   and accumulate max count for a single io operation
05070          */
05071         ii = NCiocount(ncp, varp, edges, &iocount);
05072 
05073         if(ii == -1)
05074         {
05075                 return( putNCv_uchar(ncp, varp, start, iocount, value) );
05076         }
05077 
05078         assert(ii >= 0);
05079 
05080 
05081         { /* inline */
05082         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05083         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05084         const size_t index = ii;
05085 
05086         /* copy in starting indices */
05087         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05088 
05089         /* set up in maximum indices */
05090         set_upper(upper, start, edges, &upper[varp->ndims]);
05091 
05092         /* ripple counter */
05093         while(*coord < *upper)
05094         {
05095                 const int lstatus = putNCv_uchar(ncp, varp, coord, iocount,
05096                                  value);
05097                 if(lstatus != NC_NOERR)
05098                 {
05099                         if(lstatus != NC_ERANGE)
05100                         {
05101                                 status = lstatus;
05102                                 /* fatal for the loop */
05103                                 break;
05104                         }
05105                         /* else NC_ERANGE, not fatal for the loop */
05106                         if(status == NC_NOERR)
05107                                 status = lstatus;
05108                 }
05109                 value += iocount;
05110                 odo1(start, upper, coord, &upper[index], &coord[index]);
05111         }
05112 
05113         FREE_ONSTACK(upper);
05114         FREE_ONSTACK(coord);
05115         } /* end inline */
05116 
05117         return status;
05118 }
05119 
05120 int
05121 nc_put_vara_schar(int ncid, int varid,
05122          const size_t *start, const size_t *edges, const schar *value)
05123 {
05124         int status = NC_NOERR;
05125         NC *ncp;
05126         const NC_var *varp;
05127         int ii;
05128         size_t iocount;
05129 
05130         status = NC_check_id(ncid, &ncp); 
05131         if(status != NC_NOERR)
05132                 return status;
05133 
05134         if(NC_readonly(ncp))
05135                 return NC_EPERM;
05136 
05137         if(NC_indef(ncp))
05138                 return NC_EINDEFINE;
05139 
05140         varp = NC_lookupvar(ncp, varid);
05141         if(varp == NULL)
05142                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05143 
05144         if(varp->type == NC_CHAR)
05145                 return NC_ECHAR;
05146 
05147         status = NCcoordck(ncp, varp, start);
05148         if(status != NC_NOERR)
05149                 return status;
05150         status = NCedgeck(ncp, varp, start, edges);
05151         if(status != NC_NOERR)
05152                 return status;
05153 
05154         if(varp->ndims == 0) /* scalar variable */
05155         {
05156                 return( putNCv_schar(ncp, varp, start, 1, value) );
05157         }
05158 
05159         if(IS_RECVAR(varp))
05160         {
05161                 status = NCvnrecs(ncp, *start + *edges);
05162                 if(status != NC_NOERR)
05163                         return status;
05164 
05165                 if(varp->ndims == 1
05166                         && ncp->recsize <= varp->len)
05167                 {
05168                         /* one dimensional && the only record variable  */
05169                         return( putNCv_schar(ncp, varp, start, *edges, value) );
05170                 }
05171         }
05172 
05173         /*
05174          * find max contiguous
05175          *   and accumulate max count for a single io operation
05176          */
05177         ii = NCiocount(ncp, varp, edges, &iocount);
05178 
05179         if(ii == -1)
05180         {
05181                 return( putNCv_schar(ncp, varp, start, iocount, value) );
05182         }
05183 
05184         assert(ii >= 0);
05185 
05186 
05187         { /* inline */
05188         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05189         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05190         const size_t index = ii;
05191 
05192         /* copy in starting indices */
05193         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05194 
05195         /* set up in maximum indices */
05196         set_upper(upper, start, edges, &upper[varp->ndims]);
05197 
05198         /* ripple counter */
05199         while(*coord < *upper)
05200         {
05201                 const int lstatus = putNCv_schar(ncp, varp, coord, iocount,
05202                                  value);
05203                 if(lstatus != NC_NOERR)
05204                 {
05205                         if(lstatus != NC_ERANGE)
05206                         {
05207                                 status = lstatus;
05208                                 /* fatal for the loop */
05209                                 break;
05210                         }
05211                         /* else NC_ERANGE, not fatal for the loop */
05212                         if(status == NC_NOERR)
05213                                 status = lstatus;
05214                 }
05215                 value += iocount;
05216                 odo1(start, upper, coord, &upper[index], &coord[index]);
05217         }
05218 
05219         FREE_ONSTACK(upper);
05220         FREE_ONSTACK(coord);
05221         } /* end inline */
05222 
05223         return status;
05224 }
05225 
05226 int
05227 nc_put_vara_short(int ncid, int varid,
05228          const size_t *start, const size_t *edges, const short *value)
05229 {
05230         int status = NC_NOERR;
05231         NC *ncp;
05232         const NC_var *varp;
05233         int ii;
05234         size_t iocount;
05235 
05236         status = NC_check_id(ncid, &ncp); 
05237         if(status != NC_NOERR)
05238                 return status;
05239 
05240         if(NC_readonly(ncp))
05241                 return NC_EPERM;
05242 
05243         if(NC_indef(ncp))
05244                 return NC_EINDEFINE;
05245 
05246         varp = NC_lookupvar(ncp, varid);
05247         if(varp == NULL)
05248                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05249 
05250         if(varp->type == NC_CHAR)
05251                 return NC_ECHAR;
05252 
05253         status = NCcoordck(ncp, varp, start);
05254         if(status != NC_NOERR)
05255                 return status;
05256         status = NCedgeck(ncp, varp, start, edges);
05257         if(status != NC_NOERR)
05258                 return status;
05259 
05260         if(varp->ndims == 0) /* scalar variable */
05261         {
05262                 return( putNCv_short(ncp, varp, start, 1, value) );
05263         }
05264 
05265         if(IS_RECVAR(varp))
05266         {
05267                 status = NCvnrecs(ncp, *start + *edges);
05268                 if(status != NC_NOERR)
05269                         return status;
05270 
05271                 if(varp->ndims == 1
05272                         && ncp->recsize <= varp->len)
05273                 {
05274                         /* one dimensional && the only record variable  */
05275                         return( putNCv_short(ncp, varp, start, *edges, value) );
05276                 }
05277         }
05278 
05279         /*
05280          * find max contiguous
05281          *   and accumulate max count for a single io operation
05282          */
05283         ii = NCiocount(ncp, varp, edges, &iocount);
05284 
05285         if(ii == -1)
05286         {
05287                 return( putNCv_short(ncp, varp, start, iocount, value) );
05288         }
05289 
05290         assert(ii >= 0);
05291 
05292 
05293         { /* inline */
05294         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05295         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05296         const size_t index = ii;
05297 
05298         /* copy in starting indices */
05299         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05300 
05301         /* set up in maximum indices */
05302         set_upper(upper, start, edges, &upper[varp->ndims]);
05303 
05304         /* ripple counter */
05305         while(*coord < *upper)
05306         {
05307                 const int lstatus = putNCv_short(ncp, varp, coord, iocount,
05308                                  value);
05309                 if(lstatus != NC_NOERR)
05310                 {
05311                         if(lstatus != NC_ERANGE)
05312                         {
05313                                 status = lstatus;
05314                                 /* fatal for the loop */
05315                                 break;
05316                         }
05317                         /* else NC_ERANGE, not fatal for the loop */
05318                         if(status == NC_NOERR)
05319                                 status = lstatus;
05320                 }
05321                 value += iocount;
05322                 odo1(start, upper, coord, &upper[index], &coord[index]);
05323         }
05324 
05325         FREE_ONSTACK(upper);