Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

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 
00007 #include "nc.h"
00008 #include <string.h>
00009 #include <stdlib.h>
00010 #include <assert.h>
00011 #include "ncx.h"
00012 #include "fbits.h"
00013 #include "onstack.h"
00014 #ifdef LOCKNUMREC
00015 #  include <mpp/shmem.h>        /* for SGI/Cray SHMEM routines */
00016 #  ifdef LN_TEST
00017 #    include <stdio.h>
00018 #  endif
00019 #endif
00020 
00021 #undef MIN  /* system may define MIN somewhere and complain */
00022 #define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
00023 
00024 #undef  SIZEOF_INT
00025 #define SIZEOF_INT 4
00026 
00027 /* #define ODEBUG 1 */
00028 
00029 #if ODEBUG
00030 #include <stdio.h>
00031 /*
00032  * Print the values of an array of size_t
00033  */
00034 void
00035 arrayp(const char *label, size_t count, const size_t *array)
00036 {
00037         (void) fprintf(stderr, "%s", label);
00038         (void) fputc('\t',stderr);      
00039         for(; count > 0; count--, array++)
00040                 (void) fprintf(stderr," %lu", (unsigned long)*array);
00041         (void) fputc('\n',stderr);      
00042 }
00043 #endif /* ODEBUG */
00044 
00045 
00046 /* Begin fill */
00047 /*
00048  * This is tunable parameter.
00049  * It essentially controls the tradeoff between the number of times
00050  * memcpy() gets called to copy the external data to fill 
00051  * a large buffer vs the number of times its called to
00052  * prepare the external data.
00053  */
00054 #define NFILL 16
00055 
00056 
00057 
00058 /*
00059  * Next 6 type specific functions
00060  * Fill a some memory with the default special value.
00061  * Formerly
00062 NC_arrayfill()
00063  */
00064 static int
00065 NC_fill_schar(
00066         void **xpp,
00067         size_t nelems)  /* how many */
00068 {
00069         schar fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];
00070 
00071         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00072 
00073         {
00074                 schar *vp = fillp;      /* lower bound of area to be filled */
00075                 const schar *const end = vp + nelems;
00076                 while(vp < end)
00077                 {
00078                         *vp++ = NC_FILL_BYTE;
00079                 }
00080         }
00081         return ncx_putn_schar_schar(xpp, nelems, fillp);
00082 }
00083 
00084 static int
00085 NC_fill_char(
00086         void **xpp,
00087         size_t nelems)  /* how many */
00088 {
00089         char fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR];
00090 
00091         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00092 
00093         {
00094                 char *vp = fillp;       /* lower bound of area to be filled */
00095                 const char *const end = vp + nelems;
00096                 while(vp < end)
00097                 {
00098                         *vp++ = NC_FILL_CHAR;
00099                 }
00100         }
00101         return ncx_putn_char_char(xpp, nelems, fillp);
00102 }
00103 
00104 static int
00105 NC_fill_short(
00106         void **xpp,
00107         size_t nelems)  /* how many */
00108 {
00109         short fillp[NFILL * sizeof(double)/X_SIZEOF_SHORT];
00110 
00111         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00112 
00113         {
00114                 short *vp = fillp;      /* lower bound of area to be filled */
00115                 const short *const end = vp + nelems;
00116                 while(vp < end)
00117                 {
00118                         *vp++ = NC_FILL_SHORT;
00119                 }
00120         }
00121         return ncx_putn_short_short(xpp, nelems, fillp);
00122 }
00123 
00124 
00125 #if (SIZEOF_INT >= X_SIZEOF_INT)
00126 static int
00127 NC_fill_int(
00128         void **xpp,
00129         size_t nelems)  /* how many */
00130 {
00131         int fillp[NFILL * sizeof(double)/X_SIZEOF_INT];
00132 
00133         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00134 
00135         {
00136                 int *vp = fillp;        /* lower bound of area to be filled */
00137                 const int *const end = vp + nelems;
00138                 while(vp < end)
00139                 {
00140                         *vp++ = NC_FILL_INT;
00141                 }
00142         }
00143         return ncx_putn_int_int(xpp, nelems, fillp);
00144 }
00145 
00146 #elif SIZEOF_LONG == X_SIZEOF_INT
00147 static int
00148 NC_fill_int(
00149         void **xpp,
00150         size_t nelems)  /* how many */
00151 {
00152         long fillp[NFILL * sizeof(double)/X_SIZEOF_INT];
00153 
00154         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00155 
00156         {
00157                 long *vp = fillp;       /* lower bound of area to be filled */
00158                 const long *const end = vp + nelems;
00159                 while(vp < end)
00160                 {
00161                         *vp++ = NC_FILL_INT;
00162                 }
00163         }
00164         return ncx_putn_int_long(xpp, nelems, fillp);
00165 }
00166 
00167 #else
00168 #error "NC_fill_int implementation"
00169 #endif
00170 
00171 static int
00172 NC_fill_float(
00173         void **xpp,
00174         size_t nelems)  /* how many */
00175 {
00176         float fillp[NFILL * sizeof(double)/X_SIZEOF_FLOAT];
00177 
00178         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00179 
00180         {
00181                 float *vp = fillp;      /* lower bound of area to be filled */
00182                 const float *const end = vp + nelems;
00183                 while(vp < end)
00184                 {
00185                         *vp++ = NC_FILL_FLOAT;
00186                 }
00187         }
00188         return ncx_putn_float_float(xpp, nelems, fillp);
00189 }
00190 
00191 static int
00192 NC_fill_double(
00193         void **xpp,
00194         size_t nelems)  /* how many */
00195 {
00196         double fillp[NFILL * sizeof(double)/X_SIZEOF_DOUBLE];
00197 
00198         assert(nelems <= sizeof(fillp)/sizeof(fillp[0]));
00199 
00200         {
00201                 double *vp = fillp;     /* lower bound of area to be filled */
00202                 const double *const end = vp + nelems;
00203                 while(vp < end)
00204                 {
00205                         *vp++ = NC_FILL_DOUBLE;
00206                 }
00207         }
00208         return ncx_putn_double_double(xpp, nelems, fillp);
00209 }
00210 
00211 
00212 
00213 /*
00214  * Fill the external space for variable 'varp' values at 'recno'
00215  * with the appropriate value. If 'varp' is not a record
00216  * variable, fill the whole thing.
00217  * Formerly
00218 xdr_NC_fill()
00219  */
00220 int
00221 fill_NC_var(NC *ncp, const NC_var *varp, size_t recno)
00222 {
00223         char xfillp[NFILL * X_SIZEOF_DOUBLE];
00224         const size_t step = varp->xsz;
00225         const size_t nelems = sizeof(xfillp)/step;
00226         const size_t xsz = varp->xsz * nelems;
00227         NC_attr **attrpp = NULL;
00228         off_t offset;
00229         size_t remaining = varp->len;
00230 
00231         void *xp;
00232         int status = NC_NOERR;
00233 
00234         /*
00235          * Set up fill value
00236          */
00237         attrpp = NC_findattr(&varp->attrs, _FillValue);
00238         if( attrpp != NULL )
00239         {
00240                 /* User defined fill value */
00241                 if( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 )
00242                 {
00243                         return NC_EBADTYPE;
00244                 }
00245                 else
00246                 {
00247                         /* Use the user defined value */
00248                         char *cp = xfillp;
00249                         const char *const end = &xfillp[sizeof(xfillp)];
00250 
00251                         assert(step <= (*attrpp)->xsz);
00252 
00253                         for( /*NADA*/; cp < end; cp += step)
00254                         {
00255                                 (void) memcpy(cp, (*attrpp)->xvalue, step);
00256                         }
00257                 }
00258         }
00259         else
00260         {
00261                 /* use the default */
00262                 
00263                 assert(xsz % X_ALIGN == 0);
00264                 assert(xsz <= sizeof(xfillp));
00265         
00266                 xp = xfillp;
00267         
00268                 switch(varp->type){
00269                 case NC_BYTE :
00270                         status = NC_fill_schar(&xp, nelems);
00271                         break;
00272                 case NC_CHAR :
00273                         status = NC_fill_char(&xp, nelems);
00274                         break;
00275                 case NC_SHORT :
00276                         status = NC_fill_short(&xp, nelems);
00277                         break;
00278                 case NC_INT :
00279                         status = NC_fill_int(&xp, nelems);
00280                         break;
00281                 case NC_FLOAT :
00282                         status = NC_fill_float(&xp, nelems);
00283                         break;
00284                 case NC_DOUBLE : 
00285                         status = NC_fill_double(&xp, nelems);
00286                         break;
00287                 default :
00288                         assert("fill_NC_var invalid type" == 0);
00289                         status = NC_EBADTYPE;
00290                         break;
00291                 }
00292                 if(status != NC_NOERR)
00293                         return status;
00294         
00295                 assert(xp == xfillp + xsz);
00296         }
00297 
00298         /*
00299          * copyout:
00300          * xfillp now contains 'nelems' elements of the fill value
00301          * in external representation.
00302          */
00303 
00304         /*
00305          * Copy it out.
00306          */
00307 
00308         offset = varp->begin;
00309         if(IS_RECVAR(varp))
00310         {
00311                 offset += (off_t)ncp->recsize * recno;
00312         }
00313 
00314         assert(remaining > 0);
00315         for(;;)
00316         {
00317                 const size_t chunksz = MIN(remaining, ncp->chunk);
00318                 size_t ii;
00319                 assert(chunksz % X_ALIGN == 0);
00320 
00321                 status = ncp->nciop->get(ncp->nciop, offset, chunksz,
00322                                  RGN_WRITE, &xp);       
00323                 if(status != NC_NOERR)
00324                 {
00325                         return status;
00326                 }
00327 
00328                 /*
00329                  * fill the chunksz buffer in units  of xsz
00330                  */
00331                 for(ii = 0; ii < chunksz/xsz; ii++)
00332                 {
00333                         (void) memcpy(xp, xfillp, xsz);
00334                         xp = (char *)xp + xsz;
00335                 }
00336                 /*
00337                  * Deal with any remainder
00338                  */
00339                 {
00340                         const size_t rem = chunksz % xsz;
00341                         if(rem != 0)
00342                         {
00343                                 (void) memcpy(xp, xfillp, rem);
00344                                 /* xp = (char *)xp + xsz; */
00345                         }
00346 
00347                 }
00348 
00349                 status = ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED);
00350 
00351                 if(status != NC_NOERR)
00352                 {
00353                         break;
00354                 }
00355 
00356                 remaining -= chunksz;
00357                 if(remaining == 0)
00358                         break;  /* normal loop exit */
00359                 offset += chunksz;
00360 
00361         }
00362 
00363         return status;
00364 }
00365 /* End fill */
00366 
00367 
00368 /*
00369  * Add a record containing the fill values.
00370  */
00371 static int
00372 NCfillrecord(NC *ncp, const NC_var *const *varpp, size_t recno)
00373 {
00374         size_t ii = 0;
00375         for(; ii < ncp->vars.nelems; ii++, varpp++)
00376         {
00377                 if( !IS_RECVAR(*varpp) )
00378                 {
00379                         continue;       /* skip non-record variables */
00380                 }
00381                 {
00382                 const int status = fill_NC_var(ncp, *varpp, recno);
00383                 if(status != NC_NOERR)
00384                         return status;
00385                 }
00386         }
00387         return NC_NOERR;
00388 }
00389 
00390 /*
00391  * It is advantageous to
00392  * #define TOUCH_LAST
00393  * when using memory mapped io.
00394  */
00395 #if TOUCH_LAST
00396 /*
00397  * Grow the file to a size which can contain recno
00398  */
00399 static int
00400 NCtouchlast(NC *ncp, const NC_var *const *varpp, size_t recno)
00401 {
00402         int status = NC_NOERR;
00403         const NC_var *varp = NULL;
00404         
00405         {
00406         size_t ii = 0;
00407         for(; ii < ncp->vars.nelems; ii++, varpp++)
00408         {
00409                 if( !IS_RECVAR(*varpp) )
00410                 {
00411                         continue;       /* skip non-record variables */
00412                 }
00413                 varp = *varpp;
00414         }
00415         }
00416         assert(varp != NULL);
00417         assert( IS_RECVAR(varp) );
00418         {
00419                 const off_t offset = varp->begin
00420                                 + (off_t)(recno-1) * (off_t)ncp->recsize
00421                                 + (off_t)(varp->len - varp->xsz);
00422                 void *xp;
00423 
00424 
00425                 status = ncp->nciop->get(ncp->nciop, offset, varp->xsz,
00426                                  RGN_WRITE, &xp);       
00427                 if(status != NC_NOERR)
00428                         return status;
00429                 (void)memset(xp, 0, varp->xsz);
00430                 status = ncp->nciop->rel(ncp->nciop, offset, RGN_MODIFIED);
00431         }
00432         return status;
00433 }
00434 #endif /* TOUCH_LAST */
00435 
00436 
00437 /*
00438  * Ensure that the netcdf file has 'numrecs' records,
00439  * add records and fill as neccessary.
00440  */
00441 static int
00442 NCvnrecs(NC *ncp, size_t numrecs)
00443 {
00444         int status = NC_NOERR;
00445 #ifdef LOCKNUMREC
00446         ushmem_t myticket = 0, nowserving = 0;
00447         ushmem_t numpe = (ushmem_t) _num_pes();
00448 
00449         /* get ticket and wait */
00450         myticket = shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
00451                 ncp->lock[LOCKNUMREC_BASEPE]);
00452 #ifdef LN_TEST
00453                 fprintf(stderr,"%d of %d : ticket = %hu\n",
00454                         _my_pe(), _num_pes(), myticket);
00455 #endif
00456         do {
00457                 shmem_short_get((shmem_t *) &nowserving,
00458                         (shmem_t *) ncp->lock + LOCKNUMREC_SERVING, 1,
00459                         ncp->lock[LOCKNUMREC_BASEPE]);
00460 #ifdef LN_TEST
00461                 fprintf(stderr,"%d of %d : serving = %hu\n",
00462                         _my_pe(), _num_pes(), nowserving);
00463 #endif
00464                 /* work-around for non-unique tickets */
00465                 if (nowserving > myticket && nowserving < myticket + numpe ) {
00466                         /* get a new ticket ... you've been bypassed */ 
00467                         /* and handle the unlikely wrap-around effect */
00468                         myticket = shmem_short_finc(
00469                                 (shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
00470                                 ncp->lock[LOCKNUMREC_BASEPE]);
00471 #ifdef LN_TEST
00472                                 fprintf(stderr,"%d of %d : new ticket = %hu\n",
00473                                         _my_pe(), _num_pes(), myticket);
00474 #endif
00475                 }
00476         } while(nowserving != myticket);
00477         /* now our turn to check & update value */
00478 #endif
00479 
00480         if(numrecs > NC_get_numrecs(ncp))
00481         {
00482 
00483 
00484 #if TOUCH_LAST
00485                 status = NCtouchlast(ncp,
00486                         (const NC_var *const*)ncp->vars.value,
00487                         numrecs);
00488                 if(status != NC_NOERR)
00489                         goto common_return;
00490 #endif /* TOUCH_LAST */
00491 
00492                 set_NC_ndirty(ncp);
00493 
00494                 if(!NC_dofill(ncp))
00495                 {
00496                         /* Simply set the new numrecs value */
00497                         NC_set_numrecs(ncp, numrecs);
00498                 }
00499                 else
00500                 {
00501                         /* Fill each record out to numrecs */
00502                         size_t cur_nrecs;
00503                         while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs)
00504                         {
00505                                 status = NCfillrecord(ncp,
00506                                         (const NC_var *const*)ncp->vars.value,
00507                                         cur_nrecs);
00508                                 if(status != NC_NOERR)
00509                                 {
00510                                         break;
00511                                 }
00512                                 NC_increase_numrecs(ncp, cur_nrecs +1);
00513                         }
00514                         if(status != NC_NOERR)
00515                                 goto common_return;
00516                 }
00517 
00518                 if(NC_doNsync(ncp))
00519                 {
00520                         status = write_numrecs(ncp);
00521                 }
00522 
00523         }
00524 common_return:
00525 #ifdef LOCKNUMREC
00526         /* finished with our lock - increment serving number */
00527         (void) shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_SERVING,
00528                 ncp->lock[LOCKNUMREC_BASEPE]);
00529 #endif
00530         return status;
00531 }
00532 
00533 
00534 /* 
00535  * Check whether 'coord' values are valid for the variable.
00536  */
00537 static int
00538 NCcoordck(NC *ncp, const NC_var *varp, const size_t *coord)
00539 {
00540         const size_t *ip;
00541         size_t *up;
00542 
00543         if(varp->ndims == 0)
00544                 return NC_NOERR;        /* 'scalar' variable */
00545 
00546         if(IS_RECVAR(varp))
00547         {
00548                 if(*coord > X_INT_MAX)
00549                         return NC_EINVALCOORDS; /* sanity check */
00550                 if(NC_readonly(ncp) && *coord >= NC_get_numrecs(ncp))
00551                 {
00552                         if(!NC_doNsync(ncp))
00553                                 return NC_EINVALCOORDS;
00554                         /* else */
00555                         {
00556                                 /* Update from disk and check again */
00557                                 const int status = read_numrecs(ncp);
00558                                 if(status != NC_NOERR)
00559                                         return status;
00560                                 if(*coord >= NC_get_numrecs(ncp))
00561                                         return NC_EINVALCOORDS;
00562                         }
00563                 }
00564                 ip = coord + 1;
00565                 up = varp->shape + 1;
00566         }
00567         else
00568         {
00569                 ip = coord;
00570                 up = varp->shape;
00571         }
00572         
00573 #ifdef CDEBUG
00574 fprintf(stderr,"        NCcoordck: coord %ld, count %d, ip %ld\n",
00575                 coord, varp->ndims, ip );
00576 #endif /* CDEBUG */
00577 
00578         for(; ip < coord + varp->ndims; ip++, up++)
00579         {
00580 
00581 #ifdef CDEBUG
00582 fprintf(stderr,"        NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n",
00583                         ip, *ip, up, *up );
00584 #endif /* CDEBUG */
00585 
00586                 /* cast needed for braindead systems with signed size_t */
00587                 if((unsigned long) *ip >= (unsigned long) *up )
00588                         return NC_EINVALCOORDS;
00589         }
00590 
00591         return NC_NOERR;
00592 }
00593 
00594 
00595 /* 
00596  * Check whether 'edges' are valid for the variable and 'start'
00597  */
00598 /*ARGSUSED*/
00599 static int
00600 NCedgeck(const NC *ncp, const NC_var *varp,
00601          const size_t *start, const size_t *edges)
00602 {
00603         const size_t *const end = start + varp->ndims;
00604         const size_t *shp = varp->shape;
00605 
00606         if(varp->ndims == 0)
00607                 return NC_NOERR;        /* 'scalar' variable */
00608 
00609         if(IS_RECVAR(varp))
00610         {
00611                 start++;
00612                 edges++;
00613                 shp++;
00614         }
00615 
00616         for(; start < end; start++, edges++, shp++)
00617         {
00618                 /* cast needed for braindead systems with signed size_t */
00619                 if((unsigned long) *edges > *shp ||
00620                         (unsigned long) *start + (unsigned long) *edges > *shp)
00621                 {
00622                         return(NC_EEDGE);
00623                 }
00624         }
00625         return NC_NOERR;
00626 }
00627 
00628 
00629 /* 
00630  * Translate the (variable, coord) pair into a seek index
00631  */
00632 static off_t
00633 NC_varoffset(const NC *ncp, const NC_var *varp, const size_t *coord)
00634 {
00635         if(varp->ndims == 0) /* 'scalar' variable */
00636                 return varp->begin;
00637 
00638         if(varp->ndims == 1)
00639         {
00640                 if(IS_RECVAR(varp))
00641                         return varp->begin +
00642                                  (off_t)(*coord) * (off_t)ncp->recsize;
00643                 /* else */
00644                 return varp->begin + (off_t)(*coord) * (off_t)varp->xsz;
00645         }
00646         /* else */
00647         {
00648                 off_t lcoord = (off_t)coord[varp->ndims -1];
00649 
00650                 size_t *up = varp->dsizes +1;
00651                 const size_t *ip = coord;
00652                 const size_t *const end = varp->dsizes + varp->ndims;
00653                 
00654                 if(IS_RECVAR(varp))
00655                         up++, ip++;
00656 
00657                 for(; up < end; up++, ip++)
00658                         lcoord += *up * *ip;
00659 
00660                 lcoord *= varp->xsz;
00661                 
00662                 if(IS_RECVAR(varp))
00663                         lcoord += (off_t)(*coord) * ncp->recsize;
00664                 
00665                 lcoord += varp->begin;
00666                 return lcoord;
00667         }
00668 }
00669 
00670 
00671 
00672 static int
00673 putNCvx_char_char(NC *ncp, const NC_var *varp,
00674                  const size_t *start, size_t nelems, const char *value)
00675 {
00676         off_t offset = NC_varoffset(ncp, varp, start);
00677         size_t remaining = varp->xsz * nelems;
00678         int status = NC_NOERR;
00679         void *xp;
00680 
00681         if(nelems == 0)
00682                 return NC_NOERR;
00683 
00684         assert(value != NULL);
00685 
00686         for(;;)
00687         {
00688                 size_t extent = MIN(remaining, ncp->chunk);
00689                 size_t nput = ncx_howmany(varp->type, extent);
00690 
00691                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00692                                  RGN_WRITE, &xp);       
00693                 if(lstatus != NC_NOERR)
00694                         return lstatus;
00695                 
00696                 lstatus = ncx_putn_char_char(&xp, nput, value);
00697                 if(lstatus != NC_NOERR && status == NC_NOERR)
00698                 {
00699                         /* not fatal to the loop */
00700                         status = lstatus;
00701                 }
00702 
00703                 (void) ncp->nciop->rel(ncp->nciop, offset,
00704                                  RGN_MODIFIED); 
00705 
00706                 remaining -= extent;
00707                 if(remaining == 0)
00708                         break; /* normal loop exit */
00709                 offset += extent;
00710                 value += nput;
00711 
00712         }
00713 
00714         return status;
00715 }
00716 
00717 
00718 static int
00719 putNCvx_schar_schar(NC *ncp, const NC_var *varp,
00720                  const size_t *start, size_t nelems, const schar *value)
00721 {
00722         off_t offset = NC_varoffset(ncp, varp, start);
00723         size_t remaining = varp->xsz * nelems;
00724         int status = NC_NOERR;
00725         void *xp;
00726 
00727         if(nelems == 0)
00728                 return NC_NOERR;
00729 
00730         assert(value != NULL);
00731 
00732         for(;;)
00733         {
00734                 size_t extent = MIN(remaining, ncp->chunk);
00735                 size_t nput = ncx_howmany(varp->type, extent);
00736 
00737                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00738                                  RGN_WRITE, &xp);       
00739                 if(lstatus != NC_NOERR)
00740                         return lstatus;
00741                 
00742                 lstatus = ncx_putn_schar_schar(&xp, nput, value);
00743                 if(lstatus != NC_NOERR && status == NC_NOERR)
00744                 {
00745                         /* not fatal to the loop */
00746                         status = lstatus;
00747                 }
00748 
00749                 (void) ncp->nciop->rel(ncp->nciop, offset,
00750                                  RGN_MODIFIED); 
00751 
00752                 remaining -= extent;
00753                 if(remaining == 0)
00754                         break; /* normal loop exit */
00755                 offset += extent;
00756                 value += nput;
00757 
00758         }
00759 
00760         return status;
00761 }
00762 
00763 static int
00764 putNCvx_schar_uchar(NC *ncp, const NC_var *varp,
00765                  const size_t *start, size_t nelems, const uchar *value)
00766 {
00767         off_t offset = NC_varoffset(ncp, varp, start);
00768         size_t remaining = varp->xsz * nelems;
00769         int status = NC_NOERR;
00770         void *xp;
00771 
00772         if(nelems == 0)
00773                 return NC_NOERR;
00774 
00775         assert(value != NULL);
00776 
00777         for(;;)
00778         {
00779                 size_t extent = MIN(remaining, ncp->chunk);
00780                 size_t nput = ncx_howmany(varp->type, extent);
00781 
00782                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00783                                  RGN_WRITE, &xp);       
00784                 if(lstatus != NC_NOERR)
00785                         return lstatus;
00786                 
00787                 lstatus = ncx_putn_schar_uchar(&xp, nput, value);
00788                 if(lstatus != NC_NOERR && status == NC_NOERR)
00789                 {
00790                         /* not fatal to the loop */
00791                         status = lstatus;
00792                 }
00793 
00794                 (void) ncp->nciop->rel(ncp->nciop, offset,
00795                                  RGN_MODIFIED); 
00796 
00797                 remaining -= extent;
00798                 if(remaining == 0)
00799                         break; /* normal loop exit */
00800                 offset += extent;
00801                 value += nput;
00802 
00803         }
00804 
00805         return status;
00806 }
00807 
00808 static int
00809 putNCvx_schar_short(NC *ncp, const NC_var *varp,
00810                  const size_t *start, size_t nelems, const short *value)
00811 {
00812         off_t offset = NC_varoffset(ncp, varp, start);
00813         size_t remaining = varp->xsz * nelems;
00814         int status = NC_NOERR;
00815         void *xp;
00816 
00817         if(nelems == 0)
00818                 return NC_NOERR;
00819 
00820         assert(value != NULL);
00821 
00822         for(;;)
00823         {
00824                 size_t extent = MIN(remaining, ncp->chunk);
00825                 size_t nput = ncx_howmany(varp->type, extent);
00826 
00827                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00828                                  RGN_WRITE, &xp);       
00829                 if(lstatus != NC_NOERR)
00830                         return lstatus;
00831                 
00832                 lstatus = ncx_putn_schar_short(&xp, nput, value);
00833                 if(lstatus != NC_NOERR && status == NC_NOERR)
00834                 {
00835                         /* not fatal to the loop */
00836                         status = lstatus;
00837                 }
00838 
00839                 (void) ncp->nciop->rel(ncp->nciop, offset,
00840                                  RGN_MODIFIED); 
00841 
00842                 remaining -= extent;
00843                 if(remaining == 0)
00844                         break; /* normal loop exit */
00845                 offset += extent;
00846                 value += nput;
00847 
00848         }
00849 
00850         return status;
00851 }
00852 
00853 static int
00854 putNCvx_schar_int(NC *ncp, const NC_var *varp,
00855                  const size_t *start, size_t nelems, const int *value)
00856 {
00857         off_t offset = NC_varoffset(ncp, varp, start);
00858         size_t remaining = varp->xsz * nelems;
00859         int status = NC_NOERR;
00860         void *xp;
00861 
00862         if(nelems == 0)
00863                 return NC_NOERR;
00864 
00865         assert(value != NULL);
00866 
00867         for(;;)
00868         {
00869                 size_t extent = MIN(remaining, ncp->chunk);
00870                 size_t nput = ncx_howmany(varp->type, extent);
00871 
00872                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00873                                  RGN_WRITE, &xp);       
00874                 if(lstatus != NC_NOERR)
00875                         return lstatus;
00876                 
00877                 lstatus = ncx_putn_schar_int(&xp, nput, value);
00878                 if(lstatus != NC_NOERR && status == NC_NOERR)
00879                 {
00880                         /* not fatal to the loop */
00881                         status = lstatus;
00882                 }
00883 
00884                 (void) ncp->nciop->rel(ncp->nciop, offset,
00885                                  RGN_MODIFIED); 
00886 
00887                 remaining -= extent;
00888                 if(remaining == 0)
00889                         break; /* normal loop exit */
00890                 offset += extent;
00891                 value += nput;
00892 
00893         }
00894 
00895         return status;
00896 }
00897 
00898 static int
00899 putNCvx_schar_long(NC *ncp, const NC_var *varp,
00900                  const size_t *start, size_t nelems, const long *value)
00901 {
00902         off_t offset = NC_varoffset(ncp, varp, start);
00903         size_t remaining = varp->xsz * nelems;
00904         int status = NC_NOERR;
00905         void *xp;
00906 
00907         if(nelems == 0)
00908                 return NC_NOERR;
00909 
00910         assert(value != NULL);
00911 
00912         for(;;)
00913         {
00914                 size_t extent = MIN(remaining, ncp->chunk);
00915                 size_t nput = ncx_howmany(varp->type, extent);
00916 
00917                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00918                                  RGN_WRITE, &xp);       
00919                 if(lstatus != NC_NOERR)
00920                         return lstatus;
00921                 
00922                 lstatus = ncx_putn_schar_long(&xp, nput, value);
00923                 if(lstatus != NC_NOERR && status == NC_NOERR)
00924                 {
00925                         /* not fatal to the loop */
00926                         status = lstatus;
00927                 }
00928 
00929                 (void) ncp->nciop->rel(ncp->nciop, offset,
00930                                  RGN_MODIFIED); 
00931 
00932                 remaining -= extent;
00933                 if(remaining == 0)
00934                         break; /* normal loop exit */
00935                 offset += extent;
00936                 value += nput;
00937 
00938         }
00939 
00940         return status;
00941 }
00942 
00943 static int
00944 putNCvx_schar_float(NC *ncp, const NC_var *varp,
00945                  const size_t *start, size_t nelems, const float *value)
00946 {
00947         off_t offset = NC_varoffset(ncp, varp, start);
00948         size_t remaining = varp->xsz * nelems;
00949         int status = NC_NOERR;
00950         void *xp;
00951 
00952         if(nelems == 0)
00953                 return NC_NOERR;
00954 
00955         assert(value != NULL);
00956 
00957         for(;;)
00958         {
00959                 size_t extent = MIN(remaining, ncp->chunk);
00960                 size_t nput = ncx_howmany(varp->type, extent);
00961 
00962                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
00963                                  RGN_WRITE, &xp);       
00964                 if(lstatus != NC_NOERR)
00965                         return lstatus;
00966                 
00967                 lstatus = ncx_putn_schar_float(&xp, nput, value);
00968                 if(lstatus != NC_NOERR && status == NC_NOERR)
00969                 {
00970                         /* not fatal to the loop */
00971                         status = lstatus;
00972                 }
00973 
00974                 (void) ncp->nciop->rel(ncp->nciop, offset,
00975                                  RGN_MODIFIED); 
00976 
00977                 remaining -= extent;
00978                 if(remaining == 0)
00979                         break; /* normal loop exit */
00980                 offset += extent;
00981                 value += nput;
00982 
00983         }
00984 
00985         return status;
00986 }
00987 
00988 static int
00989 putNCvx_schar_double(NC *ncp, const NC_var *varp,
00990                  const size_t *start, size_t nelems, const double *value)
00991 {
00992         off_t offset = NC_varoffset(ncp, varp, start);
00993         size_t remaining = varp->xsz * nelems;
00994         int status = NC_NOERR;
00995         void *xp;
00996 
00997         if(nelems == 0)
00998                 return NC_NOERR;
00999 
01000         assert(value != NULL);
01001 
01002         for(;;)
01003         {
01004                 size_t extent = MIN(remaining, ncp->chunk);
01005                 size_t nput = ncx_howmany(varp->type, extent);
01006 
01007                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01008                                  RGN_WRITE, &xp);       
01009                 if(lstatus != NC_NOERR)
01010                         return lstatus;
01011                 
01012                 lstatus = ncx_putn_schar_double(&xp, nput, value);
01013                 if(lstatus != NC_NOERR && status == NC_NOERR)
01014                 {
01015                         /* not fatal to the loop */
01016                         status = lstatus;
01017                 }
01018 
01019                 (void) ncp->nciop->rel(ncp->nciop, offset,
01020                                  RGN_MODIFIED); 
01021 
01022                 remaining -= extent;
01023                 if(remaining == 0)
01024                         break; /* normal loop exit */
01025                 offset += extent;
01026                 value += nput;
01027 
01028         }
01029 
01030         return status;
01031 }
01032 
01033 
01034 static int
01035 putNCvx_short_schar(NC *ncp, const NC_var *varp,
01036                  const size_t *start, size_t nelems, const schar *value)
01037 {
01038         off_t offset = NC_varoffset(ncp, varp, start);
01039         size_t remaining = varp->xsz * nelems;
01040         int status = NC_NOERR;
01041         void *xp;
01042 
01043         if(nelems == 0)
01044                 return NC_NOERR;
01045 
01046         assert(value != NULL);
01047 
01048         for(;;)
01049         {
01050                 size_t extent = MIN(remaining, ncp->chunk);
01051                 size_t nput = ncx_howmany(varp->type, extent);
01052 
01053                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01054                                  RGN_WRITE, &xp);       
01055                 if(lstatus != NC_NOERR)
01056                         return lstatus;
01057                 
01058                 lstatus = ncx_putn_short_schar(&xp, nput, value);
01059                 if(lstatus != NC_NOERR && status == NC_NOERR)
01060                 {
01061                         /* not fatal to the loop */
01062                         status = lstatus;
01063                 }
01064 
01065                 (void) ncp->nciop->rel(ncp->nciop, offset,
01066                                  RGN_MODIFIED); 
01067 
01068                 remaining -= extent;
01069                 if(remaining == 0)
01070                         break; /* normal loop exit */
01071                 offset += extent;
01072                 value += nput;
01073 
01074         }
01075 
01076         return status;
01077 }
01078 
01079 static int
01080 putNCvx_short_uchar(NC *ncp, const NC_var *varp,
01081                  const size_t *start, size_t nelems, const uchar *value)
01082 {
01083         off_t offset = NC_varoffset(ncp, varp, start);
01084         size_t remaining = varp->xsz * nelems;
01085         int status = NC_NOERR;
01086         void *xp;
01087 
01088         if(nelems == 0)
01089                 return NC_NOERR;
01090 
01091         assert(value != NULL);
01092 
01093         for(;;)
01094         {
01095                 size_t extent = MIN(remaining, ncp->chunk);
01096                 size_t nput = ncx_howmany(varp->type, extent);
01097 
01098                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01099                                  RGN_WRITE, &xp);       
01100                 if(lstatus != NC_NOERR)
01101                         return lstatus;
01102                 
01103                 lstatus = ncx_putn_short_uchar(&xp, nput, value);
01104                 if(lstatus != NC_NOERR && status == NC_NOERR)
01105                 {
01106                         /* not fatal to the loop */
01107                         status = lstatus;
01108                 }
01109 
01110                 (void) ncp->nciop->rel(ncp->nciop, offset,
01111                                  RGN_MODIFIED); 
01112 
01113                 remaining -= extent;
01114                 if(remaining == 0)
01115                         break; /* normal loop exit */
01116                 offset += extent;
01117                 value += nput;
01118 
01119         }
01120 
01121         return status;
01122 }
01123 
01124 static int
01125 putNCvx_short_short(NC *ncp, const NC_var *varp,
01126                  const size_t *start, size_t nelems, const short *value)
01127 {
01128         off_t offset = NC_varoffset(ncp, varp, start);
01129         size_t remaining = varp->xsz * nelems;
01130         int status = NC_NOERR;
01131         void *xp;
01132 
01133         if(nelems == 0)
01134                 return NC_NOERR;
01135 
01136         assert(value != NULL);
01137 
01138         for(;;)
01139         {
01140                 size_t extent = MIN(remaining, ncp->chunk);
01141                 size_t nput = ncx_howmany(varp->type, extent);
01142 
01143                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01144                                  RGN_WRITE, &xp);       
01145                 if(lstatus != NC_NOERR)
01146                         return lstatus;
01147                 
01148                 lstatus = ncx_putn_short_short(&xp, nput, value);
01149                 if(lstatus != NC_NOERR && status == NC_NOERR)
01150                 {
01151                         /* not fatal to the loop */
01152                         status = lstatus;
01153                 }
01154 
01155                 (void) ncp->nciop->rel(ncp->nciop, offset,
01156                                  RGN_MODIFIED); 
01157 
01158                 remaining -= extent;
01159                 if(remaining == 0)
01160                         break; /* normal loop exit */
01161                 offset += extent;
01162                 value += nput;
01163 
01164         }
01165 
01166         return status;
01167 }
01168 
01169 static int
01170 putNCvx_short_int(NC *ncp, const NC_var *varp,
01171                  const size_t *start, size_t nelems, const int *value)
01172 {
01173         off_t offset = NC_varoffset(ncp, varp, start);
01174         size_t remaining = varp->xsz * nelems;
01175         int status = NC_NOERR;
01176         void *xp;
01177 
01178         if(nelems == 0)
01179                 return NC_NOERR;
01180 
01181         assert(value != NULL);
01182 
01183         for(;;)
01184         {
01185                 size_t extent = MIN(remaining, ncp->chunk);
01186                 size_t nput = ncx_howmany(varp->type, extent);
01187 
01188                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01189                                  RGN_WRITE, &xp);       
01190                 if(lstatus != NC_NOERR)
01191                         return lstatus;
01192                 
01193                 lstatus = ncx_putn_short_int(&xp, nput, value);
01194                 if(lstatus != NC_NOERR && status == NC_NOERR)
01195                 {
01196                         /* not fatal to the loop */
01197                         status = lstatus;
01198                 }
01199 
01200                 (void) ncp->nciop->rel(ncp->nciop, offset,
01201                                  RGN_MODIFIED); 
01202 
01203                 remaining -= extent;
01204                 if(remaining == 0)
01205                         break; /* normal loop exit */
01206                 offset += extent;
01207                 value += nput;
01208 
01209         }
01210 
01211         return status;
01212 }
01213 
01214 static int
01215 putNCvx_short_long(NC *ncp, const NC_var *varp,
01216                  const size_t *start, size_t nelems, const long *value)
01217 {
01218         off_t offset = NC_varoffset(ncp, varp, start);
01219         size_t remaining = varp->xsz * nelems;
01220         int status = NC_NOERR;
01221         void *xp;
01222 
01223         if(nelems == 0)
01224                 return NC_NOERR;
01225 
01226         assert(value != NULL);
01227 
01228         for(;;)
01229         {
01230                 size_t extent = MIN(remaining, ncp->chunk);
01231                 size_t nput = ncx_howmany(varp->type, extent);
01232 
01233                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01234                                  RGN_WRITE, &xp);       
01235                 if(lstatus != NC_NOERR)
01236                         return lstatus;
01237                 
01238                 lstatus = ncx_putn_short_long(&xp, nput, value);
01239                 if(lstatus != NC_NOERR && status == NC_NOERR)
01240                 {
01241                         /* not fatal to the loop */
01242                         status = lstatus;
01243                 }
01244 
01245                 (void) ncp->nciop->rel(ncp->nciop, offset,
01246                                  RGN_MODIFIED); 
01247 
01248                 remaining -= extent;
01249                 if(remaining == 0)
01250                         break; /* normal loop exit */
01251                 offset += extent;
01252                 value += nput;
01253 
01254         }
01255 
01256         return status;
01257 }
01258 
01259 static int
01260 putNCvx_short_float(NC *ncp, const NC_var *varp,
01261                  const size_t *start, size_t nelems, const float *value)
01262 {
01263         off_t offset = NC_varoffset(ncp, varp, start);
01264         size_t remaining = varp->xsz * nelems;
01265         int status = NC_NOERR;
01266         void *xp;
01267 
01268         if(nelems == 0)
01269                 return NC_NOERR;
01270 
01271         assert(value != NULL);
01272 
01273         for(;;)
01274         {
01275                 size_t extent = MIN(remaining, ncp->chunk);
01276                 size_t nput = ncx_howmany(varp->type, extent);
01277 
01278                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01279                                  RGN_WRITE, &xp);       
01280                 if(lstatus != NC_NOERR)
01281                         return lstatus;
01282                 
01283                 lstatus = ncx_putn_short_float(&xp, nput, value);
01284                 if(lstatus != NC_NOERR && status == NC_NOERR)
01285                 {
01286                         /* not fatal to the loop */
01287                         status = lstatus;
01288                 }
01289 
01290                 (void) ncp->nciop->rel(ncp->nciop, offset,
01291                                  RGN_MODIFIED); 
01292 
01293                 remaining -= extent;
01294                 if(remaining == 0)
01295                         break; /* normal loop exit */
01296                 offset += extent;
01297                 value += nput;
01298 
01299         }
01300 
01301         return status;
01302 }
01303 
01304 static int
01305 putNCvx_short_double(NC *ncp, const NC_var *varp,
01306                  const size_t *start, size_t nelems, const double *value)
01307 {
01308         off_t offset = NC_varoffset(ncp, varp, start);
01309         size_t remaining = varp->xsz * nelems;
01310         int status = NC_NOERR;
01311         void *xp;
01312 
01313         if(nelems == 0)
01314                 return NC_NOERR;
01315 
01316         assert(value != NULL);
01317 
01318         for(;;)
01319         {
01320                 size_t extent = MIN(remaining, ncp->chunk);
01321                 size_t nput = ncx_howmany(varp->type, extent);
01322 
01323                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01324                                  RGN_WRITE, &xp);       
01325                 if(lstatus != NC_NOERR)
01326                         return lstatus;
01327                 
01328                 lstatus = ncx_putn_short_double(&xp, nput, value);
01329                 if(lstatus != NC_NOERR && status == NC_NOERR)
01330                 {
01331                         /* not fatal to the loop */
01332                         status = lstatus;
01333                 }
01334 
01335                 (void) ncp->nciop->rel(ncp->nciop, offset,
01336                                  RGN_MODIFIED); 
01337 
01338                 remaining -= extent;
01339                 if(remaining == 0)
01340                         break; /* normal loop exit */
01341                 offset += extent;
01342                 value += nput;
01343 
01344         }
01345 
01346         return status;
01347 }
01348 
01349 
01350 static int
01351 putNCvx_int_schar(NC *ncp, const NC_var *varp,
01352                  const size_t *start, size_t nelems, const schar *value)
01353 {
01354         off_t offset = NC_varoffset(ncp, varp, start);
01355         size_t remaining = varp->xsz * nelems;
01356         int status = NC_NOERR;
01357         void *xp;
01358 
01359         if(nelems == 0)
01360                 return NC_NOERR;
01361 
01362         assert(value != NULL);
01363 
01364         for(;;)
01365         {
01366                 size_t extent = MIN(remaining, ncp->chunk);
01367                 size_t nput = ncx_howmany(varp->type, extent);
01368 
01369                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01370                                  RGN_WRITE, &xp);       
01371                 if(lstatus != NC_NOERR)
01372                         return lstatus;
01373                 
01374                 lstatus = ncx_putn_int_schar(&xp, nput, value);
01375                 if(lstatus != NC_NOERR && status == NC_NOERR)
01376                 {
01377                         /* not fatal to the loop */
01378                         status = lstatus;
01379                 }
01380 
01381                 (void) ncp->nciop->rel(ncp->nciop, offset,
01382                                  RGN_MODIFIED); 
01383 
01384                 remaining -= extent;
01385                 if(remaining == 0)
01386                         break; /* normal loop exit */
01387                 offset += extent;
01388                 value += nput;
01389 
01390         }
01391 
01392         return status;
01393 }
01394 
01395 static int
01396 putNCvx_int_uchar(NC *ncp, const NC_var *varp,
01397                  const size_t *start, size_t nelems, const uchar *value)
01398 {
01399         off_t offset = NC_varoffset(ncp, varp, start);
01400         size_t remaining = varp->xsz * nelems;
01401         int status = NC_NOERR;
01402         void *xp;
01403 
01404         if(nelems == 0)
01405                 return NC_NOERR;
01406 
01407         assert(value != NULL);
01408 
01409         for(;;)
01410         {
01411                 size_t extent = MIN(remaining, ncp->chunk);
01412                 size_t nput = ncx_howmany(varp->type, extent);
01413 
01414                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01415                                  RGN_WRITE, &xp);       
01416                 if(lstatus != NC_NOERR)
01417                         return lstatus;
01418                 
01419                 lstatus = ncx_putn_int_uchar(&xp, nput, value);
01420                 if(lstatus != NC_NOERR && status == NC_NOERR)
01421                 {
01422                         /* not fatal to the loop */
01423                         status = lstatus;
01424                 }
01425 
01426                 (void) ncp->nciop->rel(ncp->nciop, offset,
01427                                  RGN_MODIFIED); 
01428 
01429                 remaining -= extent;
01430                 if(remaining == 0)
01431                         break; /* normal loop exit */
01432                 offset += extent;
01433                 value += nput;
01434 
01435         }
01436 
01437         return status;
01438 }
01439 
01440 static int
01441 putNCvx_int_short(NC *ncp, const NC_var *varp,
01442                  const size_t *start, size_t nelems, const short *value)
01443 {
01444         off_t offset = NC_varoffset(ncp, varp, start);
01445         size_t remaining = varp->xsz * nelems;
01446         int status = NC_NOERR;
01447         void *xp;
01448 
01449         if(nelems == 0)
01450                 return NC_NOERR;
01451 
01452         assert(value != NULL);
01453 
01454         for(;;)
01455         {
01456                 size_t extent = MIN(remaining, ncp->chunk);
01457                 size_t nput = ncx_howmany(varp->type, extent);
01458 
01459                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01460                                  RGN_WRITE, &xp);       
01461                 if(lstatus != NC_NOERR)
01462                         return lstatus;
01463                 
01464                 lstatus = ncx_putn_int_short(&xp, nput, value);
01465                 if(lstatus != NC_NOERR && status == NC_NOERR)
01466                 {
01467                         /* not fatal to the loop */
01468                         status = lstatus;
01469                 }
01470 
01471                 (void) ncp->nciop->rel(ncp->nciop, offset,
01472                                  RGN_MODIFIED); 
01473 
01474                 remaining -= extent;
01475                 if(remaining == 0)
01476                         break; /* normal loop exit */
01477                 offset += extent;
01478                 value += nput;
01479 
01480         }
01481 
01482         return status;
01483 }
01484 
01485 static int
01486 putNCvx_int_int(NC *ncp, const NC_var *varp,
01487                  const size_t *start, size_t nelems, const int *value)
01488 {
01489         off_t offset = NC_varoffset(ncp, varp, start);
01490         size_t remaining = varp->xsz * nelems;
01491         int status = NC_NOERR;
01492         void *xp;
01493 
01494         if(nelems == 0)
01495                 return NC_NOERR;
01496 
01497         assert(value != NULL);
01498 
01499         for(;;)
01500         {
01501                 size_t extent = MIN(remaining, ncp->chunk);
01502                 size_t nput = ncx_howmany(varp->type, extent);
01503 
01504                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01505                                  RGN_WRITE, &xp);       
01506                 if(lstatus != NC_NOERR)
01507                         return lstatus;
01508                 
01509                 lstatus = ncx_putn_int_int(&xp, nput, value);
01510                 if(lstatus != NC_NOERR && status == NC_NOERR)
01511                 {
01512                         /* not fatal to the loop */
01513                         status = lstatus;
01514                 }
01515 
01516                 (void) ncp->nciop->rel(ncp->nciop, offset,
01517                                  RGN_MODIFIED); 
01518 
01519                 remaining -= extent;
01520                 if(remaining == 0)
01521                         break; /* normal loop exit */
01522                 offset += extent;
01523                 value += nput;
01524 
01525         }
01526 
01527         return status;
01528 }
01529 
01530 static int
01531 putNCvx_int_long(NC *ncp, const NC_var *varp,
01532                  const size_t *start, size_t nelems, const long *value)
01533 {
01534         off_t offset = NC_varoffset(ncp, varp, start);
01535         size_t remaining = varp->xsz * nelems;
01536         int status = NC_NOERR;
01537         void *xp;
01538 
01539         if(nelems == 0)
01540                 return NC_NOERR;
01541 
01542         assert(value != NULL);
01543 
01544         for(;;)
01545         {
01546                 size_t extent = MIN(remaining, ncp->chunk);
01547                 size_t nput = ncx_howmany(varp->type, extent);
01548 
01549                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01550                                  RGN_WRITE, &xp);       
01551                 if(lstatus != NC_NOERR)
01552                         return lstatus;
01553                 
01554                 lstatus = ncx_putn_int_long(&xp, nput, value);
01555                 if(lstatus != NC_NOERR && status == NC_NOERR)
01556                 {
01557                         /* not fatal to the loop */
01558                         status = lstatus;
01559                 }
01560 
01561                 (void) ncp->nciop->rel(ncp->nciop, offset,
01562                                  RGN_MODIFIED); 
01563 
01564                 remaining -= extent;
01565                 if(remaining == 0)
01566                         break; /* normal loop exit */
01567                 offset += extent;
01568                 value += nput;
01569 
01570         }
01571 
01572         return status;
01573 }
01574 
01575 static int
01576 putNCvx_int_float(NC *ncp, const NC_var *varp,
01577                  const size_t *start, size_t nelems, const float *value)
01578 {
01579         off_t offset = NC_varoffset(ncp, varp, start);
01580         size_t remaining = varp->xsz * nelems;
01581         int status = NC_NOERR;
01582         void *xp;
01583 
01584         if(nelems == 0)
01585                 return NC_NOERR;
01586 
01587         assert(value != NULL);
01588 
01589         for(;;)
01590         {
01591                 size_t extent = MIN(remaining, ncp->chunk);
01592                 size_t nput = ncx_howmany(varp->type, extent);
01593 
01594                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01595                                  RGN_WRITE, &xp);       
01596                 if(lstatus != NC_NOERR)
01597                         return lstatus;
01598                 
01599                 lstatus = ncx_putn_int_float(&xp, nput, value);
01600                 if(lstatus != NC_NOERR && status == NC_NOERR)
01601                 {
01602                         /* not fatal to the loop */
01603                         status = lstatus;
01604                 }
01605 
01606                 (void) ncp->nciop->rel(ncp->nciop, offset,
01607                                  RGN_MODIFIED); 
01608 
01609                 remaining -= extent;
01610                 if(remaining == 0)
01611                         break; /* normal loop exit */
01612                 offset += extent;
01613                 value += nput;
01614 
01615         }
01616 
01617         return status;
01618 }
01619 
01620 static int
01621 putNCvx_int_double(NC *ncp, const NC_var *varp,
01622                  const size_t *start, size_t nelems, const double *value)
01623 {
01624         off_t offset = NC_varoffset(ncp, varp, start);
01625         size_t remaining = varp->xsz * nelems;
01626         int status = NC_NOERR;
01627         void *xp;
01628 
01629         if(nelems == 0)
01630                 return NC_NOERR;
01631 
01632         assert(value != NULL);
01633 
01634         for(;;)
01635         {
01636                 size_t extent = MIN(remaining, ncp->chunk);
01637                 size_t nput = ncx_howmany(varp->type, extent);
01638 
01639                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01640                                  RGN_WRITE, &xp);       
01641                 if(lstatus != NC_NOERR)
01642                         return lstatus;
01643                 
01644                 lstatus = ncx_putn_int_double(&xp, nput, value);
01645                 if(lstatus != NC_NOERR && status == NC_NOERR)
01646                 {
01647                         /* not fatal to the loop */
01648                         status = lstatus;
01649                 }
01650 
01651                 (void) ncp->nciop->rel(ncp->nciop, offset,
01652                                  RGN_MODIFIED); 
01653 
01654                 remaining -= extent;
01655                 if(remaining == 0)
01656                         break; /* normal loop exit */
01657                 offset += extent;
01658                 value += nput;
01659 
01660         }
01661 
01662         return status;
01663 }
01664 
01665 
01666 static int
01667 putNCvx_float_schar(NC *ncp, const NC_var *varp,
01668                  const size_t *start, size_t nelems, const schar *value)
01669 {
01670         off_t offset = NC_varoffset(ncp, varp, start);
01671         size_t remaining = varp->xsz * nelems;
01672         int status = NC_NOERR;
01673         void *xp;
01674 
01675         if(nelems == 0)
01676                 return NC_NOERR;
01677 
01678         assert(value != NULL);
01679 
01680         for(;;)
01681         {
01682                 size_t extent = MIN(remaining, ncp->chunk);
01683                 size_t nput = ncx_howmany(varp->type, extent);
01684 
01685                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01686                                  RGN_WRITE, &xp);       
01687                 if(lstatus != NC_NOERR)
01688                         return lstatus;
01689                 
01690                 lstatus = ncx_putn_float_schar(&xp, nput, value);
01691                 if(lstatus != NC_NOERR && status == NC_NOERR)
01692                 {
01693                         /* not fatal to the loop */
01694                         status = lstatus;
01695                 }
01696 
01697                 (void) ncp->nciop->rel(ncp->nciop, offset,
01698                                  RGN_MODIFIED); 
01699 
01700                 remaining -= extent;
01701                 if(remaining == 0)
01702                         break; /* normal loop exit */
01703                 offset += extent;
01704                 value += nput;
01705 
01706         }
01707 
01708         return status;
01709 }
01710 
01711 static int
01712 putNCvx_float_uchar(NC *ncp, const NC_var *varp,
01713                  const size_t *start, size_t nelems, const uchar *value)
01714 {
01715         off_t offset = NC_varoffset(ncp, varp, start);
01716         size_t remaining = varp->xsz * nelems;
01717         int status = NC_NOERR;
01718         void *xp;
01719 
01720         if(nelems == 0)
01721                 return NC_NOERR;
01722 
01723         assert(value != NULL);
01724 
01725         for(;;)
01726         {
01727                 size_t extent = MIN(remaining, ncp->chunk);
01728                 size_t nput = ncx_howmany(varp->type, extent);
01729 
01730                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01731                                  RGN_WRITE, &xp);       
01732                 if(lstatus != NC_NOERR)
01733                         return lstatus;
01734                 
01735                 lstatus = ncx_putn_float_uchar(&xp, nput, value);
01736                 if(lstatus != NC_NOERR && status == NC_NOERR)
01737                 {
01738                         /* not fatal to the loop */
01739                         status = lstatus;
01740                 }
01741 
01742                 (void) ncp->nciop->rel(ncp->nciop, offset,
01743                                  RGN_MODIFIED); 
01744 
01745                 remaining -= extent;
01746                 if(remaining == 0)
01747                         break; /* normal loop exit */
01748                 offset += extent;
01749                 value += nput;
01750 
01751         }
01752 
01753         return status;
01754 }
01755 
01756 static int
01757 putNCvx_float_short(NC *ncp, const NC_var *varp,
01758                  const size_t *start, size_t nelems, const short *value)
01759 {
01760         off_t offset = NC_varoffset(ncp, varp, start);
01761         size_t remaining = varp->xsz * nelems;
01762         int status = NC_NOERR;
01763         void *xp;
01764 
01765         if(nelems == 0)
01766                 return NC_NOERR;
01767 
01768         assert(value != NULL);
01769 
01770         for(;;)
01771         {
01772                 size_t extent = MIN(remaining, ncp->chunk);
01773                 size_t nput = ncx_howmany(varp->type, extent);
01774 
01775                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01776                                  RGN_WRITE, &xp);       
01777                 if(lstatus != NC_NOERR)
01778                         return lstatus;
01779                 
01780                 lstatus = ncx_putn_float_short(&xp, nput, value);
01781                 if(lstatus != NC_NOERR && status == NC_NOERR)
01782                 {
01783                         /* not fatal to the loop */
01784                         status = lstatus;
01785                 }
01786 
01787                 (void) ncp->nciop->rel(ncp->nciop, offset,
01788                                  RGN_MODIFIED); 
01789 
01790                 remaining -= extent;
01791                 if(remaining == 0)
01792                         break; /* normal loop exit */
01793                 offset += extent;
01794                 value += nput;
01795 
01796         }
01797 
01798         return status;
01799 }
01800 
01801 static int
01802 putNCvx_float_int(NC *ncp, const NC_var *varp,
01803                  const size_t *start, size_t nelems, const int *value)
01804 {
01805         off_t offset = NC_varoffset(ncp, varp, start);
01806         size_t remaining = varp->xsz * nelems;
01807         int status = NC_NOERR;
01808         void *xp;
01809 
01810         if(nelems == 0)
01811                 return NC_NOERR;
01812 
01813         assert(value != NULL);
01814 
01815         for(;;)
01816         {
01817                 size_t extent = MIN(remaining, ncp->chunk);
01818                 size_t nput = ncx_howmany(varp->type, extent);
01819 
01820                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01821                                  RGN_WRITE, &xp);       
01822                 if(lstatus != NC_NOERR)
01823                         return lstatus;
01824                 
01825                 lstatus = ncx_putn_float_int(&xp, nput, value);
01826                 if(lstatus != NC_NOERR && status == NC_NOERR)
01827                 {
01828                         /* not fatal to the loop */
01829                         status = lstatus;
01830                 }
01831 
01832                 (void) ncp->nciop->rel(ncp->nciop, offset,
01833                                  RGN_MODIFIED); 
01834 
01835                 remaining -= extent;
01836                 if(remaining == 0)
01837                         break; /* normal loop exit */
01838                 offset += extent;
01839                 value += nput;
01840 
01841         }
01842 
01843         return status;
01844 }
01845 
01846 static int
01847 putNCvx_float_long(NC *ncp, const NC_var *varp,
01848                  const size_t *start, size_t nelems, const long *value)
01849 {
01850         off_t offset = NC_varoffset(ncp, varp, start);
01851         size_t remaining = varp->xsz * nelems;
01852         int status = NC_NOERR;
01853         void *xp;
01854 
01855         if(nelems == 0)
01856                 return NC_NOERR;
01857 
01858         assert(value != NULL);
01859 
01860         for(;;)
01861         {
01862                 size_t extent = MIN(remaining, ncp->chunk);
01863                 size_t nput = ncx_howmany(varp->type, extent);
01864 
01865                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01866                                  RGN_WRITE, &xp);       
01867                 if(lstatus != NC_NOERR)
01868                         return lstatus;
01869                 
01870                 lstatus = ncx_putn_float_long(&xp, nput, value);
01871                 if(lstatus != NC_NOERR && status == NC_NOERR)
01872                 {
01873                         /* not fatal to the loop */
01874                         status = lstatus;
01875                 }
01876 
01877                 (void) ncp->nciop->rel(ncp->nciop, offset,
01878                                  RGN_MODIFIED); 
01879 
01880                 remaining -= extent;
01881                 if(remaining == 0)
01882                         break; /* normal loop exit */
01883                 offset += extent;
01884                 value += nput;
01885 
01886         }
01887 
01888         return status;
01889 }
01890 
01891 static int
01892 putNCvx_float_float(NC *ncp, const NC_var *varp,
01893                  const size_t *start, size_t nelems, const float *value)
01894 {
01895         off_t offset = NC_varoffset(ncp, varp, start);
01896         size_t remaining = varp->xsz * nelems;
01897         int status = NC_NOERR;
01898         void *xp;
01899 
01900         if(nelems == 0)
01901                 return NC_NOERR;
01902 
01903         assert(value != NULL);
01904 
01905         for(;;)
01906         {
01907                 size_t extent = MIN(remaining, ncp->chunk);
01908                 size_t nput = ncx_howmany(varp->type, extent);
01909 
01910                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01911                                  RGN_WRITE, &xp);       
01912                 if(lstatus != NC_NOERR)
01913                         return lstatus;
01914                 
01915                 lstatus = ncx_putn_float_float(&xp, nput, value);
01916                 if(lstatus != NC_NOERR && status == NC_NOERR)
01917                 {
01918                         /* not fatal to the loop */
01919                         status = lstatus;
01920                 }
01921 
01922                 (void) ncp->nciop->rel(ncp->nciop, offset,
01923                                  RGN_MODIFIED); 
01924 
01925                 remaining -= extent;
01926                 if(remaining == 0)
01927                         break; /* normal loop exit */
01928                 offset += extent;
01929                 value += nput;
01930 
01931         }
01932 
01933         return status;
01934 }
01935 
01936 static int
01937 putNCvx_float_double(NC *ncp, const NC_var *varp,
01938                  const size_t *start, size_t nelems, const double *value)
01939 {
01940         off_t offset = NC_varoffset(ncp, varp, start);
01941         size_t remaining = varp->xsz * nelems;
01942         int status = NC_NOERR;
01943         void *xp;
01944 
01945         if(nelems == 0)
01946                 return NC_NOERR;
01947 
01948         assert(value != NULL);
01949 
01950         for(;;)
01951         {
01952                 size_t extent = MIN(remaining, ncp->chunk);
01953                 size_t nput = ncx_howmany(varp->type, extent);
01954 
01955                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
01956                                  RGN_WRITE, &xp);       
01957                 if(lstatus != NC_NOERR)
01958                         return lstatus;
01959                 
01960                 lstatus = ncx_putn_float_double(&xp, nput, value);
01961                 if(lstatus != NC_NOERR && status == NC_NOERR)
01962                 {
01963                         /* not fatal to the loop */
01964                         status = lstatus;
01965                 }
01966 
01967                 (void) ncp->nciop->rel(ncp->nciop, offset,
01968                                  RGN_MODIFIED); 
01969 
01970                 remaining -= extent;
01971                 if(remaining == 0)
01972                         break; /* normal loop exit */
01973                 offset += extent;
01974                 value += nput;
01975 
01976         }
01977 
01978         return status;
01979 }
01980 
01981 
01982 static int
01983 putNCvx_double_schar(NC *ncp, const NC_var *varp,
01984                  const size_t *start, size_t nelems, const schar *value)
01985 {
01986         off_t offset = NC_varoffset(ncp, varp, start);
01987         size_t remaining = varp->xsz * nelems;
01988         int status = NC_NOERR;
01989         void *xp;
01990 
01991         if(nelems == 0)
01992                 return NC_NOERR;
01993 
01994         assert(value != NULL);
01995 
01996         for(;;)
01997         {
01998                 size_t extent = MIN(remaining, ncp->chunk);
01999                 size_t nput = ncx_howmany(varp->type, extent);
02000 
02001                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02002                                  RGN_WRITE, &xp);       
02003                 if(lstatus != NC_NOERR)
02004                         return lstatus;
02005                 
02006                 lstatus = ncx_putn_double_schar(&xp, nput, value);
02007                 if(lstatus != NC_NOERR && status == NC_NOERR)
02008                 {
02009                         /* not fatal to the loop */
02010                         status = lstatus;
02011                 }
02012 
02013                 (void) ncp->nciop->rel(ncp->nciop, offset,
02014                                  RGN_MODIFIED); 
02015 
02016                 remaining -= extent;
02017                 if(remaining == 0)
02018                         break; /* normal loop exit */
02019                 offset += extent;
02020                 value += nput;
02021 
02022         }
02023 
02024         return status;
02025 }
02026 
02027 static int
02028 putNCvx_double_uchar(NC *ncp, const NC_var *varp,
02029                  const size_t *start, size_t nelems, const uchar *value)
02030 {
02031         off_t offset = NC_varoffset(ncp, varp, start);
02032         size_t remaining = varp->xsz * nelems;
02033         int status = NC_NOERR;
02034         void *xp;
02035 
02036         if(nelems == 0)
02037                 return NC_NOERR;
02038 
02039         assert(value != NULL);
02040 
02041         for(;;)
02042         {
02043                 size_t extent = MIN(remaining, ncp->chunk);
02044                 size_t nput = ncx_howmany(varp->type, extent);
02045 
02046                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02047                                  RGN_WRITE, &xp);       
02048                 if(lstatus != NC_NOERR)
02049                         return lstatus;
02050                 
02051                 lstatus = ncx_putn_double_uchar(&xp, nput, value);
02052                 if(lstatus != NC_NOERR && status == NC_NOERR)
02053                 {
02054                         /* not fatal to the loop */
02055                         status = lstatus;
02056                 }
02057 
02058                 (void) ncp->nciop->rel(ncp->nciop, offset,
02059                                  RGN_MODIFIED); 
02060 
02061                 remaining -= extent;
02062                 if(remaining == 0)
02063                         break; /* normal loop exit */
02064                 offset += extent;
02065                 value += nput;
02066 
02067         }
02068 
02069         return status;
02070 }
02071 
02072 static int
02073 putNCvx_double_short(NC *ncp, const NC_var *varp,
02074                  const size_t *start, size_t nelems, const short *value)
02075 {
02076         off_t offset = NC_varoffset(ncp, varp, start);
02077         size_t remaining = varp->xsz * nelems;
02078         int status = NC_NOERR;
02079         void *xp;
02080 
02081         if(nelems == 0)
02082                 return NC_NOERR;
02083 
02084         assert(value != NULL);
02085 
02086         for(;;)
02087         {
02088                 size_t extent = MIN(remaining, ncp->chunk);
02089                 size_t nput = ncx_howmany(varp->type, extent);
02090 
02091                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02092                                  RGN_WRITE, &xp);       
02093                 if(lstatus != NC_NOERR)
02094                         return lstatus;
02095                 
02096                 lstatus = ncx_putn_double_short(&xp, nput, value);
02097                 if(lstatus != NC_NOERR && status == NC_NOERR)
02098                 {
02099                         /* not fatal to the loop */
02100                         status = lstatus;
02101                 }
02102 
02103                 (void) ncp->nciop->rel(ncp->nciop, offset,
02104                                  RGN_MODIFIED); 
02105 
02106                 remaining -= extent;
02107                 if(remaining == 0)
02108                         break; /* normal loop exit */
02109                 offset += extent;
02110                 value += nput;
02111 
02112         }
02113 
02114         return status;
02115 }
02116 
02117 static int
02118 putNCvx_double_int(NC *ncp, const NC_var *varp,
02119                  const size_t *start, size_t nelems, const int *value)
02120 {
02121         off_t offset = NC_varoffset(ncp, varp, start);
02122         size_t remaining = varp->xsz * nelems;
02123         int status = NC_NOERR;
02124         void *xp;
02125 
02126         if(nelems == 0)
02127                 return NC_NOERR;
02128 
02129         assert(value != NULL);
02130 
02131         for(;;)
02132         {
02133                 size_t extent = MIN(remaining, ncp->chunk);
02134                 size_t nput = ncx_howmany(varp->type, extent);
02135 
02136                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02137                                  RGN_WRITE, &xp);       
02138                 if(lstatus != NC_NOERR)
02139                         return lstatus;
02140                 
02141                 lstatus = ncx_putn_double_int(&xp, nput, value);
02142                 if(lstatus != NC_NOERR && status == NC_NOERR)
02143                 {
02144                         /* not fatal to the loop */
02145                         status = lstatus;
02146                 }
02147 
02148                 (void) ncp->nciop->rel(ncp->nciop, offset,
02149                                  RGN_MODIFIED); 
02150 
02151                 remaining -= extent;
02152                 if(remaining == 0)
02153                         break; /* normal loop exit */
02154                 offset += extent;
02155                 value += nput;
02156 
02157         }
02158 
02159         return status;
02160 }
02161 
02162 static int
02163 putNCvx_double_long(NC *ncp, const NC_var *varp,
02164                  const size_t *start, size_t nelems, const long *value)
02165 {
02166         off_t offset = NC_varoffset(ncp, varp, start);
02167         size_t remaining = varp->xsz * nelems;
02168         int status = NC_NOERR;
02169         void *xp;
02170 
02171         if(nelems == 0)
02172                 return NC_NOERR;
02173 
02174         assert(value != NULL);
02175 
02176         for(;;)
02177         {
02178                 size_t extent = MIN(remaining, ncp->chunk);
02179                 size_t nput = ncx_howmany(varp->type, extent);
02180 
02181                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02182                                  RGN_WRITE, &xp);       
02183                 if(lstatus != NC_NOERR)
02184                         return lstatus;
02185                 
02186                 lstatus = ncx_putn_double_long(&xp, nput, value);
02187                 if(lstatus != NC_NOERR && status == NC_NOERR)
02188                 {
02189                         /* not fatal to the loop */
02190                         status = lstatus;
02191                 }
02192 
02193                 (void) ncp->nciop->rel(ncp->nciop, offset,
02194                                  RGN_MODIFIED); 
02195 
02196                 remaining -= extent;
02197                 if(remaining == 0)
02198                         break; /* normal loop exit */
02199                 offset += extent;
02200                 value += nput;
02201 
02202         }
02203 
02204         return status;
02205 }
02206 
02207 static int
02208 putNCvx_double_float(NC *ncp, const NC_var *varp,
02209                  const size_t *start, size_t nelems, const float *value)
02210 {
02211         off_t offset = NC_varoffset(ncp, varp, start);
02212         size_t remaining = varp->xsz * nelems;
02213         int status = NC_NOERR;
02214         void *xp;
02215 
02216         if(nelems == 0)
02217                 return NC_NOERR;
02218 
02219         assert(value != NULL);
02220 
02221         for(;;)
02222         {
02223                 size_t extent = MIN(remaining, ncp->chunk);
02224                 size_t nput = ncx_howmany(varp->type, extent);
02225 
02226                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02227                                  RGN_WRITE, &xp);       
02228                 if(lstatus != NC_NOERR)
02229                         return lstatus;
02230                 
02231                 lstatus = ncx_putn_double_float(&xp, nput, value);
02232                 if(lstatus != NC_NOERR && status == NC_NOERR)
02233                 {
02234                         /* not fatal to the loop */
02235                         status = lstatus;
02236                 }
02237 
02238                 (void) ncp->nciop->rel(ncp->nciop, offset,
02239                                  RGN_MODIFIED); 
02240 
02241                 remaining -= extent;
02242                 if(remaining == 0)
02243                         break; /* normal loop exit */
02244                 offset += extent;
02245                 value += nput;
02246 
02247         }
02248 
02249         return status;
02250 }
02251 
02252 static int
02253 putNCvx_double_double(NC *ncp, const NC_var *varp,
02254                  const size_t *start, size_t nelems, const double *value)
02255 {
02256         off_t offset = NC_varoffset(ncp, varp, start);
02257         size_t remaining = varp->xsz * nelems;
02258         int status = NC_NOERR;
02259         void *xp;
02260 
02261         if(nelems == 0)
02262                 return NC_NOERR;
02263 
02264         assert(value != NULL);
02265 
02266         for(;;)
02267         {
02268                 size_t extent = MIN(remaining, ncp->chunk);
02269                 size_t nput = ncx_howmany(varp->type, extent);
02270 
02271                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02272                                  RGN_WRITE, &xp);       
02273                 if(lstatus != NC_NOERR)
02274                         return lstatus;
02275                 
02276                 lstatus = ncx_putn_double_double(&xp, nput, value);
02277                 if(lstatus != NC_NOERR && status == NC_NOERR)
02278                 {
02279                         /* not fatal to the loop */
02280                         status = lstatus;
02281                 }
02282 
02283                 (void) ncp->nciop->rel(ncp->nciop, offset,
02284                                  RGN_MODIFIED); 
02285 
02286                 remaining -= extent;
02287                 if(remaining == 0)
02288                         break; /* normal loop exit */
02289                 offset += extent;
02290                 value += nput;
02291 
02292         }
02293 
02294         return status;
02295 }
02296 
02297 
02298 
02299 
02300 static int
02301 putNCv_text(NC *ncp, const NC_var *varp,
02302                  const size_t *start, size_t nelems, const char *value)
02303 {
02304         if(varp->type != NC_CHAR)
02305                 return NC_ECHAR;
02306         return putNCvx_char_char(ncp, varp, start, nelems, value);
02307 }
02308 
02309 static int
02310 putNCv_schar(NC *ncp, const NC_var *varp,
02311                  const size_t *start, size_t nelems, const schar *value)
02312 {
02313         switch(varp->type){
02314         case NC_CHAR:
02315                 return NC_ECHAR;
02316         case NC_BYTE:
02317                 return putNCvx_schar_schar(ncp, varp, start, nelems,
02318                         value);
02319         case NC_SHORT:
02320                 return putNCvx_short_schar(ncp, varp, start, nelems,
02321                         value);
02322         case NC_INT:
02323                 return putNCvx_int_schar(ncp, varp, start, nelems,
02324                         value);
02325         case NC_FLOAT:
02326                 return putNCvx_float_schar(ncp, varp, start, nelems,
02327                         value);
02328         case NC_DOUBLE: 
02329                 return putNCvx_double_schar(ncp, varp, start, nelems,
02330                         value);
02331         }
02332         return NC_EBADTYPE;
02333 }
02334 
02335 static int
02336 putNCv_uchar(NC *ncp, const NC_var *varp,
02337                  const size_t *start, size_t nelems, const uchar *value)
02338 {
02339         switch(varp->type){
02340         case NC_CHAR:
02341                 return NC_ECHAR;
02342         case NC_BYTE:
02343                 return putNCvx_schar_uchar(ncp, varp, start, nelems,
02344                         value);
02345         case NC_SHORT:
02346                 return putNCvx_short_uchar(ncp, varp, start, nelems,
02347                         value);
02348         case NC_INT:
02349                 return putNCvx_int_uchar(ncp, varp, start, nelems,
02350                         value);
02351         case NC_FLOAT:
02352                 return putNCvx_float_uchar(ncp, varp, start, nelems,
02353                         value);
02354         case NC_DOUBLE: 
02355                 return putNCvx_double_uchar(ncp, varp, start, nelems,
02356                         value);
02357         }
02358         return NC_EBADTYPE;
02359 }
02360 
02361 static int
02362 putNCv_short(NC *ncp, const NC_var *varp,
02363                  const size_t *start, size_t nelems, const short *value)
02364 {
02365         switch(varp->type){
02366         case NC_CHAR:
02367                 return NC_ECHAR;
02368         case NC_BYTE:
02369                 return putNCvx_schar_short(ncp, varp, start, nelems,
02370                         value);
02371         case NC_SHORT:
02372                 return putNCvx_short_short(ncp, varp, start, nelems,
02373                         value);
02374         case NC_INT:
02375                 return putNCvx_int_short(ncp, varp, start, nelems,
02376                         value);
02377         case NC_FLOAT:
02378                 return putNCvx_float_short(ncp, varp, start, nelems,
02379                         value);
02380         case NC_DOUBLE: 
02381                 return putNCvx_double_short(ncp, varp, start, nelems,
02382                         value);
02383         }
02384         return NC_EBADTYPE;
02385 }
02386 
02387 static int
02388 putNCv_int(NC *ncp, const NC_var *varp,
02389                  const size_t *start, size_t nelems, const int *value)
02390 {
02391         switch(varp->type){
02392         case NC_CHAR:
02393                 return NC_ECHAR;
02394         case NC_BYTE:
02395                 return putNCvx_schar_int(ncp, varp, start, nelems,
02396                         value);
02397         case NC_SHORT:
02398                 return putNCvx_short_int(ncp, varp, start, nelems,
02399                         value);
02400         case NC_INT:
02401                 return putNCvx_int_int(ncp, varp, start, nelems,
02402                         value);
02403         case NC_FLOAT:
02404                 return putNCvx_float_int(ncp, varp, start, nelems,
02405                         value);
02406         case NC_DOUBLE: 
02407                 return putNCvx_double_int(ncp, varp, start, nelems,
02408                         value);
02409         }
02410         return NC_EBADTYPE;
02411 }
02412 
02413 static int
02414 putNCv_long(NC *ncp, const NC_var *varp,
02415                  const size_t *start, size_t nelems, const long *value)
02416 {
02417         switch(varp->type){
02418         case NC_CHAR:
02419                 return NC_ECHAR;
02420         case NC_BYTE:
02421                 return putNCvx_schar_long(ncp, varp, start, nelems,
02422                         value);
02423         case NC_SHORT:
02424                 return putNCvx_short_long(ncp, varp, start, nelems,
02425                         value);
02426         case NC_INT:
02427                 return putNCvx_int_long(ncp, varp, start, nelems,
02428                         value);
02429         case NC_FLOAT:
02430                 return putNCvx_float_long(ncp, varp, start, nelems,
02431                         value);
02432         case NC_DOUBLE: 
02433                 return putNCvx_double_long(ncp, varp, start, nelems,
02434                         value);
02435         }
02436         return NC_EBADTYPE;
02437 }
02438 
02439 static int
02440 putNCv_float(NC *ncp, const NC_var *varp,
02441                  const size_t *start, size_t nelems, const float *value)
02442 {
02443         switch(varp->type){
02444         case NC_CHAR:
02445                 return NC_ECHAR;
02446         case NC_BYTE:
02447                 return putNCvx_schar_float(ncp, varp, start, nelems,
02448                         value);
02449         case NC_SHORT:
02450                 return putNCvx_short_float(ncp, varp, start, nelems,
02451                         value);
02452         case NC_INT:
02453                 return putNCvx_int_float(ncp, varp, start, nelems,
02454                         value);
02455         case NC_FLOAT:
02456                 return putNCvx_float_float(ncp, varp, start, nelems,
02457                         value);
02458         case NC_DOUBLE: 
02459                 return putNCvx_double_float(ncp, varp, start, nelems,
02460                         value);
02461         }
02462         return NC_EBADTYPE;
02463 }
02464 
02465 static int
02466 putNCv_double(NC *ncp, const NC_var *varp,
02467                  const size_t *start, size_t nelems, const double *value)
02468 {
02469         switch(varp->type){
02470         case NC_CHAR:
02471                 return NC_ECHAR;
02472         case NC_BYTE:
02473                 return putNCvx_schar_double(ncp, varp, start, nelems,
02474                         value);
02475         case NC_SHORT:
02476                 return putNCvx_short_double(ncp, varp, start, nelems,
02477                         value);
02478         case NC_INT:
02479                 return putNCvx_int_double(ncp, varp, start, nelems,
02480                         value);
02481         case NC_FLOAT:
02482                 return putNCvx_float_double(ncp, varp, start, nelems,
02483                         value);
02484         case NC_DOUBLE: 
02485                 return putNCvx_double_double(ncp, varp, start, nelems,
02486                         value);
02487         }
02488         return NC_EBADTYPE;
02489 }
02490 
02491 
02492 
02493 
02494 static int
02495 getNCvx_char_char(const NC *ncp, const NC_var *varp,
02496                  const size_t *start, size_t nelems, char *value)
02497 {
02498         off_t offset = NC_varoffset(ncp, varp, start);
02499         size_t remaining = varp->xsz * nelems;
02500         int status = NC_NOERR;
02501         const void *xp;
02502 
02503         if(nelems == 0)
02504                 return NC_NOERR;
02505 
02506         assert(value != NULL);
02507 
02508         for(;;)
02509         {
02510                 size_t extent = MIN(remaining, ncp->chunk);
02511                 size_t nget = ncx_howmany(varp->type, extent);
02512 
02513                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02514                                  0, (void **)&xp);      /* cast away const */
02515                 if(lstatus != NC_NOERR)
02516                         return lstatus;
02517                 
02518                 lstatus = ncx_getn_char_char(&xp, nget, value);
02519                 if(lstatus != NC_NOERR && status == NC_NOERR)
02520                         status = lstatus;
02521 
02522                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02523 
02524                 remaining -= extent;
02525                 if(remaining == 0)
02526                         break; /* normal loop exit */
02527                 offset += extent;
02528                 value += nget;
02529         }
02530 
02531         return status;
02532 }
02533 
02534 
02535 static int
02536 getNCvx_schar_schar(const NC *ncp, const NC_var *varp,
02537                  const size_t *start, size_t nelems, schar *value)
02538 {
02539         off_t offset = NC_varoffset(ncp, varp, start);
02540         size_t remaining = varp->xsz * nelems;
02541         int status = NC_NOERR;
02542         const void *xp;
02543 
02544         if(nelems == 0)
02545                 return NC_NOERR;
02546 
02547         assert(value != NULL);
02548 
02549         for(;;)
02550         {
02551                 size_t extent = MIN(remaining, ncp->chunk);
02552                 size_t nget = ncx_howmany(varp->type, extent);
02553 
02554                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02555                                  0, (void **)&xp);      /* cast away const */
02556                 if(lstatus != NC_NOERR)
02557                         return lstatus;
02558                 
02559                 lstatus = ncx_getn_schar_schar(&xp, nget, value);
02560                 if(lstatus != NC_NOERR && status == NC_NOERR)
02561                         status = lstatus;
02562 
02563                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02564 
02565                 remaining -= extent;
02566                 if(remaining == 0)
02567                         break; /* normal loop exit */
02568                 offset += extent;
02569                 value += nget;
02570         }
02571 
02572         return status;
02573 }
02574 
02575 static int
02576 getNCvx_schar_uchar(const NC *ncp, const NC_var *varp,
02577                  const size_t *start, size_t nelems, uchar *value)
02578 {
02579         off_t offset = NC_varoffset(ncp, varp, start);
02580         size_t remaining = varp->xsz * nelems;
02581         int status = NC_NOERR;
02582         const void *xp;
02583 
02584         if(nelems == 0)
02585                 return NC_NOERR;
02586 
02587         assert(value != NULL);
02588 
02589         for(;;)
02590         {
02591                 size_t extent = MIN(remaining, ncp->chunk);
02592                 size_t nget = ncx_howmany(varp->type, extent);
02593 
02594                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02595                                  0, (void **)&xp);      /* cast away const */
02596                 if(lstatus != NC_NOERR)
02597                         return lstatus;
02598                 
02599                 lstatus = ncx_getn_schar_uchar(&xp, nget, value);
02600                 if(lstatus != NC_NOERR && status == NC_NOERR)
02601                         status = lstatus;
02602 
02603                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02604 
02605                 remaining -= extent;
02606                 if(remaining == 0)
02607                         break; /* normal loop exit */
02608                 offset += extent;
02609                 value += nget;
02610         }
02611 
02612         return status;
02613 }
02614 
02615 static int
02616 getNCvx_schar_short(const NC *ncp, const NC_var *varp,
02617                  const size_t *start, size_t nelems, short *value)
02618 {
02619         off_t offset = NC_varoffset(ncp, varp, start);
02620         size_t remaining = varp->xsz * nelems;
02621         int status = NC_NOERR;
02622         const void *xp;
02623 
02624         if(nelems == 0)
02625                 return NC_NOERR;
02626 
02627         assert(value != NULL);
02628 
02629         for(;;)
02630         {
02631                 size_t extent = MIN(remaining, ncp->chunk);
02632                 size_t nget = ncx_howmany(varp->type, extent);
02633 
02634                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02635                                  0, (void **)&xp);      /* cast away const */
02636                 if(lstatus != NC_NOERR)
02637                         return lstatus;
02638                 
02639                 lstatus = ncx_getn_schar_short(&xp, nget, value);
02640                 if(lstatus != NC_NOERR && status == NC_NOERR)
02641                         status = lstatus;
02642 
02643                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02644 
02645                 remaining -= extent;
02646                 if(remaining == 0)
02647                         break; /* normal loop exit */
02648                 offset += extent;
02649                 value += nget;
02650         }
02651 
02652         return status;
02653 }
02654 
02655 static int
02656 getNCvx_schar_int(const NC *ncp, const NC_var *varp,
02657                  const size_t *start, size_t nelems, int *value)
02658 {
02659         off_t offset = NC_varoffset(ncp, varp, start);
02660         size_t remaining = varp->xsz * nelems;
02661         int status = NC_NOERR;
02662         const void *xp;
02663 
02664         if(nelems == 0)
02665                 return NC_NOERR;
02666 
02667         assert(value != NULL);
02668 
02669         for(;;)
02670         {
02671                 size_t extent = MIN(remaining, ncp->chunk);
02672                 size_t nget = ncx_howmany(varp->type, extent);
02673 
02674                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02675                                  0, (void **)&xp);      /* cast away const */
02676                 if(lstatus != NC_NOERR)
02677                         return lstatus;
02678                 
02679                 lstatus = ncx_getn_schar_int(&xp, nget, value);
02680                 if(lstatus != NC_NOERR && status == NC_NOERR)
02681                         status = lstatus;
02682 
02683                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02684 
02685                 remaining -= extent;
02686                 if(remaining == 0)
02687                         break; /* normal loop exit */
02688                 offset += extent;
02689                 value += nget;
02690         }
02691 
02692         return status;
02693 }
02694 
02695 static int
02696 getNCvx_schar_long(const NC *ncp, const NC_var *varp,
02697                  const size_t *start, size_t nelems, long *value)
02698 {
02699         off_t offset = NC_varoffset(ncp, varp, start);
02700         size_t remaining = varp->xsz * nelems;
02701         int status = NC_NOERR;
02702         const void *xp;
02703 
02704         if(nelems == 0)
02705                 return NC_NOERR;
02706 
02707         assert(value != NULL);
02708 
02709         for(;;)
02710         {
02711                 size_t extent = MIN(remaining, ncp->chunk);
02712                 size_t nget = ncx_howmany(varp->type, extent);
02713 
02714                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02715                                  0, (void **)&xp);      /* cast away const */
02716                 if(lstatus != NC_NOERR)
02717                         return lstatus;
02718                 
02719                 lstatus = ncx_getn_schar_long(&xp, nget, value);
02720                 if(lstatus != NC_NOERR && status == NC_NOERR)
02721                         status = lstatus;
02722 
02723                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02724 
02725                 remaining -= extent;
02726                 if(remaining == 0)
02727                         break; /* normal loop exit */
02728                 offset += extent;
02729                 value += nget;
02730         }
02731 
02732         return status;
02733 }
02734 
02735 static int
02736 getNCvx_schar_float(const NC *ncp, const NC_var *varp,
02737                  const size_t *start, size_t nelems, float *value)
02738 {
02739         off_t offset = NC_varoffset(ncp, varp, start);
02740         size_t remaining = varp->xsz * nelems;
02741         int status = NC_NOERR;
02742         const void *xp;
02743 
02744         if(nelems == 0)
02745                 return NC_NOERR;
02746 
02747         assert(value != NULL);
02748 
02749         for(;;)
02750         {
02751                 size_t extent = MIN(remaining, ncp->chunk);
02752                 size_t nget = ncx_howmany(varp->type, extent);
02753 
02754                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02755                                  0, (void **)&xp);      /* cast away const */
02756                 if(lstatus != NC_NOERR)
02757                         return lstatus;
02758                 
02759                 lstatus = ncx_getn_schar_float(&xp, nget, value);
02760                 if(lstatus != NC_NOERR && status == NC_NOERR)
02761                         status = lstatus;
02762 
02763                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02764 
02765                 remaining -= extent;
02766                 if(remaining == 0)
02767                         break; /* normal loop exit */
02768                 offset += extent;
02769                 value += nget;
02770         }
02771 
02772         return status;
02773 }
02774 
02775 static int
02776 getNCvx_schar_double(const NC *ncp, const NC_var *varp,
02777                  const size_t *start, size_t nelems, double *value)
02778 {
02779         off_t offset = NC_varoffset(ncp, varp, start);
02780         size_t remaining = varp->xsz * nelems;
02781         int status = NC_NOERR;
02782         const void *xp;
02783 
02784         if(nelems == 0)
02785                 return NC_NOERR;
02786 
02787         assert(value != NULL);
02788 
02789         for(;;)
02790         {
02791                 size_t extent = MIN(remaining, ncp->chunk);
02792                 size_t nget = ncx_howmany(varp->type, extent);
02793 
02794                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02795                                  0, (void **)&xp);      /* cast away const */
02796                 if(lstatus != NC_NOERR)
02797                         return lstatus;
02798                 
02799                 lstatus = ncx_getn_schar_double(&xp, nget, value);
02800                 if(lstatus != NC_NOERR && status == NC_NOERR)
02801                         status = lstatus;
02802 
02803                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02804 
02805                 remaining -= extent;
02806                 if(remaining == 0)
02807                         break; /* normal loop exit */
02808                 offset += extent;
02809                 value += nget;
02810         }
02811 
02812         return status;
02813 }
02814 
02815 
02816 static int
02817 getNCvx_short_schar(const NC *ncp, const NC_var *varp,
02818                  const size_t *start, size_t nelems, schar *value)
02819 {
02820         off_t offset = NC_varoffset(ncp, varp, start);
02821         size_t remaining = varp->xsz * nelems;
02822         int status = NC_NOERR;
02823         const void *xp;
02824 
02825         if(nelems == 0)
02826                 return NC_NOERR;
02827 
02828         assert(value != NULL);
02829 
02830         for(;;)
02831         {
02832                 size_t extent = MIN(remaining, ncp->chunk);
02833                 size_t nget = ncx_howmany(varp->type, extent);
02834 
02835                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02836                                  0, (void **)&xp);      /* cast away const */
02837                 if(lstatus != NC_NOERR)
02838                         return lstatus;
02839                 
02840                 lstatus = ncx_getn_short_schar(&xp, nget, value);
02841                 if(lstatus != NC_NOERR && status == NC_NOERR)
02842                         status = lstatus;
02843 
02844                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02845 
02846                 remaining -= extent;
02847                 if(remaining == 0)
02848                         break; /* normal loop exit */
02849                 offset += extent;
02850                 value += nget;
02851         }
02852 
02853         return status;
02854 }
02855 
02856 static int
02857 getNCvx_short_uchar(const NC *ncp, const NC_var *varp,
02858                  const size_t *start, size_t nelems, uchar *value)
02859 {
02860         off_t offset = NC_varoffset(ncp, varp, start);
02861         size_t remaining = varp->xsz * nelems;
02862         int status = NC_NOERR;
02863         const void *xp;
02864 
02865         if(nelems == 0)
02866                 return NC_NOERR;
02867 
02868         assert(value != NULL);
02869 
02870         for(;;)
02871         {
02872                 size_t extent = MIN(remaining, ncp->chunk);
02873                 size_t nget = ncx_howmany(varp->type, extent);
02874 
02875                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02876                                  0, (void **)&xp);      /* cast away const */
02877                 if(lstatus != NC_NOERR)
02878                         return lstatus;
02879                 
02880                 lstatus = ncx_getn_short_uchar(&xp, nget, value);
02881                 if(lstatus != NC_NOERR && status == NC_NOERR)
02882                         status = lstatus;
02883 
02884                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02885 
02886                 remaining -= extent;
02887                 if(remaining == 0)
02888                         break; /* normal loop exit */
02889                 offset += extent;
02890                 value += nget;
02891         }
02892 
02893         return status;
02894 }
02895 
02896 static int
02897 getNCvx_short_short(const NC *ncp, const NC_var *varp,
02898                  const size_t *start, size_t nelems, short *value)
02899 {
02900         off_t offset = NC_varoffset(ncp, varp, start);
02901         size_t remaining = varp->xsz * nelems;
02902         int status = NC_NOERR;
02903         const void *xp;
02904 
02905         if(nelems == 0)
02906                 return NC_NOERR;
02907 
02908         assert(value != NULL);
02909 
02910         for(;;)
02911         {
02912                 size_t extent = MIN(remaining, ncp->chunk);
02913                 size_t nget = ncx_howmany(varp->type, extent);
02914 
02915                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02916                                  0, (void **)&xp);      /* cast away const */
02917                 if(lstatus != NC_NOERR)
02918                         return lstatus;
02919                 
02920                 lstatus = ncx_getn_short_short(&xp, nget, value);
02921                 if(lstatus != NC_NOERR && status == NC_NOERR)
02922                         status = lstatus;
02923 
02924                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02925 
02926                 remaining -= extent;
02927                 if(remaining == 0)
02928                         break; /* normal loop exit */
02929                 offset += extent;
02930                 value += nget;
02931         }
02932 
02933         return status;
02934 }
02935 
02936 static int
02937 getNCvx_short_int(const NC *ncp, const NC_var *varp,
02938                  const size_t *start, size_t nelems, int *value)
02939 {
02940         off_t offset = NC_varoffset(ncp, varp, start);
02941         size_t remaining = varp->xsz * nelems;
02942         int status = NC_NOERR;
02943         const void *xp;
02944 
02945         if(nelems == 0)
02946                 return NC_NOERR;
02947 
02948         assert(value != NULL);
02949 
02950         for(;;)
02951         {
02952                 size_t extent = MIN(remaining, ncp->chunk);
02953                 size_t nget = ncx_howmany(varp->type, extent);
02954 
02955                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02956                                  0, (void **)&xp);      /* cast away const */
02957                 if(lstatus != NC_NOERR)
02958                         return lstatus;
02959                 
02960                 lstatus = ncx_getn_short_int(&xp, nget, value);
02961                 if(lstatus != NC_NOERR && status == NC_NOERR)
02962                         status = lstatus;
02963 
02964                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
02965 
02966                 remaining -= extent;
02967                 if(remaining == 0)
02968                         break; /* normal loop exit */
02969                 offset += extent;
02970                 value += nget;
02971         }
02972 
02973         return status;
02974 }
02975 
02976 static int
02977 getNCvx_short_long(const NC *ncp, const NC_var *varp,
02978                  const size_t *start, size_t nelems, long *value)
02979 {
02980         off_t offset = NC_varoffset(ncp, varp, start);
02981         size_t remaining = varp->xsz * nelems;
02982         int status = NC_NOERR;
02983         const void *xp;
02984 
02985         if(nelems == 0)
02986                 return NC_NOERR;
02987 
02988         assert(value != NULL);
02989 
02990         for(;;)
02991         {
02992                 size_t extent = MIN(remaining, ncp->chunk);
02993                 size_t nget = ncx_howmany(varp->type, extent);
02994 
02995                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
02996                                  0, (void **)&xp);      /* cast away const */
02997                 if(lstatus != NC_NOERR)
02998                         return lstatus;
02999                 
03000                 lstatus = ncx_getn_short_long(&xp, nget, value);
03001                 if(lstatus != NC_NOERR && status == NC_NOERR)
03002                         status = lstatus;
03003 
03004                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03005 
03006                 remaining -= extent;
03007                 if(remaining == 0)
03008                         break; /* normal loop exit */
03009                 offset += extent;
03010                 value += nget;
03011         }
03012 
03013         return status;
03014 }
03015 
03016 static int
03017 getNCvx_short_float(const NC *ncp, const NC_var *varp,
03018                  const size_t *start, size_t nelems, float *value)
03019 {
03020         off_t offset = NC_varoffset(ncp, varp, start);
03021         size_t remaining = varp->xsz * nelems;
03022         int status = NC_NOERR;
03023         const void *xp;
03024 
03025         if(nelems == 0)
03026                 return NC_NOERR;
03027 
03028         assert(value != NULL);
03029 
03030         for(;;)
03031         {
03032                 size_t extent = MIN(remaining, ncp->chunk);
03033                 size_t nget = ncx_howmany(varp->type, extent);
03034 
03035                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03036                                  0, (void **)&xp);      /* cast away const */
03037                 if(lstatus != NC_NOERR)
03038                         return lstatus;
03039                 
03040                 lstatus = ncx_getn_short_float(&xp, nget, value);
03041                 if(lstatus != NC_NOERR && status == NC_NOERR)
03042                         status = lstatus;
03043 
03044                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03045 
03046                 remaining -= extent;
03047                 if(remaining == 0)
03048                         break; /* normal loop exit */
03049                 offset += extent;
03050                 value += nget;
03051         }
03052 
03053         return status;
03054 }
03055 
03056 static int
03057 getNCvx_short_double(const NC *ncp, const NC_var *varp,
03058                  const size_t *start, size_t nelems, double *value)
03059 {
03060         off_t offset = NC_varoffset(ncp, varp, start);
03061         size_t remaining = varp->xsz * nelems;
03062         int status = NC_NOERR;
03063         const void *xp;
03064 
03065         if(nelems == 0)
03066                 return NC_NOERR;
03067 
03068         assert(value != NULL);
03069 
03070         for(;;)
03071         {
03072                 size_t extent = MIN(remaining, ncp->chunk);
03073                 size_t nget = ncx_howmany(varp->type, extent);
03074 
03075                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03076                                  0, (void **)&xp);      /* cast away const */
03077                 if(lstatus != NC_NOERR)
03078                         return lstatus;
03079                 
03080                 lstatus = ncx_getn_short_double(&xp, nget, value);
03081                 if(lstatus != NC_NOERR && status == NC_NOERR)
03082                         status = lstatus;
03083 
03084                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03085 
03086                 remaining -= extent;
03087                 if(remaining == 0)
03088                         break; /* normal loop exit */
03089                 offset += extent;
03090                 value += nget;
03091         }
03092 
03093         return status;
03094 }
03095 
03096 
03097 static int
03098 getNCvx_int_schar(const NC *ncp, const NC_var *varp,
03099                  const size_t *start, size_t nelems, schar *value)
03100 {
03101         off_t offset = NC_varoffset(ncp, varp, start);
03102         size_t remaining = varp->xsz * nelems;
03103         int status = NC_NOERR;
03104         const void *xp;
03105 
03106         if(nelems == 0)
03107                 return NC_NOERR;
03108 
03109         assert(value != NULL);
03110 
03111         for(;;)
03112         {
03113                 size_t extent = MIN(remaining, ncp->chunk);
03114                 size_t nget = ncx_howmany(varp->type, extent);
03115 
03116                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03117                                  0, (void **)&xp);      /* cast away const */
03118                 if(lstatus != NC_NOERR)
03119                         return lstatus;
03120                 
03121                 lstatus = ncx_getn_int_schar(&xp, nget, value);
03122                 if(lstatus != NC_NOERR && status == NC_NOERR)
03123                         status = lstatus;
03124 
03125                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03126 
03127                 remaining -= extent;
03128                 if(remaining == 0)
03129                         break; /* normal loop exit */
03130                 offset += extent;
03131                 value += nget;
03132         }
03133 
03134         return status;
03135 }
03136 
03137 static int
03138 getNCvx_int_uchar(const NC *ncp, const NC_var *varp,
03139                  const size_t *start, size_t nelems, uchar *value)
03140 {
03141         off_t offset = NC_varoffset(ncp, varp, start);
03142         size_t remaining = varp->xsz * nelems;
03143         int status = NC_NOERR;
03144         const void *xp;
03145 
03146         if(nelems == 0)
03147                 return NC_NOERR;
03148 
03149         assert(value != NULL);
03150 
03151         for(;;)
03152         {
03153                 size_t extent = MIN(remaining, ncp->chunk);
03154                 size_t nget = ncx_howmany(varp->type, extent);
03155 
03156                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03157                                  0, (void **)&xp);      /* cast away const */
03158                 if(lstatus != NC_NOERR)
03159                         return lstatus;
03160                 
03161                 lstatus = ncx_getn_int_uchar(&xp, nget, value);
03162                 if(lstatus != NC_NOERR && status == NC_NOERR)
03163                         status = lstatus;
03164 
03165                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03166 
03167                 remaining -= extent;
03168                 if(remaining == 0)
03169                         break; /* normal loop exit */
03170                 offset += extent;
03171                 value += nget;
03172         }
03173 
03174         return status;
03175 }
03176 
03177 static int
03178 getNCvx_int_short(const NC *ncp, const NC_var *varp,
03179                  const size_t *start, size_t nelems, short *value)
03180 {
03181         off_t offset = NC_varoffset(ncp, varp, start);
03182         size_t remaining = varp->xsz * nelems;
03183         int status = NC_NOERR;
03184         const void *xp;
03185 
03186         if(nelems == 0)
03187                 return NC_NOERR;
03188 
03189         assert(value != NULL);
03190 
03191         for(;;)
03192         {
03193                 size_t extent = MIN(remaining, ncp->chunk);
03194                 size_t nget = ncx_howmany(varp->type, extent);
03195 
03196                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03197                                  0, (void **)&xp);      /* cast away const */
03198                 if(lstatus != NC_NOERR)
03199                         return lstatus;
03200                 
03201                 lstatus = ncx_getn_int_short(&xp, nget, value);
03202                 if(lstatus != NC_NOERR && status == NC_NOERR)
03203                         status = lstatus;
03204 
03205                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03206 
03207                 remaining -= extent;
03208                 if(remaining == 0)
03209                         break; /* normal loop exit */
03210                 offset += extent;
03211                 value += nget;
03212         }
03213 
03214         return status;
03215 }
03216 
03217 static int
03218 getNCvx_int_int(const NC *ncp, const NC_var *varp,
03219                  const size_t *start, size_t nelems, int *value)
03220 {
03221         off_t offset = NC_varoffset(ncp, varp, start);
03222         size_t remaining = varp->xsz * nelems;
03223         int status = NC_NOERR;
03224         const void *xp;
03225 
03226         if(nelems == 0)
03227                 return NC_NOERR;
03228 
03229         assert(value != NULL);
03230 
03231         for(;;)
03232         {
03233                 size_t extent = MIN(remaining, ncp->chunk);
03234                 size_t nget = ncx_howmany(varp->type, extent);
03235 
03236                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03237                                  0, (void **)&xp);      /* cast away const */
03238                 if(lstatus != NC_NOERR)
03239                         return lstatus;
03240                 
03241                 lstatus = ncx_getn_int_int(&xp, nget, value);
03242                 if(lstatus != NC_NOERR && status == NC_NOERR)
03243                         status = lstatus;
03244 
03245                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03246 
03247                 remaining -= extent;
03248                 if(remaining == 0)
03249                         break; /* normal loop exit */
03250                 offset += extent;
03251                 value += nget;
03252         }
03253 
03254         return status;
03255 }
03256 
03257 static int
03258 getNCvx_int_long(const NC *ncp, const NC_var *varp,
03259                  const size_t *start, size_t nelems, long *value)
03260 {
03261         off_t offset = NC_varoffset(ncp, varp, start);
03262         size_t remaining = varp->xsz * nelems;
03263         int status = NC_NOERR;
03264         const void *xp;
03265 
03266         if(nelems == 0)
03267                 return NC_NOERR;
03268 
03269         assert(value != NULL);
03270 
03271         for(;;)
03272         {
03273                 size_t extent = MIN(remaining, ncp->chunk);
03274                 size_t nget = ncx_howmany(varp->type, extent);
03275 
03276                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03277                                  0, (void **)&xp);      /* cast away const */
03278                 if(lstatus != NC_NOERR)
03279                         return lstatus;
03280                 
03281                 lstatus = ncx_getn_int_long(&xp, nget, value);
03282                 if(lstatus != NC_NOERR && status == NC_NOERR)
03283                         status = lstatus;
03284 
03285                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03286 
03287                 remaining -= extent;
03288                 if(remaining == 0)
03289                         break; /* normal loop exit */
03290                 offset += extent;
03291                 value += nget;
03292         }
03293 
03294         return status;
03295 }
03296 
03297 static int
03298 getNCvx_int_float(const NC *ncp, const NC_var *varp,
03299                  const size_t *start, size_t nelems, float *value)
03300 {
03301         off_t offset = NC_varoffset(ncp, varp, start);
03302         size_t remaining = varp->xsz * nelems;
03303         int status = NC_NOERR;
03304         const void *xp;
03305 
03306         if(nelems == 0)
03307                 return NC_NOERR;
03308 
03309         assert(value != NULL);
03310 
03311         for(;;)
03312         {
03313                 size_t extent = MIN(remaining, ncp->chunk);
03314                 size_t nget = ncx_howmany(varp->type, extent);
03315 
03316                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03317                                  0, (void **)&xp);      /* cast away const */
03318                 if(lstatus != NC_NOERR)
03319                         return lstatus;
03320                 
03321                 lstatus = ncx_getn_int_float(&xp, nget, value);
03322                 if(lstatus != NC_NOERR && status == NC_NOERR)
03323                         status = lstatus;
03324 
03325                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03326 
03327                 remaining -= extent;
03328                 if(remaining == 0)
03329                         break; /* normal loop exit */
03330                 offset += extent;
03331                 value += nget;
03332         }
03333 
03334         return status;
03335 }
03336 
03337 static int
03338 getNCvx_int_double(const NC *ncp, const NC_var *varp,
03339                  const size_t *start, size_t nelems, double *value)
03340 {
03341         off_t offset = NC_varoffset(ncp, varp, start);
03342         size_t remaining = varp->xsz * nelems;
03343         int status = NC_NOERR;
03344         const void *xp;
03345 
03346         if(nelems == 0)
03347                 return NC_NOERR;
03348 
03349         assert(value != NULL);
03350 
03351         for(;;)
03352         {
03353                 size_t extent = MIN(remaining, ncp->chunk);
03354                 size_t nget = ncx_howmany(varp->type, extent);
03355 
03356                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03357                                  0, (void **)&xp);      /* cast away const */
03358                 if(lstatus != NC_NOERR)
03359                         return lstatus;
03360                 
03361                 lstatus = ncx_getn_int_double(&xp, nget, value);
03362                 if(lstatus != NC_NOERR && status == NC_NOERR)
03363                         status = lstatus;
03364 
03365                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03366 
03367                 remaining -= extent;
03368                 if(remaining == 0)
03369                         break; /* normal loop exit */
03370                 offset += extent;
03371                 value += nget;
03372         }
03373 
03374         return status;
03375 }
03376 
03377 
03378 static int
03379 getNCvx_float_schar(const NC *ncp, const NC_var *varp,
03380                  const size_t *start, size_t nelems, schar *value)
03381 {
03382         off_t offset = NC_varoffset(ncp, varp, start);
03383         size_t remaining = varp->xsz * nelems;
03384         int status = NC_NOERR;
03385         const void *xp;
03386 
03387         if(nelems == 0)
03388                 return NC_NOERR;
03389 
03390         assert(value != NULL);
03391 
03392         for(;;)
03393         {
03394                 size_t extent = MIN(remaining, ncp->chunk);
03395                 size_t nget = ncx_howmany(varp->type, extent);
03396 
03397                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03398                                  0, (void **)&xp);      /* cast away const */
03399                 if(lstatus != NC_NOERR)
03400                         return lstatus;
03401                 
03402                 lstatus = ncx_getn_float_schar(&xp, nget, value);
03403                 if(lstatus != NC_NOERR && status == NC_NOERR)
03404                         status = lstatus;
03405 
03406                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03407 
03408                 remaining -= extent;
03409                 if(remaining == 0)
03410                         break; /* normal loop exit */
03411                 offset += extent;
03412                 value += nget;
03413         }
03414 
03415         return status;
03416 }
03417 
03418 static int
03419 getNCvx_float_uchar(const NC *ncp, const NC_var *varp,
03420                  const size_t *start, size_t nelems, uchar *value)
03421 {
03422         off_t offset = NC_varoffset(ncp, varp, start);
03423         size_t remaining = varp->xsz * nelems;
03424         int status = NC_NOERR;
03425         const void *xp;
03426 
03427         if(nelems == 0)
03428                 return NC_NOERR;
03429 
03430         assert(value != NULL);
03431 
03432         for(;;)
03433         {
03434                 size_t extent = MIN(remaining, ncp->chunk);
03435                 size_t nget = ncx_howmany(varp->type, extent);
03436 
03437                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03438                                  0, (void **)&xp);      /* cast away const */
03439                 if(lstatus != NC_NOERR)
03440                         return lstatus;
03441                 
03442                 lstatus = ncx_getn_float_uchar(&xp, nget, value);
03443                 if(lstatus != NC_NOERR && status == NC_NOERR)
03444                         status = lstatus;
03445 
03446                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03447 
03448                 remaining -= extent;
03449                 if(remaining == 0)
03450                         break; /* normal loop exit */
03451                 offset += extent;
03452                 value += nget;
03453         }
03454 
03455         return status;
03456 }
03457 
03458 static int
03459 getNCvx_float_short(const NC *ncp, const NC_var *varp,
03460                  const size_t *start, size_t nelems, short *value)
03461 {
03462         off_t offset = NC_varoffset(ncp, varp, start);
03463         size_t remaining = varp->xsz * nelems;
03464         int status = NC_NOERR;
03465         const void *xp;
03466 
03467         if(nelems == 0)
03468                 return NC_NOERR;
03469 
03470         assert(value != NULL);
03471 
03472         for(;;)
03473         {
03474                 size_t extent = MIN(remaining, ncp->chunk);
03475                 size_t nget = ncx_howmany(varp->type, extent);
03476 
03477                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03478                                  0, (void **)&xp);      /* cast away const */
03479                 if(lstatus != NC_NOERR)
03480                         return lstatus;
03481                 
03482                 lstatus = ncx_getn_float_short(&xp, nget, value);
03483                 if(lstatus != NC_NOERR && status == NC_NOERR)
03484                         status = lstatus;
03485 
03486                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03487 
03488                 remaining -= extent;
03489                 if(remaining == 0)
03490                         break; /* normal loop exit */
03491                 offset += extent;
03492                 value += nget;
03493         }
03494 
03495         return status;
03496 }
03497 
03498 static int
03499 getNCvx_float_int(const NC *ncp, const NC_var *varp,
03500                  const size_t *start, size_t nelems, int *value)
03501 {
03502         off_t offset = NC_varoffset(ncp, varp, start);
03503         size_t remaining = varp->xsz * nelems;
03504         int status = NC_NOERR;
03505         const void *xp;
03506 
03507         if(nelems == 0)
03508                 return NC_NOERR;
03509 
03510         assert(value != NULL);
03511 
03512         for(;;)
03513         {
03514                 size_t extent = MIN(remaining, ncp->chunk);
03515                 size_t nget = ncx_howmany(varp->type, extent);
03516 
03517                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03518                                  0, (void **)&xp);      /* cast away const */
03519                 if(lstatus != NC_NOERR)
03520                         return lstatus;
03521                 
03522                 lstatus = ncx_getn_float_int(&xp, nget, value);
03523                 if(lstatus != NC_NOERR && status == NC_NOERR)
03524                         status = lstatus;
03525 
03526                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03527 
03528                 remaining -= extent;
03529                 if(remaining == 0)
03530                         break; /* normal loop exit */
03531                 offset += extent;
03532                 value += nget;
03533         }
03534 
03535         return status;
03536 }
03537 
03538 static int
03539 getNCvx_float_long(const NC *ncp, const NC_var *varp,
03540                  const size_t *start, size_t nelems, long *value)
03541 {
03542         off_t offset = NC_varoffset(ncp, varp, start);
03543         size_t remaining = varp->xsz * nelems;
03544         int status = NC_NOERR;
03545         const void *xp;
03546 
03547         if(nelems == 0)
03548                 return NC_NOERR;
03549 
03550         assert(value != NULL);
03551 
03552         for(;;)
03553         {
03554                 size_t extent = MIN(remaining, ncp->chunk);
03555                 size_t nget = ncx_howmany(varp->type, extent);
03556 
03557                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03558                                  0, (void **)&xp);      /* cast away const */
03559                 if(lstatus != NC_NOERR)
03560                         return lstatus;
03561                 
03562                 lstatus = ncx_getn_float_long(&xp, nget, value);
03563                 if(lstatus != NC_NOERR && status == NC_NOERR)
03564                         status = lstatus;
03565 
03566                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03567 
03568                 remaining -= extent;
03569                 if(remaining == 0)
03570                         break; /* normal loop exit */
03571                 offset += extent;
03572                 value += nget;
03573         }
03574 
03575         return status;
03576 }
03577 
03578 static int
03579 getNCvx_float_float(const NC *ncp, const NC_var *varp,
03580                  const size_t *start, size_t nelems, float *value)
03581 {
03582         off_t offset = NC_varoffset(ncp, varp, start);
03583         size_t remaining = varp->xsz * nelems;
03584         int status = NC_NOERR;
03585         const void *xp;
03586 
03587         if(nelems == 0)
03588                 return NC_NOERR;
03589 
03590         assert(value != NULL);
03591 
03592         for(;;)
03593         {
03594                 size_t extent = MIN(remaining, ncp->chunk);
03595                 size_t nget = ncx_howmany(varp->type, extent);
03596 
03597                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03598                                  0, (void **)&xp);      /* cast away const */
03599                 if(lstatus != NC_NOERR)
03600                         return lstatus;
03601                 
03602                 lstatus = ncx_getn_float_float(&xp, nget, value);
03603                 if(lstatus != NC_NOERR && status == NC_NOERR)
03604                         status = lstatus;
03605 
03606                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03607 
03608                 remaining -= extent;
03609                 if(remaining == 0)
03610                         break; /* normal loop exit */
03611                 offset += extent;
03612                 value += nget;
03613         }
03614 
03615         return status;
03616 }
03617 
03618 static int
03619 getNCvx_float_double(const NC *ncp, const NC_var *varp,
03620                  const size_t *start, size_t nelems, double *value)
03621 {
03622         off_t offset = NC_varoffset(ncp, varp, start);
03623         size_t remaining = varp->xsz * nelems;
03624         int status = NC_NOERR;
03625         const void *xp;
03626 
03627         if(nelems == 0)
03628                 return NC_NOERR;
03629 
03630         assert(value != NULL);
03631 
03632         for(;;)
03633         {
03634                 size_t extent = MIN(remaining, ncp->chunk);
03635                 size_t nget = ncx_howmany(varp->type, extent);
03636 
03637                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03638                                  0, (void **)&xp);      /* cast away const */
03639                 if(lstatus != NC_NOERR)
03640                         return lstatus;
03641                 
03642                 lstatus = ncx_getn_float_double(&xp, nget, value);
03643                 if(lstatus != NC_NOERR && status == NC_NOERR)
03644                         status = lstatus;
03645 
03646                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03647 
03648                 remaining -= extent;
03649                 if(remaining == 0)
03650                         break; /* normal loop exit */
03651                 offset += extent;
03652                 value += nget;
03653         }
03654 
03655         return status;
03656 }
03657 
03658 
03659 static int
03660 getNCvx_double_schar(const NC *ncp, const NC_var *varp,
03661                  const size_t *start, size_t nelems, schar *value)
03662 {
03663         off_t offset = NC_varoffset(ncp, varp, start);
03664         size_t remaining = varp->xsz * nelems;
03665         int status = NC_NOERR;
03666         const void *xp;
03667 
03668         if(nelems == 0)
03669                 return NC_NOERR;
03670 
03671         assert(value != NULL);
03672 
03673         for(;;)
03674         {
03675                 size_t extent = MIN(remaining, ncp->chunk);
03676                 size_t nget = ncx_howmany(varp->type, extent);
03677 
03678                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03679                                  0, (void **)&xp);      /* cast away const */
03680                 if(lstatus != NC_NOERR)
03681                         return lstatus;
03682                 
03683                 lstatus = ncx_getn_double_schar(&xp, nget, value);
03684                 if(lstatus != NC_NOERR && status == NC_NOERR)
03685                         status = lstatus;
03686 
03687                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03688 
03689                 remaining -= extent;
03690                 if(remaining == 0)
03691                         break; /* normal loop exit */
03692                 offset += extent;
03693                 value += nget;
03694         }
03695 
03696         return status;
03697 }
03698 
03699 static int
03700 getNCvx_double_uchar(const NC *ncp, const NC_var *varp,
03701                  const size_t *start, size_t nelems, uchar *value)
03702 {
03703         off_t offset = NC_varoffset(ncp, varp, start);
03704         size_t remaining = varp->xsz * nelems;
03705         int status = NC_NOERR;
03706         const void *xp;
03707 
03708         if(nelems == 0)
03709                 return NC_NOERR;
03710 
03711         assert(value != NULL);
03712 
03713         for(;;)
03714         {
03715                 size_t extent = MIN(remaining, ncp->chunk);
03716                 size_t nget = ncx_howmany(varp->type, extent);
03717 
03718                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03719                                  0, (void **)&xp);      /* cast away const */
03720                 if(lstatus != NC_NOERR)
03721                         return lstatus;
03722                 
03723                 lstatus = ncx_getn_double_uchar(&xp, nget, value);
03724                 if(lstatus != NC_NOERR && status == NC_NOERR)
03725                         status = lstatus;
03726 
03727                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03728 
03729                 remaining -= extent;
03730                 if(remaining == 0)
03731                         break; /* normal loop exit */
03732                 offset += extent;
03733                 value += nget;
03734         }
03735 
03736         return status;
03737 }
03738 
03739 static int
03740 getNCvx_double_short(const NC *ncp, const NC_var *varp,
03741                  const size_t *start, size_t nelems, short *value)
03742 {
03743         off_t offset = NC_varoffset(ncp, varp, start);
03744         size_t remaining = varp->xsz * nelems;
03745         int status = NC_NOERR;
03746         const void *xp;
03747 
03748         if(nelems == 0)
03749                 return NC_NOERR;
03750 
03751         assert(value != NULL);
03752 
03753         for(;;)
03754         {
03755                 size_t extent = MIN(remaining, ncp->chunk);
03756                 size_t nget = ncx_howmany(varp->type, extent);
03757 
03758                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03759                                  0, (void **)&xp);      /* cast away const */
03760                 if(lstatus != NC_NOERR)
03761                         return lstatus;
03762                 
03763                 lstatus = ncx_getn_double_short(&xp, nget, value);
03764                 if(lstatus != NC_NOERR && status == NC_NOERR)
03765                         status = lstatus;
03766 
03767                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03768 
03769                 remaining -= extent;
03770                 if(remaining == 0)
03771                         break; /* normal loop exit */
03772                 offset += extent;
03773                 value += nget;
03774         }
03775 
03776         return status;
03777 }
03778 
03779 static int
03780 getNCvx_double_int(const NC *ncp, const NC_var *varp,
03781                  const size_t *start, size_t nelems, int *value)
03782 {
03783         off_t offset = NC_varoffset(ncp, varp, start);
03784         size_t remaining = varp->xsz * nelems;
03785         int status = NC_NOERR;
03786         const void *xp;
03787 
03788         if(nelems == 0)
03789                 return NC_NOERR;
03790 
03791         assert(value != NULL);
03792 
03793         for(;;)
03794         {
03795                 size_t extent = MIN(remaining, ncp->chunk);
03796                 size_t nget = ncx_howmany(varp->type, extent);
03797 
03798                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03799                                  0, (void **)&xp);      /* cast away const */
03800                 if(lstatus != NC_NOERR)
03801                         return lstatus;
03802                 
03803                 lstatus = ncx_getn_double_int(&xp, nget, value);
03804                 if(lstatus != NC_NOERR && status == NC_NOERR)
03805                         status = lstatus;
03806 
03807                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03808 
03809                 remaining -= extent;
03810                 if(remaining == 0)
03811                         break; /* normal loop exit */
03812                 offset += extent;
03813                 value += nget;
03814         }
03815 
03816         return status;
03817 }
03818 
03819 static int
03820 getNCvx_double_long(const NC *ncp, const NC_var *varp,
03821                  const size_t *start, size_t nelems, long *value)
03822 {
03823         off_t offset = NC_varoffset(ncp, varp, start);
03824         size_t remaining = varp->xsz * nelems;
03825         int status = NC_NOERR;
03826         const void *xp;
03827 
03828         if(nelems == 0)
03829                 return NC_NOERR;
03830 
03831         assert(value != NULL);
03832 
03833         for(;;)
03834         {
03835                 size_t extent = MIN(remaining, ncp->chunk);
03836                 size_t nget = ncx_howmany(varp->type, extent);
03837 
03838                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03839                                  0, (void **)&xp);      /* cast away const */
03840                 if(lstatus != NC_NOERR)
03841                         return lstatus;
03842                 
03843                 lstatus = ncx_getn_double_long(&xp, nget, value);
03844                 if(lstatus != NC_NOERR && status == NC_NOERR)
03845                         status = lstatus;
03846 
03847                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03848 
03849                 remaining -= extent;
03850                 if(remaining == 0)
03851                         break; /* normal loop exit */
03852                 offset += extent;
03853                 value += nget;
03854         }
03855 
03856         return status;
03857 }
03858 
03859 static int
03860 getNCvx_double_float(const NC *ncp, const NC_var *varp,
03861                  const size_t *start, size_t nelems, float *value)
03862 {
03863         off_t offset = NC_varoffset(ncp, varp, start);
03864         size_t remaining = varp->xsz * nelems;
03865         int status = NC_NOERR;
03866         const void *xp;
03867 
03868         if(nelems == 0)
03869                 return NC_NOERR;
03870 
03871         assert(value != NULL);
03872 
03873         for(;;)
03874         {
03875                 size_t extent = MIN(remaining, ncp->chunk);
03876                 size_t nget = ncx_howmany(varp->type, extent);
03877 
03878                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03879                                  0, (void **)&xp);      /* cast away const */
03880                 if(lstatus != NC_NOERR)
03881                         return lstatus;
03882                 
03883                 lstatus = ncx_getn_double_float(&xp, nget, value);
03884                 if(lstatus != NC_NOERR && status == NC_NOERR)
03885                         status = lstatus;
03886 
03887                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03888 
03889                 remaining -= extent;
03890                 if(remaining == 0)
03891                         break; /* normal loop exit */
03892                 offset += extent;
03893                 value += nget;
03894         }
03895 
03896         return status;
03897 }
03898 
03899 static int
03900 getNCvx_double_double(const NC *ncp, const NC_var *varp,
03901                  const size_t *start, size_t nelems, double *value)
03902 {
03903         off_t offset = NC_varoffset(ncp, varp, start);
03904         size_t remaining = varp->xsz * nelems;
03905         int status = NC_NOERR;
03906         const void *xp;
03907 
03908         if(nelems == 0)
03909                 return NC_NOERR;
03910 
03911         assert(value != NULL);
03912 
03913         for(;;)
03914         {
03915                 size_t extent = MIN(remaining, ncp->chunk);
03916                 size_t nget = ncx_howmany(varp->type, extent);
03917 
03918                 int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
03919                                  0, (void **)&xp);      /* cast away const */
03920                 if(lstatus != NC_NOERR)
03921                         return lstatus;
03922                 
03923                 lstatus = ncx_getn_double_double(&xp, nget, value);
03924                 if(lstatus != NC_NOERR && status == NC_NOERR)
03925                         status = lstatus;
03926 
03927                 (void) ncp->nciop->rel(ncp->nciop, offset, 0);  
03928 
03929                 remaining -= extent;
03930                 if(remaining == 0)
03931                         break; /* normal loop exit */
03932                 offset += extent;
03933                 value += nget;
03934         }
03935 
03936         return status;
03937 }
03938 
03939 
03940 
03941 
03942 static int
03943 getNCv_schar(const NC *ncp, const NC_var *varp,
03944                  const size_t *start, size_t nelems, schar *value)
03945 {
03946         switch(varp->type){
03947         case NC_CHAR:
03948                 return NC_ECHAR;
03949         case NC_BYTE:
03950                 return getNCvx_schar_schar(ncp, varp, start, nelems,
03951                         value);
03952         case NC_SHORT:
03953                 return getNCvx_short_schar(ncp, varp, start, nelems,
03954                         value);
03955         case NC_INT:
03956                 return getNCvx_int_schar(ncp, varp, start, nelems,
03957                         value);
03958         case NC_FLOAT:
03959                 return getNCvx_float_schar(ncp, varp, start, nelems,
03960                         value);
03961         case NC_DOUBLE: 
03962                 return getNCvx_double_schar(ncp, varp, start, nelems,
03963                         value);
03964         }
03965         return NC_EBADTYPE;
03966 }
03967 
03968 static int
03969 getNCv_uchar(const NC *ncp, const NC_var *varp,
03970                  const size_t *start, size_t nelems, uchar *value)
03971 {
03972         switch(varp->type){
03973         case NC_CHAR:
03974                 return NC_ECHAR;
03975         case NC_BYTE:
03976                 return getNCvx_schar_uchar(ncp, varp, start, nelems,
03977                         value);
03978         case NC_SHORT:
03979                 return getNCvx_short_uchar(ncp, varp, start, nelems,
03980                         value);
03981         case NC_INT:
03982                 return getNCvx_int_uchar(ncp, varp, start, nelems,
03983                         value);
03984         case NC_FLOAT:
03985                 return getNCvx_float_uchar(ncp, varp, start, nelems,
03986                         value);
03987         case NC_DOUBLE: 
03988                 return getNCvx_double_uchar(ncp, varp, start, nelems,
03989                         value);
03990         }
03991         return NC_EBADTYPE;
03992 }
03993 
03994 static int
03995 getNCv_short(const NC *ncp, const NC_var *varp,
03996                  const size_t *start, size_t nelems, short *value)
03997 {
03998         switch(varp->type){
03999         case NC_CHAR:
04000                 return NC_ECHAR;
04001         case NC_BYTE:
04002                 return getNCvx_schar_short(ncp, varp, start, nelems,
04003                         value);
04004         case NC_SHORT:
04005                 return getNCvx_short_short(ncp, varp, start, nelems,
04006                         value);
04007         case NC_INT:
04008                 return getNCvx_int_short(ncp, varp, start, nelems,
04009                         value);
04010         case NC_FLOAT:
04011                 return getNCvx_float_short(ncp, varp, start, nelems,
04012                         value);
04013         case NC_DOUBLE: 
04014                 return getNCvx_double_short(ncp, varp, start, nelems,
04015                         value);
04016         }
04017         return NC_EBADTYPE;
04018 }
04019 
04020 static int
04021 getNCv_int(const NC *ncp, const NC_var *varp,
04022                  const size_t *start, size_t nelems, int *value)
04023 {
04024         switch(varp->type){
04025         case NC_CHAR:
04026                 return NC_ECHAR;
04027         case NC_BYTE:
04028                 return getNCvx_schar_int(ncp, varp, start, nelems,
04029                         value);
04030         case NC_SHORT:
04031                 return getNCvx_short_int(ncp, varp, start, nelems,
04032                         value);
04033         case NC_INT:
04034                 return getNCvx_int_int(ncp, varp, start, nelems,
04035                         value);
04036         case NC_FLOAT:
04037                 return getNCvx_float_int(ncp, varp, start, nelems,
04038                         value);
04039         case NC_DOUBLE: 
04040                 return getNCvx_double_int(ncp, varp, start, nelems,
04041                         value);
04042         }
04043         return NC_EBADTYPE;
04044 }
04045 
04046 static int
04047 getNCv_long(const NC *ncp, const NC_var *varp,
04048                  const size_t *start, size_t nelems, long *value)
04049 {
04050         switch(varp->type){
04051         case NC_CHAR:
04052                 return NC_ECHAR;
04053         case NC_BYTE:
04054                 return getNCvx_schar_long(ncp, varp, start, nelems,
04055                         value);
04056         case NC_SHORT:
04057                 return getNCvx_short_long(ncp, varp, start, nelems,
04058                         value);
04059         case NC_INT:
04060                 return getNCvx_int_long(ncp, varp, start, nelems,
04061                         value);
04062         case NC_FLOAT:
04063                 return getNCvx_float_long(ncp, varp, start, nelems,
04064                         value);
04065         case NC_DOUBLE: 
04066                 return getNCvx_double_long(ncp, varp, start, nelems,
04067                         value);
04068         }
04069         return NC_EBADTYPE;
04070 }
04071 
04072 static int
04073 getNCv_float(const NC *ncp, const NC_var *varp,
04074                  const size_t *start, size_t nelems, float *value)
04075 {
04076         switch(varp->type){
04077         case NC_CHAR:
04078                 return NC_ECHAR;
04079         case NC_BYTE:
04080                 return getNCvx_schar_float(ncp, varp, start, nelems,
04081                         value);
04082         case NC_SHORT:
04083                 return getNCvx_short_float(ncp, varp, start, nelems,
04084                         value);
04085         case NC_INT:
04086                 return getNCvx_int_float(ncp, varp, start, nelems,
04087                         value);
04088         case NC_FLOAT:
04089                 return getNCvx_float_float(ncp, varp, start, nelems,
04090                         value);
04091         case NC_DOUBLE: 
04092                 return getNCvx_double_float(ncp, varp, start, nelems,
04093                         value);
04094         }
04095         return NC_EBADTYPE;
04096 }
04097 
04098 static int
04099 getNCv_double(const NC *ncp, const NC_var *varp,
04100                  const size_t *start, size_t nelems, double *value)
04101 {
04102         switch(varp->type){
04103         case NC_CHAR:
04104                 return NC_ECHAR;
04105         case NC_BYTE:
04106                 return getNCvx_schar_double(ncp, varp, start, nelems,
04107                         value);
04108         case NC_SHORT:
04109                 return getNCvx_short_double(ncp, varp, start, nelems,
04110                         value);
04111         case NC_INT:
04112                 return getNCvx_int_double(ncp, varp, start, nelems,
04113                         value);
04114         case NC_FLOAT:
04115                 return getNCvx_float_double(ncp, varp, start, nelems,
04116                         value);
04117         case NC_DOUBLE: 
04118                 return getNCvx_double_double(ncp, varp, start, nelems,
04119                         value);
04120         }
04121         return NC_EBADTYPE;
04122 }
04123 
04124 
04125 
04126 static int
04127 getNCv_text(const NC *ncp, const NC_var *varp,
04128                  const size_t *start, size_t nelems, char *value)
04129 {
04130         if(varp->type != NC_CHAR)
04131                 return NC_ECHAR;
04132         return getNCvx_char_char(ncp, varp, start, nelems, value);
04133 }
04134 
04135 
04136 /*
04137  * Copy 'nbytes' contiguous external values
04138  * from ('inncp', invp', inncoord')
04139  * to   ('outncp', 'outvp', 'outcoord')
04140  * 'inncp' shouldn't be the same as 'outncp'.
04141  * Used only by ncvarcopy()
04142  */
04143 static int
04144 NCxvarcpy(NC *inncp, NC_var *invp, size_t *incoord,
04145         NC *outncp, NC_var *outvp, size_t *outcoord, size_t nbytes)
04146 {
04147         int status;
04148         off_t inoffset = NC_varoffset(inncp, invp, incoord);
04149         off_t outoffset = NC_varoffset(outncp, outvp, outcoord);
04150         void *inxp;
04151         void *outxp;
04152         const size_t chunk = MIN(inncp->chunk, outncp->chunk);
04153 
04154         do {
04155                 const size_t extent = MIN(nbytes, chunk);
04156 
04157                 status = inncp->nciop->get(inncp->nciop, inoffset, extent,
04158                                  0, &inxp);     
04159                 if(status != NC_NOERR)
04160                         return status;
04161 
04162                 status = outncp->nciop->get(outncp->nciop, outoffset, extent,
04163                                  RGN_WRITE, &outxp);    
04164                 if(status != NC_NOERR)
04165                 {
04166                         (void) inncp->nciop->rel(inncp->nciop, inoffset, 0);    
04167                         break;
04168                 }
04169 
04170                 (void) memcpy(outxp, inxp, extent);
04171 
04172                 status = outncp->nciop->rel(outncp->nciop, outoffset,
04173                          RGN_MODIFIED);
04174                 (void) inncp->nciop->rel(inncp->nciop, inoffset, 0);    
04175 
04176                 nbytes -= extent;
04177                 if(nbytes == 0)
04178                         break; /* normal loop exit */
04179                 inoffset += extent;
04180                 outoffset += extent;
04181                 
04182         } while (status == NC_NOERR);
04183 
04184         return status;
04185 }
04186 
04187 
04188 /*
04189  *  For ncvar{put,get},
04190  *  find the largest contiguous block from within 'edges'.
04191  *  returns the index to the left of this (which may be -1).
04192  *  Compute the number of contiguous elements and return
04193  *  that in *iocountp.
04194  *  The presence of "record" variables makes this routine
04195  *  overly subtle.
04196  */
04197 static int
04198 NCiocount(const NC *const ncp, const NC_var *const varp,
04199         const size_t *const edges,
04200         size_t *const iocountp)
04201 {
04202         const size_t *edp0 = edges;
04203         const size_t *edp = edges + varp->ndims;
04204         const size_t *shp = varp->shape + varp->ndims;
04205 
04206         if(IS_RECVAR(varp))
04207         {
04208                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
04209                 {
04210                         /* one dimensional && the only 'record' variable */
04211                         *iocountp = *edges;
04212                         return(0);
04213                 }
04214                 /* else */
04215                 edp0++;
04216         }
04217 
04218         assert(edges != NULL);
04219 
04220         /* find max contiguous */
04221         while(edp > edp0)
04222         {
04223                 shp--; edp--;
04224                 if(*edp < *shp )
04225                 {
04226                         const size_t *zedp = edp;
04227                         while(zedp >= edp0)
04228                         {
04229                                 if(*zedp == 0)
04230                                 {
04231                                         *iocountp = 0;
04232                                         goto done;
04233                                 }
04234                                 /* Tip of the hat to segmented architectures */
04235                                 if(zedp == edp0)
04236                                         break;
04237                                 zedp--;
04238                         }
04239                         break;
04240                 }
04241                 assert(*edp == *shp);
04242         }
04243 
04244         /*
04245          * edp, shp reference rightmost index s.t. *(edp +1) == *(shp +1)
04246          *
04247          * Or there is only one dimension.
04248          * If there is only one dimension and it is 'non record' dimension,
04249          *      edp is &edges[0] and we will return -1.
04250          * If there is only one dimension and and it is a "record dimension",
04251          *      edp is &edges[1] (out of bounds) and we will return 0;
04252          */
04253         assert(shp >= varp->shape + varp->ndims -1 
04254                 || *(edp +1) == *(shp +1));
04255 
04256         /* now accumulate max count for a single io operation */
04257         for(*iocountp = 1, edp0 = edp;
04258                         edp0 < edges + varp->ndims;
04259                         edp0++)
04260         {
04261                 *iocountp *= *edp0;
04262         }
04263 
04264 done:
04265         return((int)(edp - edges) - 1);
04266 }
04267 
04268 
04269 /*
04270  * Set the elements of the array 'upp' to
04271  * the sum of the corresponding elements of
04272  * 'stp' and 'edp'. 'end' should be &stp[nelems].
04273  */
04274 static void
04275 set_upper(size_t *upp, /* modified on return */
04276         const size_t *stp,
04277         const size_t *edp,
04278         const size_t *const end)
04279 {
04280         while(upp < end) {
04281                 *upp++ = *stp++ + *edp++;
04282         }
04283 }
04284 
04285 
04286 /*
04287  * The infamous and oft-discussed odometer code.
04288  *
04289  * 'start[]' is the starting coordinate.
04290  * 'upper[]' is the upper bound s.t. start[ii] < upper[ii].
04291  * 'coord[]' is the register, the current coordinate value.
04292  * For some ii,
04293  * upp == &upper[ii]
04294  * cdp == &coord[ii]
04295  * 
04296  * Running this routine increments *cdp.
04297  *
04298  * If after the increment, *cdp is equal to *upp
04299  * (and cdp is not the leftmost dimension),
04300  * *cdp is "zeroed" to the starting value and
04301  * we need to "carry", eg, increment one place to
04302  * the left.
04303  * 
04304  * TODO: Some architectures hate recursion?
04305  *      Reimplement non-recursively.
04306  */
04307 static void
04308 odo1(const size_t *const start, const size_t *const upper,
04309         size_t *const coord, /* modified on return */
04310         const size_t *upp,
04311         size_t *cdp)
04312 {
04313         assert(coord <= cdp && cdp <= coord + NC_MAX_DIMS);
04314         assert(upper <= upp && upp <= upper + NC_MAX_DIMS);
04315         assert(upp - upper == cdp - coord);
04316         
04317         assert(*cdp <= *upp);
04318 
04319         (*cdp)++;
04320         if(cdp != coord && *cdp >= *upp)
04321         {
04322                 *cdp = start[cdp - coord];
04323                 odo1(start, upper, coord, upp -1, cdp -1);
04324         }
04325 }
04326 #ifdef _CRAYC
04327 #pragma _CRI noinline odo1
04328 #endif
04329 
04330 
04331 
04332 
04333 /* Public */
04334 
04335 
04336 int
04337 nc_put_var1_text(int ncid, int varid, const size_t *coord,
04338         const char *value)
04339 {
04340         int status;
04341         NC *ncp;
04342         const NC_var *varp;
04343 
04344         status = NC_check_id(ncid, &ncp); 
04345         if(status != NC_NOERR)
04346                 return status;
04347 
04348         if(NC_readonly(ncp))
04349                 return NC_EPERM;
04350 
04351         if(NC_indef(ncp))
04352                 return NC_EINDEFINE;
04353 
04354         varp = NC_lookupvar(ncp, varid);
04355         if(varp == NULL)
04356                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04357 
04358         if(varp->type != NC_CHAR)
04359                 return NC_ECHAR;
04360 
04361         status = NCcoordck(ncp, varp, coord);
04362         if(status != NC_NOERR)
04363                 return status;
04364 
04365         if(IS_RECVAR(varp))
04366         {
04367                 status = NCvnrecs(ncp, *coord +1);
04368                 if(status != NC_NOERR)
04369                         return status;
04370         }
04371 
04372         return putNCv_text(ncp, varp, coord, 1, value);
04373 }
04374 
04375 
04376 int
04377 nc_put_var1_uchar(int ncid, int varid, const size_t *coord,
04378         const uchar *value)
04379 {
04380         int status;
04381         NC *ncp;
04382         const NC_var *varp;
04383 
04384         status = NC_check_id(ncid, &ncp); 
04385         if(status != NC_NOERR)
04386                 return status;
04387 
04388         if(NC_readonly(ncp))
04389                 return NC_EPERM;
04390 
04391         if(NC_indef(ncp))
04392                 return NC_EINDEFINE;
04393 
04394         varp = NC_lookupvar(ncp, varid);
04395         if(varp == NULL)
04396                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04397 
04398         if(varp->type == NC_CHAR)
04399                 return NC_ECHAR;
04400 
04401         status = NCcoordck(ncp, varp, coord);
04402         if(status != NC_NOERR)
04403                 return status;
04404 
04405         if(IS_RECVAR(varp))
04406         {
04407                 status = NCvnrecs(ncp, *coord +1);
04408                 if(status != NC_NOERR)
04409                         return status;
04410         }
04411 
04412         return putNCv_uchar(ncp, varp, coord, 1, value);
04413 }
04414 
04415 int
04416 nc_put_var1_schar(int ncid, int varid, const size_t *coord,
04417         const schar *value)
04418 {
04419         int status;
04420         NC *ncp;
04421         const NC_var *varp;
04422 
04423         status = NC_check_id(ncid, &ncp); 
04424         if(status != NC_NOERR)
04425                 return status;
04426 
04427         if(NC_readonly(ncp))
04428                 return NC_EPERM;
04429 
04430         if(NC_indef(ncp))
04431                 return NC_EINDEFINE;
04432 
04433         varp = NC_lookupvar(ncp, varid);
04434         if(varp == NULL)
04435                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04436 
04437         if(varp->type == NC_CHAR)
04438                 return NC_ECHAR;
04439 
04440         status = NCcoordck(ncp, varp, coord);
04441         if(status != NC_NOERR)
04442                 return status;
04443 
04444         if(IS_RECVAR(varp))
04445         {
04446                 status = NCvnrecs(ncp, *coord +1);
04447                 if(status != NC_NOERR)
04448                         return status;
04449         }
04450 
04451         return putNCv_schar(ncp, varp, coord, 1, value);
04452 }
04453 
04454 int
04455 nc_put_var1_short(int ncid, int varid, const size_t *coord,
04456         const short *value)
04457 {
04458         int status;
04459         NC *ncp;
04460         const NC_var *varp;
04461 
04462         status = NC_check_id(ncid, &ncp); 
04463         if(status != NC_NOERR)
04464                 return status;
04465 
04466         if(NC_readonly(ncp))
04467                 return NC_EPERM;
04468 
04469         if(NC_indef(ncp))
04470                 return NC_EINDEFINE;
04471 
04472         varp = NC_lookupvar(ncp, varid);
04473         if(varp == NULL)
04474                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04475 
04476         if(varp->type == NC_CHAR)
04477                 return NC_ECHAR;
04478 
04479         status = NCcoordck(ncp, varp, coord);
04480         if(status != NC_NOERR)
04481                 return status;
04482 
04483         if(IS_RECVAR(varp))
04484         {
04485                 status = NCvnrecs(ncp, *coord +1);
04486                 if(status != NC_NOERR)
04487                         return status;
04488         }
04489 
04490         return putNCv_short(ncp, varp, coord, 1, value);
04491 }
04492 
04493 int
04494 nc_put_var1_int(int ncid, int varid, const size_t *coord,
04495         const int *value)
04496 {
04497         int status;
04498         NC *ncp;
04499         const NC_var *varp;
04500 
04501         status = NC_check_id(ncid, &ncp); 
04502         if(status != NC_NOERR)
04503                 return status;
04504 
04505         if(NC_readonly(ncp))
04506                 return NC_EPERM;
04507 
04508         if(NC_indef(ncp))
04509                 return NC_EINDEFINE;
04510 
04511         varp = NC_lookupvar(ncp, varid);
04512         if(varp == NULL)
04513                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04514 
04515         if(varp->type == NC_CHAR)
04516                 return NC_ECHAR;
04517 
04518         status = NCcoordck(ncp, varp, coord);
04519         if(status != NC_NOERR)
04520                 return status;
04521 
04522         if(IS_RECVAR(varp))
04523         {
04524                 status = NCvnrecs(ncp, *coord +1);
04525                 if(status != NC_NOERR)
04526                         return status;
04527         }
04528 
04529         return putNCv_int(ncp, varp, coord, 1, value);
04530 }
04531 
04532 int
04533 nc_put_var1_long(int ncid, int varid, const size_t *coord,
04534         const long *value)
04535 {
04536         int status;
04537         NC *ncp;
04538         const NC_var *varp;
04539 
04540         status = NC_check_id(ncid, &ncp); 
04541         if(status != NC_NOERR)
04542                 return status;
04543 
04544         if(NC_readonly(ncp))
04545                 return NC_EPERM;
04546 
04547         if(NC_indef(ncp))
04548                 return NC_EINDEFINE;
04549 
04550         varp = NC_lookupvar(ncp, varid);
04551         if(varp == NULL)
04552                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04553 
04554         if(varp->type == NC_CHAR)
04555                 return NC_ECHAR;
04556 
04557         status = NCcoordck(ncp, varp, coord);
04558         if(status != NC_NOERR)
04559                 return status;
04560 
04561         if(IS_RECVAR(varp))
04562         {
04563                 status = NCvnrecs(ncp, *coord +1);
04564                 if(status != NC_NOERR)
04565                         return status;
04566         }
04567 
04568         return putNCv_long(ncp, varp, coord, 1, value);
04569 }
04570 
04571 int
04572 nc_put_var1_float(int ncid, int varid, const size_t *coord,
04573         const float *value)
04574 {
04575         int status;
04576         NC *ncp;
04577         const NC_var *varp;
04578 
04579         status = NC_check_id(ncid, &ncp); 
04580         if(status != NC_NOERR)
04581                 return status;
04582 
04583         if(NC_readonly(ncp))
04584                 return NC_EPERM;
04585 
04586         if(NC_indef(ncp))
04587                 return NC_EINDEFINE;
04588 
04589         varp = NC_lookupvar(ncp, varid);
04590         if(varp == NULL)
04591                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04592 
04593         if(varp->type == NC_CHAR)
04594                 return NC_ECHAR;
04595 
04596         status = NCcoordck(ncp, varp, coord);
04597         if(status != NC_NOERR)
04598                 return status;
04599 
04600         if(IS_RECVAR(varp))
04601         {
04602                 status = NCvnrecs(ncp, *coord +1);
04603                 if(status != NC_NOERR)
04604                         return status;
04605         }
04606 
04607         return putNCv_float(ncp, varp, coord, 1, value);
04608 }
04609 
04610 int
04611 nc_put_var1_double(int ncid, int varid, const size_t *coord,
04612         const double *value)
04613 {
04614         int status;
04615         NC *ncp;
04616         const NC_var *varp;
04617 
04618         status = NC_check_id(ncid, &ncp); 
04619         if(status != NC_NOERR)
04620                 return status;
04621 
04622         if(NC_readonly(ncp))
04623                 return NC_EPERM;
04624 
04625         if(NC_indef(ncp))
04626                 return NC_EINDEFINE;
04627 
04628         varp = NC_lookupvar(ncp, varid);
04629         if(varp == NULL)
04630                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04631 
04632         if(varp->type == NC_CHAR)
04633                 return NC_ECHAR;
04634 
04635         status = NCcoordck(ncp, varp, coord);
04636         if(status != NC_NOERR)
04637                 return status;
04638 
04639         if(IS_RECVAR(varp))
04640         {
04641                 status = NCvnrecs(ncp, *coord +1);
04642                 if(status != NC_NOERR)
04643                         return status;
04644         }
04645 
04646         return putNCv_double(ncp, varp, coord, 1, value);
04647 }
04648 
04649 
04650 
04651 /* deprecated, used to support the 2.x interface */
04652 int
04653 nc_put_var1(int ncid, int varid, const size_t *coord, const void *value)
04654 {
04655         int status;
04656         NC *ncp;
04657         const NC_var *varp;
04658 
04659         status = NC_check_id(ncid, &ncp); 
04660         if(status != NC_NOERR)
04661                 return status;
04662 
04663         varp = NC_lookupvar(ncp, varid);
04664         if(varp == NULL)
04665                 return NC_ENOTVAR;
04666 
04667         switch(varp->type){
04668         case NC_CHAR:
04669                 return nc_put_var1_text(ncid, varid, coord,
04670                         (const char *) value);
04671         case NC_BYTE:
04672                 return nc_put_var1_schar(ncid, varid, coord,
04673                         (const schar *) value);
04674         case NC_SHORT:
04675                 return nc_put_var1_short(ncid, varid, coord,
04676                         (const short *) value);
04677         case NC_INT:
04678                 return nc_put_var1_int(ncid, varid, coord,
04679                         (const int *) value);
04680         case NC_FLOAT:
04681                 return nc_put_var1_float(ncid, varid, coord,
04682                         (const float *) value);
04683         case NC_DOUBLE: 
04684                 return nc_put_var1_double(ncid, varid, coord,
04685                         (const double *) value);
04686         }
04687         return NC_EBADTYPE;
04688 }
04689 
04690 
04691 
04692 int
04693 nc_get_var1_text(int ncid, int varid, const size_t *coord, char *value)
04694 {
04695         int status;
04696         NC *ncp;
04697         const NC_var *varp;
04698 
04699         status = NC_check_id(ncid, &ncp); 
04700         if(status != NC_NOERR)
04701                 return status;
04702 
04703         if(NC_indef(ncp))
04704                 return NC_EINDEFINE;
04705 
04706         varp = NC_lookupvar(ncp, varid);
04707         if(varp == NULL)
04708                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04709 
04710         if(varp->type != NC_CHAR)
04711                 return NC_ECHAR;
04712 
04713         status = NCcoordck(ncp, varp, coord);
04714         if(status != NC_NOERR)
04715                 return status;
04716 
04717         return getNCv_text(ncp, varp, coord, 1, value);
04718 }
04719 
04720 
04721 int
04722 nc_get_var1_uchar(int ncid, int varid, const size_t *coord, uchar *value)
04723 {
04724         int status;
04725         NC *ncp;
04726         const NC_var *varp;
04727 
04728         status = NC_check_id(ncid, &ncp); 
04729         if(status != NC_NOERR)
04730                 return status;
04731 
04732         if(NC_indef(ncp))
04733                 return NC_EINDEFINE;
04734 
04735         varp = NC_lookupvar(ncp, varid);
04736         if(varp == NULL)
04737                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04738 
04739         if(varp->type == NC_CHAR)
04740                 return NC_ECHAR;
04741 
04742         status = NCcoordck(ncp, varp, coord);
04743         if(status != NC_NOERR)
04744                 return status;
04745 
04746         return getNCv_uchar(ncp, varp, coord, 1, value);
04747 }
04748 
04749 int
04750 nc_get_var1_schar(int ncid, int varid, const size_t *coord, schar *value)
04751 {
04752         int status;
04753         NC *ncp;
04754         const NC_var *varp;
04755 
04756         status = NC_check_id(ncid, &ncp); 
04757         if(status != NC_NOERR)
04758                 return status;
04759 
04760         if(NC_indef(ncp))
04761                 return NC_EINDEFINE;
04762 
04763         varp = NC_lookupvar(ncp, varid);
04764         if(varp == NULL)
04765                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04766 
04767         if(varp->type == NC_CHAR)
04768                 return NC_ECHAR;
04769 
04770         status = NCcoordck(ncp, varp, coord);
04771         if(status != NC_NOERR)
04772                 return status;
04773 
04774         return getNCv_schar(ncp, varp, coord, 1, value);
04775 }
04776 
04777 int
04778 nc_get_var1_short(int ncid, int varid, const size_t *coord, short *value)
04779 {
04780         int status;
04781         NC *ncp;
04782         const NC_var *varp;
04783 
04784         status = NC_check_id(ncid, &ncp); 
04785         if(status != NC_NOERR)
04786                 return status;
04787 
04788         if(NC_indef(ncp))
04789                 return NC_EINDEFINE;
04790 
04791         varp = NC_lookupvar(ncp, varid);
04792         if(varp == NULL)
04793                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04794 
04795         if(varp->type == NC_CHAR)
04796                 return NC_ECHAR;
04797 
04798         status = NCcoordck(ncp, varp, coord);
04799         if(status != NC_NOERR)
04800                 return status;
04801 
04802         return getNCv_short(ncp, varp, coord, 1, value);
04803 }
04804 
04805 int
04806 nc_get_var1_int(int ncid, int varid, const size_t *coord, int *value)
04807 {
04808         int status;
04809         NC *ncp;
04810         const NC_var *varp;
04811 
04812         status = NC_check_id(ncid, &ncp); 
04813         if(status != NC_NOERR)
04814                 return status;
04815 
04816         if(NC_indef(ncp))
04817                 return NC_EINDEFINE;
04818 
04819         varp = NC_lookupvar(ncp, varid);
04820         if(varp == NULL)
04821                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04822 
04823         if(varp->type == NC_CHAR)
04824                 return NC_ECHAR;
04825 
04826         status = NCcoordck(ncp, varp, coord);
04827         if(status != NC_NOERR)
04828                 return status;
04829 
04830         return getNCv_int(ncp, varp, coord, 1, value);
04831 }
04832 
04833 int
04834 nc_get_var1_long(int ncid, int varid, const size_t *coord, long *value)
04835 {
04836         int status;
04837         NC *ncp;
04838         const NC_var *varp;
04839 
04840         status = NC_check_id(ncid, &ncp); 
04841         if(status != NC_NOERR)
04842                 return status;
04843 
04844         if(NC_indef(ncp))
04845                 return NC_EINDEFINE;
04846 
04847         varp = NC_lookupvar(ncp, varid);
04848         if(varp == NULL)
04849                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04850 
04851         if(varp->type == NC_CHAR)
04852                 return NC_ECHAR;
04853 
04854         status = NCcoordck(ncp, varp, coord);
04855         if(status != NC_NOERR)
04856                 return status;
04857 
04858         return getNCv_long(ncp, varp, coord, 1, value);
04859 }
04860 
04861 int
04862 nc_get_var1_float(int ncid, int varid, const size_t *coord, float *value)
04863 {
04864         int status;
04865         NC *ncp;
04866         const NC_var *varp;
04867 
04868         status = NC_check_id(ncid, &ncp); 
04869         if(status != NC_NOERR)
04870                 return status;
04871 
04872         if(NC_indef(ncp))
04873                 return NC_EINDEFINE;
04874 
04875         varp = NC_lookupvar(ncp, varid);
04876         if(varp == NULL)
04877                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04878 
04879         if(varp->type == NC_CHAR)
04880                 return NC_ECHAR;
04881 
04882         status = NCcoordck(ncp, varp, coord);
04883         if(status != NC_NOERR)
04884                 return status;
04885 
04886         return getNCv_float(ncp, varp, coord, 1, value);
04887 }
04888 
04889 int
04890 nc_get_var1_double(int ncid, int varid, const size_t *coord, double *value)
04891 {
04892         int status;
04893         NC *ncp;
04894         const NC_var *varp;
04895 
04896         status = NC_check_id(ncid, &ncp); 
04897         if(status != NC_NOERR)
04898                 return status;
04899 
04900         if(NC_indef(ncp))
04901                 return NC_EINDEFINE;
04902 
04903         varp = NC_lookupvar(ncp, varid);
04904         if(varp == NULL)
04905                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04906 
04907         if(varp->type == NC_CHAR)
04908                 return NC_ECHAR;
04909 
04910         status = NCcoordck(ncp, varp, coord);
04911         if(status != NC_NOERR)
04912                 return status;
04913 
04914         return getNCv_double(ncp, varp, coord, 1, value);
04915 }
04916 
04917 
04918 /* deprecated, used to support the 2.x interface */
04919 int
04920 nc_get_var1(int ncid, int varid, const size_t *coord, void *value)
04921 {
04922         int status;
04923         NC *ncp;
04924         const NC_var *varp;
04925 
04926         status = NC_check_id(ncid, &ncp); 
04927         if(status != NC_NOERR)
04928                 return status;
04929 
04930         varp = NC_lookupvar(ncp, varid);
04931         if(varp == NULL)
04932                 return NC_ENOTVAR;
04933 
04934         switch(varp->type){
04935         case NC_CHAR:
04936                 return nc_get_var1_text(ncid, varid, coord,
04937                         (char *) value);
04938         case NC_BYTE:
04939                 return nc_get_var1_schar(ncid, varid, coord,
04940                         (schar *) value);
04941         case NC_SHORT:
04942                 return nc_get_var1_short(ncid, varid, coord,
04943                         (short *) value);
04944         case NC_INT:
04945                 return nc_get_var1_int(ncid, varid, coord,
04946                         (int *) value);
04947         case NC_FLOAT:
04948                 return nc_get_var1_float(ncid, varid, coord,
04949                         (float *) value);
04950         case NC_DOUBLE: 
04951                 return nc_get_var1_double(ncid, varid, coord,
04952                         (double *) value);
04953         }
04954         return NC_EBADTYPE;
04955 }
04956 
04957 
04958 
04959 int
04960 nc_put_vara_text(int ncid, int varid,
04961          const size_t *start, const size_t *edges, const char *value)
04962 {
04963         int status = NC_NOERR;
04964         NC *ncp;
04965         const NC_var *varp;
04966         int ii;
04967         size_t iocount;
04968 
04969         status = NC_check_id(ncid, &ncp); 
04970         if(status != NC_NOERR)
04971                 return status;
04972 
04973         if(NC_readonly(ncp))
04974                 return NC_EPERM;
04975 
04976         if(NC_indef(ncp))
04977                 return NC_EINDEFINE;
04978 
04979         varp = NC_lookupvar(ncp, varid);
04980         if(varp == NULL)
04981                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
04982 
04983         if(varp->type != NC_CHAR)
04984                 return NC_ECHAR;
04985 
04986         status = NCcoordck(ncp, varp, start);
04987         if(status != NC_NOERR)
04988                 return status;
04989         status = NCedgeck(ncp, varp, start, edges);
04990         if(status != NC_NOERR)
04991                 return status;
04992 
04993         if(varp->ndims == 0) /* scalar variable */
04994         {
04995                 return( putNCv_text(ncp, varp, start, 1, value) );
04996         }
04997 
04998         if(IS_RECVAR(varp))
04999         {
05000                 status = NCvnrecs(ncp, *start + *edges);
05001                 if(status != NC_NOERR)
05002                         return status;
05003 
05004                 if(varp->ndims == 1
05005                         && ncp->recsize <= varp->len)
05006                 {
05007                         /* one dimensional && the only record variable  */
05008                         return( putNCv_text(ncp, varp, start, *edges, value) );
05009                 }
05010         }
05011 
05012         /*
05013          * find max contiguous
05014          *   and accumulate max count for a single io operation
05015          */
05016         ii = NCiocount(ncp, varp, edges, &iocount);
05017 
05018         if(ii == -1)
05019         {
05020                 return( putNCv_text(ncp, varp, start, iocount, value) );
05021         }
05022 
05023         assert(ii >= 0);
05024 
05025 
05026         { /* inline */
05027         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05028         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05029         const size_t index = ii;
05030 
05031         /* copy in starting indices */
05032         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05033 
05034         /* set up in maximum indices */
05035         set_upper(upper, start, edges, &upper[varp->ndims]);
05036 
05037         /* ripple counter */
05038         while(*coord < *upper)
05039         {
05040                 const int lstatus = putNCv_text(ncp, varp, coord, iocount,
05041                                  value);
05042                 if(lstatus != NC_NOERR)
05043                 {
05044                         if(lstatus != NC_ERANGE)
05045                         {
05046                                 status = lstatus;
05047                                 /* fatal for the loop */
05048                                 break;
05049                         }
05050                         /* else NC_ERANGE, not fatal for the loop */
05051                         if(status == NC_NOERR)
05052                                 status = lstatus;
05053                 }
05054                 value += iocount;
05055                 odo1(start, upper, coord, &upper[index], &coord[index]);
05056         }
05057 
05058         FREE_ONSTACK(upper);
05059         FREE_ONSTACK(coord);
05060         } /* end inline */
05061 
05062         return status;
05063 }
05064 
05065 
05066 int
05067 nc_put_vara_uchar(int ncid, int varid,
05068          const size_t *start, const size_t *edges, const uchar *value)
05069 {
05070         int status = NC_NOERR;
05071         NC *ncp;
05072         const NC_var *varp;
05073         int ii;
05074         size_t iocount;
05075 
05076         status = NC_check_id(ncid, &ncp); 
05077         if(status != NC_NOERR)
05078                 return status;
05079 
05080         if(NC_readonly(ncp))
05081                 return NC_EPERM;
05082 
05083         if(NC_indef(ncp))
05084                 return NC_EINDEFINE;
05085 
05086         varp = NC_lookupvar(ncp, varid);
05087         if(varp == NULL)
05088                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05089 
05090         if(varp->type == NC_CHAR)
05091                 return NC_ECHAR;
05092 
05093         status = NCcoordck(ncp, varp, start);
05094         if(status != NC_NOERR)
05095                 return status;
05096         status = NCedgeck(ncp, varp, start, edges);
05097         if(status != NC_NOERR)
05098                 return status;
05099 
05100         if(varp->ndims == 0) /* scalar variable */
05101         {
05102                 return( putNCv_uchar(ncp, varp, start, 1, value) );
05103         }
05104 
05105         if(IS_RECVAR(varp))
05106         {
05107                 status = NCvnrecs(ncp, *start + *edges);
05108                 if(status != NC_NOERR)
05109                         return status;
05110 
05111                 if(varp->ndims == 1
05112                         && ncp->recsize <= varp->len)
05113                 {
05114                         /* one dimensional && the only record variable  */
05115                         return( putNCv_uchar(ncp, varp, start, *edges, value) );
05116                 }
05117         }
05118 
05119         /*
05120          * find max contiguous
05121          *   and accumulate max count for a single io operation
05122          */
05123         ii = NCiocount(ncp, varp, edges, &iocount);
05124 
05125         if(ii == -1)
05126         {
05127                 return( putNCv_uchar(ncp, varp, start, iocount, value) );
05128         }
05129 
05130         assert(ii >= 0);
05131 
05132 
05133         { /* inline */
05134         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05135         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05136         const size_t index = ii;
05137 
05138         /* copy in starting indices */
05139         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05140 
05141         /* set up in maximum indices */
05142         set_upper(upper, start, edges, &upper[varp->ndims]);
05143 
05144         /* ripple counter */
05145         while(*coord < *upper)
05146         {
05147                 const int lstatus = putNCv_uchar(ncp, varp, coord, iocount,
05148                                  value);
05149                 if(lstatus != NC_NOERR)
05150                 {
05151                         if(lstatus != NC_ERANGE)
05152                         {
05153                                 status = lstatus;
05154                                 /* fatal for the loop */
05155                                 break;
05156                         }
05157                         /* else NC_ERANGE, not fatal for the loop */
05158                         if(status == NC_NOERR)
05159                                 status = lstatus;
05160                 }
05161                 value += iocount;
05162                 odo1(start, upper, coord, &upper[index], &coord[index]);
05163         }
05164 
05165         FREE_ONSTACK(upper);
05166         FREE_ONSTACK(coord);
05167         } /* end inline */
05168 
05169         return status;
05170 }
05171 
05172 int
05173 nc_put_vara_schar(int ncid, int varid,
05174          const size_t *start, const size_t *edges, const schar *value)
05175 {
05176         int status = NC_NOERR;
05177         NC *ncp;
05178         const NC_var *varp;
05179         int ii;
05180         size_t iocount;
05181 
05182         status = NC_check_id(ncid, &ncp); 
05183         if(status != NC_NOERR)
05184                 return status;
05185 
05186         if(NC_readonly(ncp))
05187                 return NC_EPERM;
05188 
05189         if(NC_indef(ncp))
05190                 return NC_EINDEFINE;
05191 
05192         varp = NC_lookupvar(ncp, varid);
05193         if(varp == NULL)
05194                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05195 
05196         if(varp->type == NC_CHAR)
05197                 return NC_ECHAR;
05198 
05199         status = NCcoordck(ncp, varp, start);
05200         if(status != NC_NOERR)
05201                 return status;
05202         status = NCedgeck(ncp, varp, start, edges);
05203         if(status != NC_NOERR)
05204                 return status;
05205 
05206         if(varp->ndims == 0) /* scalar variable */
05207         {
05208                 return( putNCv_schar(ncp, varp, start, 1, value) );
05209         }
05210 
05211         if(IS_RECVAR(varp))
05212         {
05213                 status = NCvnrecs(ncp, *start + *edges);
05214                 if(status != NC_NOERR)
05215                         return status;
05216 
05217                 if(varp->ndims == 1
05218                         && ncp->recsize <= varp->len)
05219                 {
05220                         /* one dimensional && the only record variable  */
05221                         return( putNCv_schar(ncp, varp, start, *edges, value) );
05222                 }
05223         }
05224 
05225         /*
05226          * find max contiguous
05227          *   and accumulate max count for a single io operation
05228          */
05229         ii = NCiocount(ncp, varp, edges, &iocount);
05230 
05231         if(ii == -1)
05232         {
05233                 return( putNCv_schar(ncp, varp, start, iocount, value) );
05234         }
05235 
05236         assert(ii >= 0);
05237 
05238 
05239         { /* inline */
05240         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05241         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05242         const size_t index = ii;
05243 
05244         /* copy in starting indices */
05245         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05246 
05247         /* set up in maximum indices */
05248         set_upper(upper, start, edges, &upper[varp->ndims]);
05249 
05250         /* ripple counter */
05251         while(*coord < *upper)
05252         {
05253                 const int lstatus = putNCv_schar(ncp, varp, coord, iocount,
05254                                  value);
05255                 if(lstatus != NC_NOERR)
05256                 {
05257                         if(lstatus != NC_ERANGE)
05258                         {
05259                                 status = lstatus;
05260                                 /* fatal for the loop */
05261                                 break;
05262                         }
05263                         /* else NC_ERANGE, not fatal for the loop */
05264                         if(status == NC_NOERR)
05265                                 status = lstatus;
05266                 }
05267                 value += iocount;
05268                 odo1(start, upper, coord, &upper[index], &coord[index]);
05269         }
05270 
05271         FREE_ONSTACK(upper);
05272         FREE_ONSTACK(coord);
05273         } /* end inline */
05274 
05275         return status;
05276 }
05277 
05278 int
05279 nc_put_vara_short(int ncid, int varid,
05280          const size_t *start, const size_t *edges, const short *value)
05281 {
05282         int status = NC_NOERR;
05283         NC *ncp;
05284         const NC_var *varp;
05285         int ii;
05286         size_t iocount;
05287 
05288         status = NC_check_id(ncid, &ncp); 
05289         if(status != NC_NOERR)
05290                 return status;
05291 
05292         if(NC_readonly(ncp))
05293                 return NC_EPERM;
05294 
05295         if(NC_indef(ncp))
05296                 return NC_EINDEFINE;
05297 
05298         varp = NC_lookupvar(ncp, varid);
05299         if(varp == NULL)
05300                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05301 
05302         if(varp->type == NC_CHAR)
05303                 return NC_ECHAR;
05304 
05305         status = NCcoordck(ncp, varp, start);
05306         if(status != NC_NOERR)
05307                 return status;
05308         status = NCedgeck(ncp, varp, start, edges);
05309         if(status != NC_NOERR)
05310                 return status;
05311 
05312         if(varp->ndims == 0) /* scalar variable */
05313         {
05314                 return( putNCv_short(ncp, varp, start, 1, value) );
05315         }
05316 
05317         if(IS_RECVAR(varp))
05318         {
05319                 status = NCvnrecs(ncp, *start + *edges);
05320                 if(status != NC_NOERR)
05321                         return status;
05322 
05323                 if(varp->ndims == 1
05324                         && ncp->recsize <= varp->len)
05325                 {
05326                         /* one dimensional && the only record variable  */
05327                         return( putNCv_short(ncp, varp, start, *edges, value) );
05328                 }
05329         }
05330 
05331         /*
05332          * find max contiguous
05333          *   and accumulate max count for a single io operation
05334          */
05335         ii = NCiocount(ncp, varp, edges, &iocount);
05336 
05337         if(ii == -1)
05338         {
05339                 return( putNCv_short(ncp, varp, start, iocount, value) );
05340         }
05341 
05342         assert(ii >= 0);
05343 
05344 
05345         { /* inline */
05346         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05347         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05348         const size_t index = ii;
05349 
05350         /* copy in starting indices */
05351         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05352 
05353         /* set up in maximum indices */
05354         set_upper(upper, start, edges, &upper[varp->ndims]);
05355 
05356         /* ripple counter */
05357         while(*coord < *upper)
05358         {
05359                 const int lstatus = putNCv_short(ncp, varp, coord, iocount,
05360                                  value);
05361                 if(lstatus != NC_NOERR)
05362                 {
05363                         if(lstatus != NC_ERANGE)
05364                         {
05365                                 status = lstatus;
05366                                 /* fatal for the loop */
05367                                 break;
05368                         }
05369                         /* else NC_ERANGE, not fatal for the loop */
05370                         if(status == NC_NOERR)
05371                                 status = lstatus;
05372                 }
05373                 value += iocount;
05374                 odo1(start, upper, coord, &upper[index], &coord[index]);
05375         }
05376 
05377         FREE_ONSTACK(upper);
05378         FREE_ONSTACK(coord);
05379         } /* end inline */
05380 
05381         return status;
05382 }
05383 
05384 int
05385 nc_put_vara_int(int ncid, int varid,
05386          const size_t *start, const size_t *edges, const int *value)
05387 {
05388         int status = NC_NOERR;
05389         NC *ncp;
05390         const NC_var *varp;
05391         int ii;
05392         size_t iocount;
05393 
05394         status = NC_check_id(ncid, &ncp); 
05395         if(status != NC_NOERR)
05396                 return status;
05397 
05398         if(NC_readonly(ncp))
05399                 return NC_EPERM;
05400 
05401         if(NC_indef(ncp))
05402                 return NC_EINDEFINE;
05403 
05404         varp = NC_lookupvar(ncp, varid);
05405         if(varp == NULL)
05406                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05407 
05408         if(varp->type == NC_CHAR)
05409                 return NC_ECHAR;
05410 
05411         status = NCcoordck(ncp, varp, start);
05412         if(status != NC_NOERR)
05413                 return status;
05414         status = NCedgeck(ncp, varp, start, edges);
05415         if(status != NC_NOERR)
05416                 return status;
05417 
05418         if(varp->ndims == 0) /* scalar variable */
05419         {
05420                 return( putNCv_int(ncp, varp, start, 1, value) );
05421         }
05422 
05423         if(IS_RECVAR(varp))
05424         {
05425                 status = NCvnrecs(ncp, *start + *edges);
05426                 if(status != NC_NOERR)
05427                         return status;
05428 
05429                 if(varp->ndims == 1
05430                         && ncp->recsize <= varp->len)
05431                 {
05432                         /* one dimensional && the only record variable  */
05433                         return( putNCv_int(ncp, varp, start, *edges, value) );
05434                 }
05435         }
05436 
05437         /*
05438          * find max contiguous
05439          *   and accumulate max count for a single io operation
05440          */
05441         ii = NCiocount(ncp, varp, edges, &iocount);
05442 
05443         if(ii == -1)
05444         {
05445                 return( putNCv_int(ncp, varp, start, iocount, value) );
05446         }
05447 
05448         assert(ii >= 0);
05449 
05450 
05451         { /* inline */
05452         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05453         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05454         const size_t index = ii;
05455 
05456         /* copy in starting indices */
05457         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05458 
05459         /* set up in maximum indices */
05460         set_upper(upper, start, edges, &upper[varp->ndims]);
05461 
05462         /* ripple counter */
05463         while(*coord < *upper)
05464         {
05465                 const int lstatus = putNCv_int(ncp, varp, coord, iocount,
05466                                  value);
05467                 if(lstatus != NC_NOERR)
05468                 {
05469                         if(lstatus != NC_ERANGE)
05470                         {
05471                                 status = lstatus;
05472                                 /* fatal for the loop */
05473                                 break;
05474                         }
05475                         /* else NC_ERANGE, not fatal for the loop */
05476                         if(status == NC_NOERR)
05477                                 status = lstatus;
05478                 }
05479                 value += iocount;
05480                 odo1(start, upper, coord, &upper[index], &coord[index]);
05481         }
05482 
05483         FREE_ONSTACK(upper);
05484         FREE_ONSTACK(coord);
05485         } /* end inline */
05486 
05487         return status;
05488 }
05489 
05490 int
05491 nc_put_vara_long(int ncid, int varid,
05492          const size_t *start, const size_t *edges, const long *value)
05493 {
05494         int status = NC_NOERR;
05495         NC *ncp;
05496         const NC_var *varp;
05497         int ii;
05498         size_t iocount;
05499 
05500         status = NC_check_id(ncid, &ncp); 
05501         if(status != NC_NOERR)
05502                 return status;
05503 
05504         if(NC_readonly(ncp))
05505                 return NC_EPERM;
05506 
05507         if(NC_indef(ncp))
05508                 return NC_EINDEFINE;
05509 
05510         varp = NC_lookupvar(ncp, varid);
05511         if(varp == NULL)
05512                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05513 
05514         if(varp->type == NC_CHAR)
05515                 return NC_ECHAR;
05516 
05517         status = NCcoordck(ncp, varp, start);
05518         if(status != NC_NOERR)
05519                 return status;
05520         status = NCedgeck(ncp, varp, start, edges);
05521         if(status != NC_NOERR)
05522                 return status;
05523 
05524         if(varp->ndims == 0) /* scalar variable */
05525         {
05526                 return( putNCv_long(ncp, varp, start, 1, value) );
05527         }
05528 
05529         if(IS_RECVAR(varp))
05530         {
05531                 status = NCvnrecs(ncp, *start + *edges);
05532                 if(status != NC_NOERR)
05533                         return status;
05534 
05535                 if(varp->ndims == 1
05536                         && ncp->recsize <= varp->len)
05537                 {
05538                         /* one dimensional && the only record variable  */
05539                         return( putNCv_long(ncp, varp, start, *edges, value) );
05540                 }
05541         }
05542 
05543         /*
05544          * find max contiguous
05545          *   and accumulate max count for a single io operation
05546          */
05547         ii = NCiocount(ncp, varp, edges, &iocount);
05548 
05549         if(ii == -1)
05550         {
05551                 return( putNCv_long(ncp, varp, start, iocount, value) );
05552         }
05553 
05554         assert(ii >= 0);
05555 
05556 
05557         { /* inline */
05558         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05559         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05560         const size_t index = ii;
05561 
05562         /* copy in starting indices */
05563         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05564 
05565         /* set up in maximum indices */
05566         set_upper(upper, start, edges, &upper[varp->ndims]);
05567 
05568         /* ripple counter */
05569         while(*coord < *upper)
05570         {
05571                 const int lstatus = putNCv_long(ncp, varp, coord, iocount,
05572                                  value);
05573                 if(lstatus != NC_NOERR)
05574                 {
05575                         if(lstatus != NC_ERANGE)
05576                         {
05577                                 status = lstatus;
05578                                 /* fatal for the loop */
05579                                 break;
05580                         }
05581                         /* else NC_ERANGE, not fatal for the loop */
05582                         if(status == NC_NOERR)
05583                                 status = lstatus;
05584                 }
05585                 value += iocount;
05586                 odo1(start, upper, coord, &upper[index], &coord[index]);
05587         }
05588 
05589         FREE_ONSTACK(upper);
05590         FREE_ONSTACK(coord);
05591         } /* end inline */
05592 
05593         return status;
05594 }
05595 
05596 int
05597 nc_put_vara_float(int ncid, int varid,
05598          const size_t *start, const size_t *edges, const float *value)
05599 {
05600         int status = NC_NOERR;
05601         NC *ncp;
05602         const NC_var *varp;
05603         int ii;
05604         size_t iocount;
05605 
05606         status = NC_check_id(ncid, &ncp); 
05607         if(status != NC_NOERR)
05608                 return status;
05609 
05610         if(NC_readonly(ncp))
05611                 return NC_EPERM;
05612 
05613         if(NC_indef(ncp))
05614                 return NC_EINDEFINE;
05615 
05616         varp = NC_lookupvar(ncp, varid);
05617         if(varp == NULL)
05618                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05619 
05620         if(varp->type == NC_CHAR)
05621                 return NC_ECHAR;
05622 
05623         status = NCcoordck(ncp, varp, start);
05624         if(status != NC_NOERR)
05625                 return status;
05626         status = NCedgeck(ncp, varp, start, edges);
05627         if(status != NC_NOERR)
05628                 return status;
05629 
05630         if(varp->ndims == 0) /* scalar variable */
05631         {
05632                 return( putNCv_float(ncp, varp, start, 1, value) );
05633         }
05634 
05635         if(IS_RECVAR(varp))
05636         {
05637                 status = NCvnrecs(ncp, *start + *edges);
05638                 if(status != NC_NOERR)
05639                         return status;
05640 
05641                 if(varp->ndims == 1
05642                         && ncp->recsize <= varp->len)
05643                 {
05644                         /* one dimensional && the only record variable  */
05645                         return( putNCv_float(ncp, varp, start, *edges, value) );
05646                 }
05647         }
05648 
05649         /*
05650          * find max contiguous
05651          *   and accumulate max count for a single io operation
05652          */
05653         ii = NCiocount(ncp, varp, edges, &iocount);
05654 
05655         if(ii == -1)
05656         {
05657                 return( putNCv_float(ncp, varp, start, iocount, value) );
05658         }
05659 
05660         assert(ii >= 0);
05661 
05662 
05663         { /* inline */
05664         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05665         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05666         const size_t index = ii;
05667 
05668         /* copy in starting indices */
05669         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05670 
05671         /* set up in maximum indices */
05672         set_upper(upper, start, edges, &upper[varp->ndims]);
05673 
05674         /* ripple counter */
05675         while(*coord < *upper)
05676         {
05677                 const int lstatus = putNCv_float(ncp, varp, coord, iocount,
05678                                  value);
05679                 if(lstatus != NC_NOERR)
05680                 {
05681                         if(lstatus != NC_ERANGE)
05682                         {
05683                                 status = lstatus;
05684                                 /* fatal for the loop */
05685                                 break;
05686                         }
05687                         /* else NC_ERANGE, not fatal for the loop */
05688                         if(status == NC_NOERR)
05689                                 status = lstatus;
05690                 }
05691                 value += iocount;
05692                 odo1(start, upper, coord, &upper[index], &coord[index]);
05693         }
05694 
05695         FREE_ONSTACK(upper);
05696         FREE_ONSTACK(coord);
05697         } /* end inline */
05698 
05699         return status;
05700 }
05701 
05702 int
05703 nc_put_vara_double(int ncid, int varid,
05704          const size_t *start, const size_t *edges, const double *value)
05705 {
05706         int status = NC_NOERR;
05707         NC *ncp;
05708         const NC_var *varp;
05709         int ii;
05710         size_t iocount;
05711 
05712         status = NC_check_id(ncid, &ncp); 
05713         if(status != NC_NOERR)
05714                 return status;
05715 
05716         if(NC_readonly(ncp))
05717                 return NC_EPERM;
05718 
05719         if(NC_indef(ncp))
05720                 return NC_EINDEFINE;
05721 
05722         varp = NC_lookupvar(ncp, varid);
05723         if(varp == NULL)
05724                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05725 
05726         if(varp->type == NC_CHAR)
05727                 return NC_ECHAR;
05728 
05729         status = NCcoordck(ncp, varp, start);
05730         if(status != NC_NOERR)
05731                 return status;
05732         status = NCedgeck(ncp, varp, start, edges);
05733         if(status != NC_NOERR)
05734                 return status;
05735 
05736         if(varp->ndims == 0) /* scalar variable */
05737         {
05738                 return( putNCv_double(ncp, varp, start, 1, value) );
05739         }
05740 
05741         if(IS_RECVAR(varp))
05742         {
05743                 status = NCvnrecs(ncp, *start + *edges);
05744                 if(status != NC_NOERR)
05745                         return status;
05746 
05747                 if(varp->ndims == 1
05748                         && ncp->recsize <= varp->len)
05749                 {
05750                         /* one dimensional && the only record variable  */
05751                         return( putNCv_double(ncp, varp, start, *edges, value) );
05752                 }
05753         }
05754 
05755         /*
05756          * find max contiguous
05757          *   and accumulate max count for a single io operation
05758          */
05759         ii = NCiocount(ncp, varp, edges, &iocount);
05760 
05761         if(ii == -1)
05762         {
05763                 return( putNCv_double(ncp, varp, start, iocount, value) );
05764         }
05765 
05766         assert(ii >= 0);
05767 
05768 
05769         { /* inline */
05770         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05771         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05772         const size_t index = ii;
05773 
05774         /* copy in starting indices */
05775         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05776 
05777         /* set up in maximum indices */
05778         set_upper(upper, start, edges, &upper[varp->ndims]);
05779 
05780         /* ripple counter */
05781         while(*coord < *upper)
05782         {
05783                 const int lstatus = putNCv_double(ncp, varp, coord, iocount,
05784                                  value);
05785                 if(lstatus != NC_NOERR)
05786                 {
05787                         if(lstatus != NC_ERANGE)
05788                         {
05789                                 status = lstatus;
05790                                 /* fatal for the loop */
05791                                 break;
05792                         }
05793                         /* else NC_ERANGE, not fatal for the loop */
05794                         if(status == NC_NOERR)
05795                                 status = lstatus;
05796                 }
05797                 value += iocount;
05798                 odo1(start, upper, coord, &upper[index], &coord[index]);
05799         }
05800 
05801         FREE_ONSTACK(upper);
05802         FREE_ONSTACK(coord);
05803         } /* end inline */
05804 
05805         return status;
05806 }
05807 
05808 
05809 
05810 /* deprecated, used to support the 2.x interface */
05811 int
05812 nc_put_vara(int ncid, int varid,
05813          const size_t *start, const size_t *edges, const void *value)
05814 {
05815         int status;
05816         NC *ncp;
05817         const NC_var *varp;
05818 
05819         status = NC_check_id(ncid, &ncp); 
05820         if(status != NC_NOERR)
05821                 return status;
05822 
05823         if(NC_readonly(ncp))
05824                 return NC_EPERM;
05825 
05826         if(NC_indef(ncp))
05827                 return NC_EINDEFINE;
05828 
05829         varp = NC_lookupvar(ncp, varid);
05830         if(varp == NULL)
05831                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05832 
05833         switch(varp->type){
05834         case NC_CHAR:
05835                 return nc_put_vara_text(ncid, varid, start, edges,
05836                         (const char *) value);
05837         case NC_BYTE:
05838                 return nc_put_vara_schar(ncid, varid, start, edges,
05839                         (const schar *) value);
05840         case NC_SHORT:
05841                 return nc_put_vara_short(ncid, varid, start, edges,
05842                         (const short *) value);
05843         case NC_INT:
05844                 return nc_put_vara_int(ncid, varid, start, edges,
05845                         (const int *) value);
05846         case NC_FLOAT:
05847                 return nc_put_vara_float(ncid, varid, start, edges,
05848                         (const float *) value);
05849         case NC_DOUBLE: 
05850                 return nc_put_vara_double(ncid, varid, start, edges,
05851                         (const double *) value);
05852         }
05853         return NC_EBADTYPE;
05854 }
05855 
05856 
05857 
05858 int
05859 nc_get_vara_text(int ncid, int varid,
05860          const size_t *start, const size_t *edges, char *value)
05861 {
05862         int status = NC_NOERR;
05863         NC *ncp;
05864         const NC_var *varp;
05865         int ii;
05866         size_t iocount;
05867 
05868         status = NC_check_id(ncid, &ncp); 
05869         if(status != NC_NOERR)
05870                 return status;
05871 
05872         if(NC_indef(ncp))
05873                 return NC_EINDEFINE;
05874 
05875         varp = NC_lookupvar(ncp, varid);
05876         if(varp == NULL)
05877                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05878 
05879         if(varp->type != NC_CHAR)
05880                 return NC_ECHAR;
05881 
05882         status = NCcoordck(ncp, varp, start);
05883         if(status != NC_NOERR)
05884                 return status;
05885         status = NCedgeck(ncp, varp, start, edges);
05886         if(status != NC_NOERR)
05887                 return status;
05888 
05889         if(varp->ndims == 0) /* scalar variable */
05890         {
05891                 return( getNCv_text(ncp, varp, start, 1, value) );
05892         }
05893 
05894         if(IS_RECVAR(varp))
05895         {
05896                 if(*start + *edges > NC_get_numrecs(ncp))
05897                         return NC_EEDGE;
05898                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
05899                 {
05900                         /* one dimensional && the only record variable  */
05901                         return( getNCv_text(ncp, varp, start, *edges, value) );
05902                 }
05903         }
05904 
05905         /*
05906          * find max contiguous
05907          *   and accumulate max count for a single io operation
05908          */
05909         ii = NCiocount(ncp, varp, edges, &iocount);
05910 
05911         if(ii == -1)
05912         {
05913                 return( getNCv_text(ncp, varp, start, iocount, value) );
05914         }
05915 
05916         assert(ii >= 0);
05917 
05918 
05919         { /* inline */
05920         ALLOC_ONSTACK(coord, size_t, varp->ndims);
05921         ALLOC_ONSTACK(upper, size_t, varp->ndims);
05922         const size_t index = ii;
05923 
05924         /* copy in starting indices */
05925         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
05926 
05927         /* set up in maximum indices */
05928         set_upper(upper, start, edges, &upper[varp->ndims]);
05929 
05930         /* ripple counter */
05931         while(*coord < *upper)
05932         {
05933                 const int lstatus = getNCv_text(ncp, varp, coord, iocount,
05934                                 value);
05935                 if(lstatus != NC_NOERR)
05936                 {
05937                         if(lstatus != NC_ERANGE)
05938                         {
05939                                 status = lstatus;
05940                                 /* fatal for the loop */
05941                                 break;
05942                         }
05943                         /* else NC_ERANGE, not fatal for the loop */
05944                         if(status == NC_NOERR)
05945                                 status = lstatus;
05946                 }
05947                 value += iocount;
05948                 odo1(start, upper, coord, &upper[index], &coord[index]);
05949         }
05950 
05951         FREE_ONSTACK(upper);
05952         FREE_ONSTACK(coord);
05953         } /* end inline */
05954 
05955         return status;
05956 }
05957 
05958 
05959 int
05960 nc_get_vara_uchar(int ncid, int varid,
05961          const size_t *start, const size_t *edges, uchar *value)
05962 {
05963         int status = NC_NOERR;
05964         NC *ncp;
05965         const NC_var *varp;
05966         int ii;
05967         size_t iocount;
05968 
05969         status = NC_check_id(ncid, &ncp); 
05970         if(status != NC_NOERR)
05971                 return status;
05972 
05973         if(NC_indef(ncp))
05974                 return NC_EINDEFINE;
05975 
05976         varp = NC_lookupvar(ncp, varid);
05977         if(varp == NULL)
05978                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
05979 
05980         if(varp->type == NC_CHAR)
05981                 return NC_ECHAR;
05982 
05983         status = NCcoordck(ncp, varp, start);
05984         if(status != NC_NOERR)
05985                 return status;
05986         status = NCedgeck(ncp, varp, start, edges);
05987         if(status != NC_NOERR)
05988                 return status;
05989 
05990         if(varp->ndims == 0) /* scalar variable */
05991         {
05992                 return( getNCv_uchar(ncp, varp, start, 1, value) );
05993         }
05994 
05995         if(IS_RECVAR(varp))
05996         {
05997                 if(*start + *edges > NC_get_numrecs(ncp))
05998                         return NC_EEDGE;
05999                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06000                 {
06001                         /* one dimensional && the only record variable  */
06002                         return( getNCv_uchar(ncp, varp, start, *edges, value) );
06003                 }
06004         }
06005 
06006         /*
06007          * find max contiguous
06008          *   and accumulate max count for a single io operation
06009          */
06010         ii = NCiocount(ncp, varp, edges, &iocount);
06011 
06012         if(ii == -1)
06013         {
06014                 return( getNCv_uchar(ncp, varp, start, iocount, value) );
06015         }
06016 
06017         assert(ii >= 0);
06018 
06019 
06020         { /* inline */
06021         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06022         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06023         const size_t index = ii;
06024 
06025         /* copy in starting indices */
06026         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06027 
06028         /* set up in maximum indices */
06029         set_upper(upper, start, edges, &upper[varp->ndims]);
06030 
06031         /* ripple counter */
06032         while(*coord < *upper)
06033         {
06034                 const int lstatus = getNCv_uchar(ncp, varp, coord, iocount,
06035                                 value);
06036                 if(lstatus != NC_NOERR)
06037                 {
06038                         if(lstatus != NC_ERANGE)
06039                         {
06040                                 status = lstatus;
06041                                 /* fatal for the loop */
06042                                 break;
06043                         }
06044                         /* else NC_ERANGE, not fatal for the loop */
06045                         if(status == NC_NOERR)
06046                                 status = lstatus;
06047                 }
06048                 value += iocount;
06049                 odo1(start, upper, coord, &upper[index], &coord[index]);
06050         }
06051 
06052         FREE_ONSTACK(upper);
06053         FREE_ONSTACK(coord);
06054         } /* end inline */
06055 
06056         return status;
06057 }
06058 
06059 int
06060 nc_get_vara_schar(int ncid, int varid,
06061          const size_t *start, const size_t *edges, schar *value)
06062 {
06063         int status = NC_NOERR;
06064         NC *ncp;
06065         const NC_var *varp;
06066         int ii;
06067         size_t iocount;
06068 
06069         status = NC_check_id(ncid, &ncp); 
06070         if(status != NC_NOERR)
06071                 return status;
06072 
06073         if(NC_indef(ncp))
06074                 return NC_EINDEFINE;
06075 
06076         varp = NC_lookupvar(ncp, varid);
06077         if(varp == NULL)
06078                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06079 
06080         if(varp->type == NC_CHAR)
06081                 return NC_ECHAR;
06082 
06083         status = NCcoordck(ncp, varp, start);
06084         if(status != NC_NOERR)
06085                 return status;
06086         status = NCedgeck(ncp, varp, start, edges);
06087         if(status != NC_NOERR)
06088                 return status;
06089 
06090         if(varp->ndims == 0) /* scalar variable */
06091         {
06092                 return( getNCv_schar(ncp, varp, start, 1, value) );
06093         }
06094 
06095         if(IS_RECVAR(varp))
06096         {
06097                 if(*start + *edges > NC_get_numrecs(ncp))
06098                         return NC_EEDGE;
06099                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06100                 {
06101                         /* one dimensional && the only record variable  */
06102                         return( getNCv_schar(ncp, varp, start, *edges, value) );
06103                 }
06104         }
06105 
06106         /*
06107          * find max contiguous
06108          *   and accumulate max count for a single io operation
06109          */
06110         ii = NCiocount(ncp, varp, edges, &iocount);
06111 
06112         if(ii == -1)
06113         {
06114                 return( getNCv_schar(ncp, varp, start, iocount, value) );
06115         }
06116 
06117         assert(ii >= 0);
06118 
06119 
06120         { /* inline */
06121         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06122         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06123         const size_t index = ii;
06124 
06125         /* copy in starting indices */
06126         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06127 
06128         /* set up in maximum indices */
06129         set_upper(upper, start, edges, &upper[varp->ndims]);
06130 
06131         /* ripple counter */
06132         while(*coord < *upper)
06133         {
06134                 const int lstatus = getNCv_schar(ncp, varp, coord, iocount,
06135                                 value);
06136                 if(lstatus != NC_NOERR)
06137                 {
06138                         if(lstatus != NC_ERANGE)
06139                         {
06140                                 status = lstatus;
06141                                 /* fatal for the loop */
06142                                 break;
06143                         }
06144                         /* else NC_ERANGE, not fatal for the loop */
06145                         if(status == NC_NOERR)
06146                                 status = lstatus;
06147                 }
06148                 value += iocount;
06149                 odo1(start, upper, coord, &upper[index], &coord[index]);
06150         }
06151 
06152         FREE_ONSTACK(upper);
06153         FREE_ONSTACK(coord);
06154         } /* end inline */
06155 
06156         return status;
06157 }
06158 
06159 int
06160 nc_get_vara_short(int ncid, int varid,
06161          const size_t *start, const size_t *edges, short *value)
06162 {
06163         int status = NC_NOERR;
06164         NC *ncp;
06165         const NC_var *varp;
06166         int ii;
06167         size_t iocount;
06168 
06169         status = NC_check_id(ncid, &ncp); 
06170         if(status != NC_NOERR)
06171                 return status;
06172 
06173         if(NC_indef(ncp))
06174                 return NC_EINDEFINE;
06175 
06176         varp = NC_lookupvar(ncp, varid);
06177         if(varp == NULL)
06178                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06179 
06180         if(varp->type == NC_CHAR)
06181                 return NC_ECHAR;
06182 
06183         status = NCcoordck(ncp, varp, start);
06184         if(status != NC_NOERR)
06185                 return status;
06186         status = NCedgeck(ncp, varp, start, edges);
06187         if(status != NC_NOERR)
06188                 return status;
06189 
06190         if(varp->ndims == 0) /* scalar variable */
06191         {
06192                 return( getNCv_short(ncp, varp, start, 1, value) );
06193         }
06194 
06195         if(IS_RECVAR(varp))
06196         {
06197                 if(*start + *edges > NC_get_numrecs(ncp))
06198                         return NC_EEDGE;
06199                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06200                 {
06201                         /* one dimensional && the only record variable  */
06202                         return( getNCv_short(ncp, varp, start, *edges, value) );
06203                 }
06204         }
06205 
06206         /*
06207          * find max contiguous
06208          *   and accumulate max count for a single io operation
06209          */
06210         ii = NCiocount(ncp, varp, edges, &iocount);
06211 
06212         if(ii == -1)
06213         {
06214                 return( getNCv_short(ncp, varp, start, iocount, value) );
06215         }
06216 
06217         assert(ii >= 0);
06218 
06219 
06220         { /* inline */
06221         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06222         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06223         const size_t index = ii;
06224 
06225         /* copy in starting indices */
06226         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06227 
06228         /* set up in maximum indices */
06229         set_upper(upper, start, edges, &upper[varp->ndims]);
06230 
06231         /* ripple counter */
06232         while(*coord < *upper)
06233         {
06234                 const int lstatus = getNCv_short(ncp, varp, coord, iocount,
06235                                 value);
06236                 if(lstatus != NC_NOERR)
06237                 {
06238                         if(lstatus != NC_ERANGE)
06239                         {
06240                                 status = lstatus;
06241                                 /* fatal for the loop */
06242                                 break;
06243                         }
06244                         /* else NC_ERANGE, not fatal for the loop */
06245                         if(status == NC_NOERR)
06246                                 status = lstatus;
06247                 }
06248                 value += iocount;
06249                 odo1(start, upper, coord, &upper[index], &coord[index]);
06250         }
06251 
06252         FREE_ONSTACK(upper);
06253         FREE_ONSTACK(coord);
06254         } /* end inline */
06255 
06256         return status;
06257 }
06258 
06259 int
06260 nc_get_vara_int(int ncid, int varid,
06261          const size_t *start, const size_t *edges, int *value)
06262 {
06263         int status = NC_NOERR;
06264         NC *ncp;
06265         const NC_var *varp;
06266         int ii;
06267         size_t iocount;
06268 
06269         status = NC_check_id(ncid, &ncp); 
06270         if(status != NC_NOERR)
06271                 return status;
06272 
06273         if(NC_indef(ncp))
06274                 return NC_EINDEFINE;
06275 
06276         varp = NC_lookupvar(ncp, varid);
06277         if(varp == NULL)
06278                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06279 
06280         if(varp->type == NC_CHAR)
06281                 return NC_ECHAR;
06282 
06283         status = NCcoordck(ncp, varp, start);
06284         if(status != NC_NOERR)
06285                 return status;
06286         status = NCedgeck(ncp, varp, start, edges);
06287         if(status != NC_NOERR)
06288                 return status;
06289 
06290         if(varp->ndims == 0) /* scalar variable */
06291         {
06292                 return( getNCv_int(ncp, varp, start, 1, value) );
06293         }
06294 
06295         if(IS_RECVAR(varp))
06296         {
06297                 if(*start + *edges > NC_get_numrecs(ncp))
06298                         return NC_EEDGE;
06299                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06300                 {
06301                         /* one dimensional && the only record variable  */
06302                         return( getNCv_int(ncp, varp, start, *edges, value) );
06303                 }
06304         }
06305 
06306         /*
06307          * find max contiguous
06308          *   and accumulate max count for a single io operation
06309          */
06310         ii = NCiocount(ncp, varp, edges, &iocount);
06311 
06312         if(ii == -1)
06313         {
06314                 return( getNCv_int(ncp, varp, start, iocount, value) );
06315         }
06316 
06317         assert(ii >= 0);
06318 
06319 
06320         { /* inline */
06321         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06322         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06323         const size_t index = ii;
06324 
06325         /* copy in starting indices */
06326         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06327 
06328         /* set up in maximum indices */
06329         set_upper(upper, start, edges, &upper[varp->ndims]);
06330 
06331         /* ripple counter */
06332         while(*coord < *upper)
06333         {
06334                 const int lstatus = getNCv_int(ncp, varp, coord, iocount,
06335                                 value);
06336                 if(lstatus != NC_NOERR)
06337                 {
06338                         if(lstatus != NC_ERANGE)
06339                         {
06340                                 status = lstatus;
06341                                 /* fatal for the loop */
06342                                 break;
06343                         }
06344                         /* else NC_ERANGE, not fatal for the loop */
06345                         if(status == NC_NOERR)
06346                                 status = lstatus;
06347                 }
06348                 value += iocount;
06349                 odo1(start, upper, coord, &upper[index], &coord[index]);
06350         }
06351 
06352         FREE_ONSTACK(upper);
06353         FREE_ONSTACK(coord);
06354         } /* end inline */
06355 
06356         return status;
06357 }
06358 
06359 int
06360 nc_get_vara_long(int ncid, int varid,
06361          const size_t *start, const size_t *edges, long *value)
06362 {
06363         int status = NC_NOERR;
06364         NC *ncp;
06365         const NC_var *varp;
06366         int ii;
06367         size_t iocount;
06368 
06369         status = NC_check_id(ncid, &ncp); 
06370         if(status != NC_NOERR)
06371                 return status;
06372 
06373         if(NC_indef(ncp))
06374                 return NC_EINDEFINE;
06375 
06376         varp = NC_lookupvar(ncp, varid);
06377         if(varp == NULL)
06378                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06379 
06380         if(varp->type == NC_CHAR)
06381                 return NC_ECHAR;
06382 
06383         status = NCcoordck(ncp, varp, start);
06384         if(status != NC_NOERR)
06385                 return status;
06386         status = NCedgeck(ncp, varp, start, edges);
06387         if(status != NC_NOERR)
06388                 return status;
06389 
06390         if(varp->ndims == 0) /* scalar variable */
06391         {
06392                 return( getNCv_long(ncp, varp, start, 1, value) );
06393         }
06394 
06395         if(IS_RECVAR(varp))
06396         {
06397                 if(*start + *edges > NC_get_numrecs(ncp))
06398                         return NC_EEDGE;
06399                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06400                 {
06401                         /* one dimensional && the only record variable  */
06402                         return( getNCv_long(ncp, varp, start, *edges, value) );
06403                 }
06404         }
06405 
06406         /*
06407          * find max contiguous
06408          *   and accumulate max count for a single io operation
06409          */
06410         ii = NCiocount(ncp, varp, edges, &iocount);
06411 
06412         if(ii == -1)
06413         {
06414                 return( getNCv_long(ncp, varp, start, iocount, value) );
06415         }
06416 
06417         assert(ii >= 0);
06418 
06419 
06420         { /* inline */
06421         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06422         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06423         const size_t index = ii;
06424 
06425         /* copy in starting indices */
06426         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06427 
06428         /* set up in maximum indices */
06429         set_upper(upper, start, edges, &upper[varp->ndims]);
06430 
06431         /* ripple counter */
06432         while(*coord < *upper)
06433         {
06434                 const int lstatus = getNCv_long(ncp, varp, coord, iocount,
06435                                 value);
06436                 if(lstatus != NC_NOERR)
06437                 {
06438                         if(lstatus != NC_ERANGE)
06439                         {
06440                                 status = lstatus;
06441                                 /* fatal for the loop */
06442                                 break;
06443                         }
06444                         /* else NC_ERANGE, not fatal for the loop */
06445                         if(status == NC_NOERR)
06446                                 status = lstatus;
06447                 }
06448                 value += iocount;
06449                 odo1(start, upper, coord, &upper[index], &coord[index]);
06450         }
06451 
06452         FREE_ONSTACK(upper);
06453         FREE_ONSTACK(coord);
06454         } /* end inline */
06455 
06456         return status;
06457 }
06458 
06459 int
06460 nc_get_vara_float(int ncid, int varid,
06461          const size_t *start, const size_t *edges, float *value)
06462 {
06463         int status = NC_NOERR;
06464         NC *ncp;
06465         const NC_var *varp;
06466         int ii;
06467         size_t iocount;
06468 
06469         status = NC_check_id(ncid, &ncp); 
06470         if(status != NC_NOERR)
06471                 return status;
06472 
06473         if(NC_indef(ncp))
06474                 return NC_EINDEFINE;
06475 
06476         varp = NC_lookupvar(ncp, varid);
06477         if(varp == NULL)
06478                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06479 
06480         if(varp->type == NC_CHAR)
06481                 return NC_ECHAR;
06482 
06483         status = NCcoordck(ncp, varp, start);
06484         if(status != NC_NOERR)
06485                 return status;
06486         status = NCedgeck(ncp, varp, start, edges);
06487         if(status != NC_NOERR)
06488                 return status;
06489 
06490         if(varp->ndims == 0) /* scalar variable */
06491         {
06492                 return( getNCv_float(ncp, varp, start, 1, value) );
06493         }
06494 
06495         if(IS_RECVAR(varp))
06496         {
06497                 if(*start + *edges > NC_get_numrecs(ncp))
06498                         return NC_EEDGE;
06499                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06500                 {
06501                         /* one dimensional && the only record variable  */
06502                         return( getNCv_float(ncp, varp, start, *edges, value) );
06503                 }
06504         }
06505 
06506         /*
06507          * find max contiguous
06508          *   and accumulate max count for a single io operation
06509          */
06510         ii = NCiocount(ncp, varp, edges, &iocount);
06511 
06512         if(ii == -1)
06513         {
06514                 return( getNCv_float(ncp, varp, start, iocount, value) );
06515         }
06516 
06517         assert(ii >= 0);
06518 
06519 
06520         { /* inline */
06521         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06522         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06523         const size_t index = ii;
06524 
06525         /* copy in starting indices */
06526         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06527 
06528         /* set up in maximum indices */
06529         set_upper(upper, start, edges, &upper[varp->ndims]);
06530 
06531         /* ripple counter */
06532         while(*coord < *upper)
06533         {
06534                 const int lstatus = getNCv_float(ncp, varp, coord, iocount,
06535                                 value);
06536                 if(lstatus != NC_NOERR)
06537                 {
06538                         if(lstatus != NC_ERANGE)
06539                         {
06540                                 status = lstatus;
06541                                 /* fatal for the loop */
06542                                 break;
06543                         }
06544                         /* else NC_ERANGE, not fatal for the loop */
06545                         if(status == NC_NOERR)
06546                                 status = lstatus;
06547                 }
06548                 value += iocount;
06549                 odo1(start, upper, coord, &upper[index], &coord[index]);
06550         }
06551 
06552         FREE_ONSTACK(upper);
06553         FREE_ONSTACK(coord);
06554         } /* end inline */
06555 
06556         return status;
06557 }
06558 
06559 int
06560 nc_get_vara_double(int ncid, int varid,
06561          const size_t *start, const size_t *edges, double *value)
06562 {
06563         int status = NC_NOERR;
06564         NC *ncp;
06565         const NC_var *varp;
06566         int ii;
06567         size_t iocount;
06568 
06569         status = NC_check_id(ncid, &ncp); 
06570         if(status != NC_NOERR)
06571                 return status;
06572 
06573         if(NC_indef(ncp))
06574                 return NC_EINDEFINE;
06575 
06576         varp = NC_lookupvar(ncp, varid);
06577         if(varp == NULL)
06578                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06579 
06580         if(varp->type == NC_CHAR)
06581                 return NC_ECHAR;
06582 
06583         status = NCcoordck(ncp, varp, start);
06584         if(status != NC_NOERR)
06585                 return status;
06586         status = NCedgeck(ncp, varp, start, edges);
06587         if(status != NC_NOERR)
06588                 return status;
06589 
06590         if(varp->ndims == 0) /* scalar variable */
06591         {
06592                 return( getNCv_double(ncp, varp, start, 1, value) );
06593         }
06594 
06595         if(IS_RECVAR(varp))
06596         {
06597                 if(*start + *edges > NC_get_numrecs(ncp))
06598                         return NC_EEDGE;
06599                 if(varp->ndims == 1 && ncp->recsize <= varp->len)
06600                 {
06601                         /* one dimensional && the only record variable  */
06602                         return( getNCv_double(ncp, varp, start, *edges, value) );
06603                 }
06604         }
06605 
06606         /*
06607          * find max contiguous
06608          *   and accumulate max count for a single io operation
06609          */
06610         ii = NCiocount(ncp, varp, edges, &iocount);
06611 
06612         if(ii == -1)
06613         {
06614                 return( getNCv_double(ncp, varp, start, iocount, value) );
06615         }
06616 
06617         assert(ii >= 0);
06618 
06619 
06620         { /* inline */
06621         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06622         ALLOC_ONSTACK(upper, size_t, varp->ndims);
06623         const size_t index = ii;
06624 
06625         /* copy in starting indices */
06626         (void) memcpy(coord, start, varp->ndims * sizeof(size_t));
06627 
06628         /* set up in maximum indices */
06629         set_upper(upper, start, edges, &upper[varp->ndims]);
06630 
06631         /* ripple counter */
06632         while(*coord < *upper)
06633         {
06634                 const int lstatus = getNCv_double(ncp, varp, coord, iocount,
06635                                 value);
06636                 if(lstatus != NC_NOERR)
06637                 {
06638                         if(lstatus != NC_ERANGE)
06639                         {
06640                                 status = lstatus;
06641                                 /* fatal for the loop */
06642                                 break;
06643                         }
06644                         /* else NC_ERANGE, not fatal for the loop */
06645                         if(status == NC_NOERR)
06646                                 status = lstatus;
06647                 }
06648                 value += iocount;
06649                 odo1(start, upper, coord, &upper[index], &coord[index]);
06650         }
06651 
06652         FREE_ONSTACK(upper);
06653         FREE_ONSTACK(coord);
06654         } /* end inline */
06655 
06656         return status;
06657 }
06658 
06659 
06660 
06661 /* deprecated, used to support the 2.x interface */
06662 int
06663 nc_get_vara(int ncid, int varid,
06664          const size_t *start, const size_t *edges, void *value)
06665 {
06666         int status;
06667         NC *ncp;
06668         const NC_var *varp;
06669 
06670         status = NC_check_id(ncid, &ncp); 
06671         if(status != NC_NOERR)
06672                 return status;
06673 
06674         if(NC_indef(ncp))
06675                 return NC_EINDEFINE;
06676 
06677         varp = NC_lookupvar(ncp, varid);
06678         if(varp == NULL)
06679                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06680 
06681         switch(varp->type){
06682         case NC_CHAR:
06683                 return nc_get_vara_text(ncid, varid, start, edges,
06684                         (char *) value);
06685         case NC_BYTE:
06686                 return nc_get_vara_schar(ncid, varid, start, edges,
06687                         (schar *) value);
06688         case NC_SHORT:
06689                 return nc_get_vara_short(ncid, varid, start, edges,
06690                         (short *) value);
06691         case NC_INT:
06692 #if (SIZEOF_INT >= X_SIZEOF_INT)
06693                 return nc_get_vara_int(ncid, varid, start, edges,
06694                         (int *) value);
06695 #elif SIZEOF_LONG == X_SIZEOF_INT
06696                 return nc_get_vara_long(ncid, varid, start, edges,
06697                         (long *) value);
06698 #else
06699 #error "nc_get_vara implementation"
06700 #endif
06701         case NC_FLOAT:
06702                 return nc_get_vara_float(ncid, varid, start, edges,
06703                         (float *) value);
06704         case NC_DOUBLE: 
06705                 return nc_get_vara_double(ncid, varid, start, edges,
06706                         (double *) value);
06707         }
06708         return NC_EBADTYPE;
06709 }
06710 
06711 #if defined(__cplusplus)
06712 /* C++ consts default to internal linkage and must be initialized */
06713 const size_t coord_zero[NC_MAX_VAR_DIMS] = {0};
06714 #else
06715 static const size_t coord_zero[NC_MAX_VAR_DIMS];
06716 #endif
06717 
06718 
06719 int
06720 nc_put_var_text(int ncid, int varid, const char *value)
06721 {
06722         int status = NC_NOERR;
06723         NC *ncp;
06724         const NC_var *varp;
06725 
06726         status = NC_check_id(ncid, &ncp); 
06727         if(status != NC_NOERR)
06728                 return status;
06729 
06730         if(NC_readonly(ncp))
06731                 return NC_EPERM;
06732 
06733         if(NC_indef(ncp))
06734                 return NC_EINDEFINE;
06735 
06736         varp = NC_lookupvar(ncp, varid);
06737         if(varp == NULL)
06738                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06739 
06740         if(varp->type != NC_CHAR)
06741                 return NC_ECHAR;
06742 
06743         if(varp->ndims == 0) /* scalar variable */
06744         {
06745                 const size_t zed = 0;
06746                 return( putNCv_text(ncp, varp, &zed, 1, value) );
06747         }
06748 
06749         if(!IS_RECVAR(varp))
06750         {
06751                 return(putNCv_text(ncp, varp, coord_zero, *varp->dsizes, value));
06752         }
06753         /* else */
06754 
06755         if(varp->ndims == 1
06756                         && ncp->recsize <= varp->len)
06757         {
06758                 /* one dimensional && the only record variable  */
06759                 return(putNCv_text(ncp, varp, coord_zero, NC_get_numrecs(ncp),
06760                         value));
06761         }
06762         /* else */
06763 
06764         {
06765         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06766         size_t elemsPerRec = 1;
06767         const size_t nrecs = NC_get_numrecs(ncp);
06768         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
06769         /* TODO: fix dsizes to avoid this nonsense */
06770         if(varp->ndims > 1)
06771                 elemsPerRec = varp->dsizes[1];
06772         while(*coord < nrecs)
06773         {
06774                 const int lstatus = putNCv_text(ncp, varp, coord, elemsPerRec,
06775                                  value);
06776                 if(lstatus != NC_NOERR)
06777                 {
06778                         if(lstatus != NC_ERANGE)
06779                         {
06780                                 status = lstatus;
06781                                 /* fatal for the loop */
06782                                 break;
06783                         }
06784                         /* else NC_ERANGE, not fatal for the loop */
06785                         if(status == NC_NOERR)
06786                                 status = lstatus;
06787                 }
06788                 value += elemsPerRec;
06789                 (*coord)++;
06790         }
06791         FREE_ONSTACK(coord);
06792         } /* elemsPerRec */
06793 
06794         return status;
06795 }
06796 
06797 
06798 int
06799 nc_put_var_uchar(int ncid, int varid, const uchar *value)
06800 {
06801         int status = NC_NOERR;
06802         NC *ncp;
06803         const NC_var *varp;
06804 
06805         status = NC_check_id(ncid, &ncp); 
06806         if(status != NC_NOERR)
06807                 return status;
06808 
06809         if(NC_readonly(ncp))
06810                 return NC_EPERM;
06811 
06812         if(NC_indef(ncp))
06813                 return NC_EINDEFINE;
06814 
06815         varp = NC_lookupvar(ncp, varid);
06816         if(varp == NULL)
06817                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06818 
06819         if(varp->type == NC_CHAR)
06820                 return NC_ECHAR;
06821 
06822         if(varp->ndims == 0) /* scalar variable */
06823         {
06824                 const size_t zed = 0;
06825                 return( putNCv_uchar(ncp, varp, &zed, 1, value) );
06826         }
06827 
06828         if(!IS_RECVAR(varp))
06829         {
06830                 return(putNCv_uchar(ncp, varp, coord_zero, *varp->dsizes, value));
06831         }
06832         /* else */
06833 
06834         if(varp->ndims == 1
06835                         && ncp->recsize <= varp->len)
06836         {
06837                 /* one dimensional && the only record variable  */
06838                 return(putNCv_uchar(ncp, varp, coord_zero, NC_get_numrecs(ncp),
06839                         value));
06840         }
06841         /* else */
06842 
06843         {
06844         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06845         size_t elemsPerRec = 1;
06846         const size_t nrecs = NC_get_numrecs(ncp);
06847         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
06848         /* TODO: fix dsizes to avoid this nonsense */
06849         if(varp->ndims > 1)
06850                 elemsPerRec = varp->dsizes[1];
06851         while(*coord < nrecs)
06852         {
06853                 const int lstatus = putNCv_uchar(ncp, varp, coord, elemsPerRec,
06854                                  value);
06855                 if(lstatus != NC_NOERR)
06856                 {
06857                         if(lstatus != NC_ERANGE)
06858                         {
06859                                 status = lstatus;
06860                                 /* fatal for the loop */
06861                                 break;
06862                         }
06863                         /* else NC_ERANGE, not fatal for the loop */
06864                         if(status == NC_NOERR)
06865                                 status = lstatus;
06866                 }
06867                 value += elemsPerRec;
06868                 (*coord)++;
06869         }
06870         FREE_ONSTACK(coord);
06871         } /* elemsPerRec */
06872 
06873         return status;
06874 }
06875 
06876 int
06877 nc_put_var_schar(int ncid, int varid, const schar *value)
06878 {
06879         int status = NC_NOERR;
06880         NC *ncp;
06881         const NC_var *varp;
06882 
06883         status = NC_check_id(ncid, &ncp); 
06884         if(status != NC_NOERR)
06885                 return status;
06886 
06887         if(NC_readonly(ncp))
06888                 return NC_EPERM;
06889 
06890         if(NC_indef(ncp))
06891                 return NC_EINDEFINE;
06892 
06893         varp = NC_lookupvar(ncp, varid);
06894         if(varp == NULL)
06895                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06896 
06897         if(varp->type == NC_CHAR)
06898                 return NC_ECHAR;
06899 
06900         if(varp->ndims == 0) /* scalar variable */
06901         {
06902                 const size_t zed = 0;
06903                 return( putNCv_schar(ncp, varp, &zed, 1, value) );
06904         }
06905 
06906         if(!IS_RECVAR(varp))
06907         {
06908                 return(putNCv_schar(ncp, varp, coord_zero, *varp->dsizes, value));
06909         }
06910         /* else */
06911 
06912         if(varp->ndims == 1
06913                         && ncp->recsize <= varp->len)
06914         {
06915                 /* one dimensional && the only record variable  */
06916                 return(putNCv_schar(ncp, varp, coord_zero, NC_get_numrecs(ncp),
06917                         value));
06918         }
06919         /* else */
06920 
06921         {
06922         ALLOC_ONSTACK(coord, size_t, varp->ndims);
06923         size_t elemsPerRec = 1;
06924         const size_t nrecs = NC_get_numrecs(ncp);
06925         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
06926         /* TODO: fix dsizes to avoid this nonsense */
06927         if(varp->ndims > 1)
06928                 elemsPerRec = varp->dsizes[1];
06929         while(*coord < nrecs)
06930         {
06931                 const int lstatus = putNCv_schar(ncp, varp, coord, elemsPerRec,
06932                                  value);
06933                 if(lstatus != NC_NOERR)
06934                 {
06935                         if(lstatus != NC_ERANGE)
06936                         {
06937                                 status = lstatus;
06938                                 /* fatal for the loop */
06939                                 break;
06940                         }
06941                         /* else NC_ERANGE, not fatal for the loop */
06942                         if(status == NC_NOERR)
06943                                 status = lstatus;
06944                 }
06945                 value += elemsPerRec;
06946                 (*coord)++;
06947         }
06948         FREE_ONSTACK(coord);
06949         } /* elemsPerRec */
06950 
06951         return status;
06952 }
06953 
06954 int
06955 nc_put_var_short(int ncid, int varid, const short *value)
06956 {
06957         int status = NC_NOERR;
06958         NC *ncp;
06959         const NC_var *varp;
06960 
06961         status = NC_check_id(ncid, &ncp); 
06962         if(status != NC_NOERR)
06963                 return status;
06964 
06965         if(NC_readonly(ncp))
06966                 return NC_EPERM;
06967 
06968         if(NC_indef(ncp))
06969                 return NC_EINDEFINE;
06970 
06971         varp = NC_lookupvar(ncp, varid);
06972         if(varp == NULL)
06973                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
06974 
06975         if(varp->type == NC_CHAR)
06976                 return NC_ECHAR;
06977 
06978         if(varp->ndims == 0) /* scalar variable */
06979         {
06980                 const size_t zed = 0;
06981                 return( putNCv_short(ncp, varp, &zed, 1, value) );
06982         }
06983 
06984         if(!IS_RECVAR(varp))
06985         {
06986                 return(putNCv_short(ncp, varp, coord_zero, *varp->dsizes, value));
06987         }
06988         /* else */
06989 
06990         if(varp->ndims == 1
06991                         && ncp->recsize <= varp->len)
06992         {
06993                 /* one dimensional && the only record variable  */
06994                 return(putNCv_short(ncp, varp, coord_zero, NC_get_numrecs(ncp),
06995                         value));
06996         }
06997         /* else */
06998 
06999         {
07000         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07001         size_t elemsPerRec = 1;
07002         const size_t nrecs = NC_get_numrecs(ncp);
07003         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07004         /* TODO: fix dsizes to avoid this nonsense */
07005         if(varp->ndims > 1)
07006                 elemsPerRec = varp->dsizes[1];
07007         while(*coord < nrecs)
07008         {
07009                 const int lstatus = putNCv_short(ncp, varp, coord, elemsPerRec,
07010                                  value);
07011                 if(lstatus != NC_NOERR)
07012                 {
07013                         if(lstatus != NC_ERANGE)
07014                         {
07015                                 status = lstatus;
07016                                 /* fatal for the loop */
07017                                 break;
07018                         }
07019                         /* else NC_ERANGE, not fatal for the loop */
07020                         if(status == NC_NOERR)
07021                                 status = lstatus;
07022                 }
07023                 value += elemsPerRec;
07024                 (*coord)++;
07025         }
07026         FREE_ONSTACK(coord);
07027         } /* elemsPerRec */
07028 
07029         return status;
07030 }
07031 
07032 int
07033 nc_put_var_int(int ncid, int varid, const int *value)
07034 {
07035         int status = NC_NOERR;
07036         NC *ncp;
07037         const NC_var *varp;
07038 
07039         status = NC_check_id(ncid, &ncp); 
07040         if(status != NC_NOERR)
07041                 return status;
07042 
07043         if(NC_readonly(ncp))
07044                 return NC_EPERM;
07045 
07046         if(NC_indef(ncp))
07047                 return NC_EINDEFINE;
07048 
07049         varp = NC_lookupvar(ncp, varid);
07050         if(varp == NULL)
07051                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07052 
07053         if(varp->type == NC_CHAR)
07054                 return NC_ECHAR;
07055 
07056         if(varp->ndims == 0) /* scalar variable */
07057         {
07058                 const size_t zed = 0;
07059                 return( putNCv_int(ncp, varp, &zed, 1, value) );
07060         }
07061 
07062         if(!IS_RECVAR(varp))
07063         {
07064                 return(putNCv_int(ncp, varp, coord_zero, *varp->dsizes, value));
07065         }
07066         /* else */
07067 
07068         if(varp->ndims == 1
07069                         && ncp->recsize <= varp->len)
07070         {
07071                 /* one dimensional && the only record variable  */
07072                 return(putNCv_int(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07073                         value));
07074         }
07075         /* else */
07076 
07077         {
07078         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07079         size_t elemsPerRec = 1;
07080         const size_t nrecs = NC_get_numrecs(ncp);
07081         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07082         /* TODO: fix dsizes to avoid this nonsense */
07083         if(varp->ndims > 1)
07084                 elemsPerRec = varp->dsizes[1];
07085         while(*coord < nrecs)
07086         {
07087                 const int lstatus = putNCv_int(ncp, varp, coord, elemsPerRec,
07088                                  value);
07089                 if(lstatus != NC_NOERR)
07090                 {
07091                         if(lstatus != NC_ERANGE)
07092                         {
07093                                 status = lstatus;
07094                                 /* fatal for the loop */
07095                                 break;
07096                         }
07097                         /* else NC_ERANGE, not fatal for the loop */
07098                         if(status == NC_NOERR)
07099                                 status = lstatus;
07100                 }
07101                 value += elemsPerRec;
07102                 (*coord)++;
07103         }
07104         FREE_ONSTACK(coord);
07105         } /* elemsPerRec */
07106 
07107         return status;
07108 }
07109 
07110 int
07111 nc_put_var_long(int ncid, int varid, const long *value)
07112 {
07113         int status = NC_NOERR;
07114         NC *ncp;
07115         const NC_var *varp;
07116 
07117         status = NC_check_id(ncid, &ncp); 
07118         if(status != NC_NOERR)
07119                 return status;
07120 
07121         if(NC_readonly(ncp))
07122                 return NC_EPERM;
07123 
07124         if(NC_indef(ncp))
07125                 return NC_EINDEFINE;
07126 
07127         varp = NC_lookupvar(ncp, varid);
07128         if(varp == NULL)
07129                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07130 
07131         if(varp->type == NC_CHAR)
07132                 return NC_ECHAR;
07133 
07134         if(varp->ndims == 0) /* scalar variable */
07135         {
07136                 const size_t zed = 0;
07137                 return( putNCv_long(ncp, varp, &zed, 1, value) );
07138         }
07139 
07140         if(!IS_RECVAR(varp))
07141         {
07142                 return(putNCv_long(ncp, varp, coord_zero, *varp->dsizes, value));
07143         }
07144         /* else */
07145 
07146         if(varp->ndims == 1
07147                         && ncp->recsize <= varp->len)
07148         {
07149                 /* one dimensional && the only record variable  */
07150                 return(putNCv_long(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07151                         value));
07152         }
07153         /* else */
07154 
07155         {
07156         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07157         size_t elemsPerRec = 1;
07158         const size_t nrecs = NC_get_numrecs(ncp);
07159         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07160         /* TODO: fix dsizes to avoid this nonsense */
07161         if(varp->ndims > 1)
07162                 elemsPerRec = varp->dsizes[1];
07163         while(*coord < nrecs)
07164         {
07165                 const int lstatus = putNCv_long(ncp, varp, coord, elemsPerRec,
07166                                  value);
07167                 if(lstatus != NC_NOERR)
07168                 {
07169                         if(lstatus != NC_ERANGE)
07170                         {
07171                                 status = lstatus;
07172                                 /* fatal for the loop */
07173                                 break;
07174                         }
07175                         /* else NC_ERANGE, not fatal for the loop */
07176                         if(status == NC_NOERR)
07177                                 status = lstatus;
07178                 }
07179                 value += elemsPerRec;
07180                 (*coord)++;
07181         }
07182         FREE_ONSTACK(coord);
07183         } /* elemsPerRec */
07184 
07185         return status;
07186 }
07187 
07188 int
07189 nc_put_var_float(int ncid, int varid, const float *value)
07190 {
07191         int status = NC_NOERR;
07192         NC *ncp;
07193         const NC_var *varp;
07194 
07195         status = NC_check_id(ncid, &ncp); 
07196         if(status != NC_NOERR)
07197                 return status;
07198 
07199         if(NC_readonly(ncp))
07200                 return NC_EPERM;
07201 
07202         if(NC_indef(ncp))
07203                 return NC_EINDEFINE;
07204 
07205         varp = NC_lookupvar(ncp, varid);
07206         if(varp == NULL)
07207                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07208 
07209         if(varp->type == NC_CHAR)
07210                 return NC_ECHAR;
07211 
07212         if(varp->ndims == 0) /* scalar variable */
07213         {
07214                 const size_t zed = 0;
07215                 return( putNCv_float(ncp, varp, &zed, 1, value) );
07216         }
07217 
07218         if(!IS_RECVAR(varp))
07219         {
07220                 return(putNCv_float(ncp, varp, coord_zero, *varp->dsizes, value));
07221         }
07222         /* else */
07223 
07224         if(varp->ndims == 1
07225                         && ncp->recsize <= varp->len)
07226         {
07227                 /* one dimensional && the only record variable  */
07228                 return(putNCv_float(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07229                         value));
07230         }
07231         /* else */
07232 
07233         {
07234         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07235         size_t elemsPerRec = 1;
07236         const size_t nrecs = NC_get_numrecs(ncp);
07237         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07238         /* TODO: fix dsizes to avoid this nonsense */
07239         if(varp->ndims > 1)
07240                 elemsPerRec = varp->dsizes[1];
07241         while(*coord < nrecs)
07242         {
07243                 const int lstatus = putNCv_float(ncp, varp, coord, elemsPerRec,
07244                                  value);
07245                 if(lstatus != NC_NOERR)
07246                 {
07247                         if(lstatus != NC_ERANGE)
07248                         {
07249                                 status = lstatus;
07250                                 /* fatal for the loop */
07251                                 break;
07252                         }
07253                         /* else NC_ERANGE, not fatal for the loop */
07254                         if(status == NC_NOERR)
07255                                 status = lstatus;
07256                 }
07257                 value += elemsPerRec;
07258                 (*coord)++;
07259         }
07260         FREE_ONSTACK(coord);
07261         } /* elemsPerRec */
07262 
07263         return status;
07264 }
07265 
07266 int
07267 nc_put_var_double(int ncid, int varid, const double *value)
07268 {
07269         int status = NC_NOERR;
07270         NC *ncp;
07271         const NC_var *varp;
07272 
07273         status = NC_check_id(ncid, &ncp); 
07274         if(status != NC_NOERR)
07275                 return status;
07276 
07277         if(NC_readonly(ncp))
07278                 return NC_EPERM;
07279 
07280         if(NC_indef(ncp))
07281                 return NC_EINDEFINE;
07282 
07283         varp = NC_lookupvar(ncp, varid);
07284         if(varp == NULL)
07285                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07286 
07287         if(varp->type == NC_CHAR)
07288                 return NC_ECHAR;
07289 
07290         if(varp->ndims == 0) /* scalar variable */
07291         {
07292                 const size_t zed = 0;
07293                 return( putNCv_double(ncp, varp, &zed, 1, value) );
07294         }
07295 
07296         if(!IS_RECVAR(varp))
07297         {
07298                 return(putNCv_double(ncp, varp, coord_zero, *varp->dsizes, value));
07299         }
07300         /* else */
07301 
07302         if(varp->ndims == 1
07303                         && ncp->recsize <= varp->len)
07304         {
07305                 /* one dimensional && the only record variable  */
07306                 return(putNCv_double(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07307                         value));
07308         }
07309         /* else */
07310 
07311         {
07312         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07313         size_t elemsPerRec = 1;
07314         const size_t nrecs = NC_get_numrecs(ncp);
07315         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07316         /* TODO: fix dsizes to avoid this nonsense */
07317         if(varp->ndims > 1)
07318                 elemsPerRec = varp->dsizes[1];
07319         while(*coord < nrecs)
07320         {
07321                 const int lstatus = putNCv_double(ncp, varp, coord, elemsPerRec,
07322                                  value);
07323                 if(lstatus != NC_NOERR)
07324                 {
07325                         if(lstatus != NC_ERANGE)
07326                         {
07327                                 status = lstatus;
07328                                 /* fatal for the loop */
07329                                 break;
07330                         }
07331                         /* else NC_ERANGE, not fatal for the loop */
07332                         if(status == NC_NOERR)
07333                                 status = lstatus;
07334                 }
07335                 value += elemsPerRec;
07336                 (*coord)++;
07337         }
07338         FREE_ONSTACK(coord);
07339         } /* elemsPerRec */
07340 
07341         return status;
07342 }
07343 
07344 
07345 
07346 
07347 int
07348 nc_get_var_text(int ncid, int varid, char *value)
07349 {
07350         int status = NC_NOERR;
07351         NC *ncp;
07352         const NC_var *varp;
07353 
07354         status = NC_check_id(ncid, &ncp); 
07355         if(status != NC_NOERR)
07356                 return status;
07357 
07358         if(NC_indef(ncp))
07359                 return NC_EINDEFINE;
07360 
07361         varp = NC_lookupvar(ncp, varid);
07362         if(varp == NULL)
07363                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07364 
07365         if(varp->ndims == 0) /* scalar variable */
07366         {
07367                 const size_t zed = 0;
07368                 return( getNCv_text(ncp, varp, &zed, 1, value) );
07369         }
07370 
07371         if(varp->type != NC_CHAR)
07372                 return NC_ECHAR;
07373 
07374 
07375         if(!IS_RECVAR(varp))
07376         {
07377                 return(getNCv_text(ncp, varp, coord_zero, *varp->dsizes, value));
07378         }
07379         /* else */
07380 
07381         if(varp->ndims == 1
07382                         && ncp->recsize <= varp->len)
07383         {
07384                 /* one dimensional && the only record variable  */
07385                 return(getNCv_text(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07386                         value));
07387         }
07388         /* else */
07389 
07390         {
07391         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07392         size_t elemsPerRec = 1;
07393         const size_t nrecs = NC_get_numrecs(ncp);
07394         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07395         /* TODO: fix dsizes to avoid this nonsense */
07396         if(varp->ndims > 1)
07397                 elemsPerRec = varp->dsizes[1];
07398         while(*coord < nrecs)
07399         {
07400                 const int lstatus = getNCv_text(ncp, varp, coord, elemsPerRec,
07401                                 value);
07402                 if(lstatus != NC_NOERR)
07403                 {
07404                         if(lstatus != NC_ERANGE)
07405                         {
07406                                 status = lstatus;
07407                                 /* fatal for the loop */
07408                                 break;
07409                         }
07410                         /* else NC_ERANGE, not fatal for the loop */
07411                         if(status == NC_NOERR)
07412                                 status = lstatus;
07413                 }
07414                 value += elemsPerRec;
07415                 (*coord)++;
07416         }
07417         FREE_ONSTACK(coord);
07418         } /* elemsPerRec */
07419 
07420         return status;
07421 }
07422 
07423 
07424 int
07425 nc_get_var_uchar(int ncid, int varid, uchar *value)
07426 {
07427         int status = NC_NOERR;
07428         NC *ncp;
07429         const NC_var *varp;
07430 
07431         status = NC_check_id(ncid, &ncp); 
07432         if(status != NC_NOERR)
07433                 return status;
07434 
07435         if(NC_indef(ncp))
07436                 return NC_EINDEFINE;
07437 
07438         varp = NC_lookupvar(ncp, varid);
07439         if(varp == NULL)
07440                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07441 
07442         if(varp->ndims == 0) /* scalar variable */
07443         {
07444                 const size_t zed = 0;
07445                 return( getNCv_uchar(ncp, varp, &zed, 1, value) );
07446         }
07447 
07448         if(varp->type == NC_CHAR)
07449                 return NC_ECHAR;
07450 
07451 
07452         if(!IS_RECVAR(varp))
07453         {
07454                 return(getNCv_uchar(ncp, varp, coord_zero, *varp->dsizes, value));
07455         }
07456         /* else */
07457 
07458         if(varp->ndims == 1
07459                         && ncp->recsize <= varp->len)
07460         {
07461                 /* one dimensional && the only record variable  */
07462                 return(getNCv_uchar(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07463                         value));
07464         }
07465         /* else */
07466 
07467         {
07468         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07469         size_t elemsPerRec = 1;
07470         const size_t nrecs = NC_get_numrecs(ncp);
07471         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07472         /* TODO: fix dsizes to avoid this nonsense */
07473         if(varp->ndims > 1)
07474                 elemsPerRec = varp->dsizes[1];
07475         while(*coord < nrecs)
07476         {
07477                 const int lstatus = getNCv_uchar(ncp, varp, coord, elemsPerRec,
07478                                 value);
07479                 if(lstatus != NC_NOERR)
07480                 {
07481                         if(lstatus != NC_ERANGE)
07482                         {
07483                                 status = lstatus;
07484                                 /* fatal for the loop */
07485                                 break;
07486                         }
07487                         /* else NC_ERANGE, not fatal for the loop */
07488                         if(status == NC_NOERR)
07489                                 status = lstatus;
07490                 }
07491                 value += elemsPerRec;
07492                 (*coord)++;
07493         }
07494         FREE_ONSTACK(coord);
07495         } /* elemsPerRec */
07496 
07497         return status;
07498 }
07499 
07500 int
07501 nc_get_var_schar(int ncid, int varid, schar *value)
07502 {
07503         int status = NC_NOERR;
07504         NC *ncp;
07505         const NC_var *varp;
07506 
07507         status = NC_check_id(ncid, &ncp); 
07508         if(status != NC_NOERR)
07509                 return status;
07510 
07511         if(NC_indef(ncp))
07512                 return NC_EINDEFINE;
07513 
07514         varp = NC_lookupvar(ncp, varid);
07515         if(varp == NULL)
07516                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07517 
07518         if(varp->ndims == 0) /* scalar variable */
07519         {
07520                 const size_t zed = 0;
07521                 return( getNCv_schar(ncp, varp, &zed, 1, value) );
07522         }
07523 
07524         if(varp->type == NC_CHAR)
07525                 return NC_ECHAR;
07526 
07527 
07528         if(!IS_RECVAR(varp))
07529         {
07530                 return(getNCv_schar(ncp, varp, coord_zero, *varp->dsizes, value));
07531         }
07532         /* else */
07533 
07534         if(varp->ndims == 1
07535                         && ncp->recsize <= varp->len)
07536         {
07537                 /* one dimensional && the only record variable  */
07538                 return(getNCv_schar(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07539                         value));
07540         }
07541         /* else */
07542 
07543         {
07544         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07545         size_t elemsPerRec = 1;
07546         const size_t nrecs = NC_get_numrecs(ncp);
07547         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07548         /* TODO: fix dsizes to avoid this nonsense */
07549         if(varp->ndims > 1)
07550                 elemsPerRec = varp->dsizes[1];
07551         while(*coord < nrecs)
07552         {
07553                 const int lstatus = getNCv_schar(ncp, varp, coord, elemsPerRec,
07554                                 value);
07555                 if(lstatus != NC_NOERR)
07556                 {
07557                         if(lstatus != NC_ERANGE)
07558                         {
07559                                 status = lstatus;
07560                                 /* fatal for the loop */
07561                                 break;
07562                         }
07563                         /* else NC_ERANGE, not fatal for the loop */
07564                         if(status == NC_NOERR)
07565                                 status = lstatus;
07566                 }
07567                 value += elemsPerRec;
07568                 (*coord)++;
07569         }
07570         FREE_ONSTACK(coord);
07571         } /* elemsPerRec */
07572 
07573         return status;
07574 }
07575 
07576 int
07577 nc_get_var_short(int ncid, int varid, short *value)
07578 {
07579         int status = NC_NOERR;
07580         NC *ncp;
07581         const NC_var *varp;
07582 
07583         status = NC_check_id(ncid, &ncp); 
07584         if(status != NC_NOERR)
07585                 return status;
07586 
07587         if(NC_indef(ncp))
07588                 return NC_EINDEFINE;
07589 
07590         varp = NC_lookupvar(ncp, varid);
07591         if(varp == NULL)
07592                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07593 
07594         if(varp->ndims == 0) /* scalar variable */
07595         {
07596                 const size_t zed = 0;
07597                 return( getNCv_short(ncp, varp, &zed, 1, value) );
07598         }
07599 
07600         if(varp->type == NC_CHAR)
07601                 return NC_ECHAR;
07602 
07603 
07604         if(!IS_RECVAR(varp))
07605         {
07606                 return(getNCv_short(ncp, varp, coord_zero, *varp->dsizes, value));
07607         }
07608         /* else */
07609 
07610         if(varp->ndims == 1
07611                         && ncp->recsize <= varp->len)
07612         {
07613                 /* one dimensional && the only record variable  */
07614                 return(getNCv_short(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07615                         value));
07616         }
07617         /* else */
07618 
07619         {
07620         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07621         size_t elemsPerRec = 1;
07622         const size_t nrecs = NC_get_numrecs(ncp);
07623         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07624         /* TODO: fix dsizes to avoid this nonsense */
07625         if(varp->ndims > 1)
07626                 elemsPerRec = varp->dsizes[1];
07627         while(*coord < nrecs)
07628         {
07629                 const int lstatus = getNCv_short(ncp, varp, coord, elemsPerRec,
07630                                 value);
07631                 if(lstatus != NC_NOERR)
07632                 {
07633                         if(lstatus != NC_ERANGE)
07634                         {
07635                                 status = lstatus;
07636                                 /* fatal for the loop */
07637                                 break;
07638                         }
07639                         /* else NC_ERANGE, not fatal for the loop */
07640                         if(status == NC_NOERR)
07641                                 status = lstatus;
07642                 }
07643                 value += elemsPerRec;
07644                 (*coord)++;
07645         }
07646         FREE_ONSTACK(coord);
07647         } /* elemsPerRec */
07648 
07649         return status;
07650 }
07651 
07652 int
07653 nc_get_var_int(int ncid, int varid, int *value)
07654 {
07655         int status = NC_NOERR;
07656         NC *ncp;
07657         const NC_var *varp;
07658 
07659         status = NC_check_id(ncid, &ncp); 
07660         if(status != NC_NOERR)
07661                 return status;
07662 
07663         if(NC_indef(ncp))
07664                 return NC_EINDEFINE;
07665 
07666         varp = NC_lookupvar(ncp, varid);
07667         if(varp == NULL)
07668                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07669 
07670         if(varp->ndims == 0) /* scalar variable */
07671         {
07672                 const size_t zed = 0;
07673                 return( getNCv_int(ncp, varp, &zed, 1, value) );
07674         }
07675 
07676         if(varp->type == NC_CHAR)
07677                 return NC_ECHAR;
07678 
07679 
07680         if(!IS_RECVAR(varp))
07681         {
07682                 return(getNCv_int(ncp, varp, coord_zero, *varp->dsizes, value));
07683         }
07684         /* else */
07685 
07686         if(varp->ndims == 1
07687                         && ncp->recsize <= varp->len)
07688         {
07689                 /* one dimensional && the only record variable  */
07690                 return(getNCv_int(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07691                         value));
07692         }
07693         /* else */
07694 
07695         {
07696         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07697         size_t elemsPerRec = 1;
07698         const size_t nrecs = NC_get_numrecs(ncp);
07699         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07700         /* TODO: fix dsizes to avoid this nonsense */
07701         if(varp->ndims > 1)
07702                 elemsPerRec = varp->dsizes[1];
07703         while(*coord < nrecs)
07704         {
07705                 const int lstatus = getNCv_int(ncp, varp, coord, elemsPerRec,
07706                                 value);
07707                 if(lstatus != NC_NOERR)
07708                 {
07709                         if(lstatus != NC_ERANGE)
07710                         {
07711                                 status = lstatus;
07712                                 /* fatal for the loop */
07713                                 break;
07714                         }
07715                         /* else NC_ERANGE, not fatal for the loop */
07716                         if(status == NC_NOERR)
07717                                 status = lstatus;
07718                 }
07719                 value += elemsPerRec;
07720                 (*coord)++;
07721         }
07722         FREE_ONSTACK(coord);
07723         } /* elemsPerRec */
07724 
07725         return status;
07726 }
07727 
07728 int
07729 nc_get_var_long(int ncid, int varid, long *value)
07730 {
07731         int status = NC_NOERR;
07732         NC *ncp;
07733         const NC_var *varp;
07734 
07735         status = NC_check_id(ncid, &ncp); 
07736         if(status != NC_NOERR)
07737                 return status;
07738 
07739         if(NC_indef(ncp))
07740                 return NC_EINDEFINE;
07741 
07742         varp = NC_lookupvar(ncp, varid);
07743         if(varp == NULL)
07744                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07745 
07746         if(varp->ndims == 0) /* scalar variable */
07747         {
07748                 const size_t zed = 0;
07749                 return( getNCv_long(ncp, varp, &zed, 1, value) );
07750         }
07751 
07752         if(varp->type == NC_CHAR)
07753                 return NC_ECHAR;
07754 
07755 
07756         if(!IS_RECVAR(varp))
07757         {
07758                 return(getNCv_long(ncp, varp, coord_zero, *varp->dsizes, value));
07759         }
07760         /* else */
07761 
07762         if(varp->ndims == 1
07763                         && ncp->recsize <= varp->len)
07764         {
07765                 /* one dimensional && the only record variable  */
07766                 return(getNCv_long(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07767                         value));
07768         }
07769         /* else */
07770 
07771         {
07772         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07773         size_t elemsPerRec = 1;
07774         const size_t nrecs = NC_get_numrecs(ncp);
07775         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07776         /* TODO: fix dsizes to avoid this nonsense */
07777         if(varp->ndims > 1)
07778                 elemsPerRec = varp->dsizes[1];
07779         while(*coord < nrecs)
07780         {
07781                 const int lstatus = getNCv_long(ncp, varp, coord, elemsPerRec,
07782                                 value);
07783                 if(lstatus != NC_NOERR)
07784                 {
07785                         if(lstatus != NC_ERANGE)
07786                         {
07787                                 status = lstatus;
07788                                 /* fatal for the loop */
07789                                 break;
07790                         }
07791                         /* else NC_ERANGE, not fatal for the loop */
07792                         if(status == NC_NOERR)
07793                                 status = lstatus;
07794                 }
07795                 value += elemsPerRec;
07796                 (*coord)++;
07797         }
07798         FREE_ONSTACK(coord);
07799         } /* elemsPerRec */
07800 
07801         return status;
07802 }
07803 
07804 int
07805 nc_get_var_float(int ncid, int varid, float *value)
07806 {
07807         int status = NC_NOERR;
07808         NC *ncp;
07809         const NC_var *varp;
07810 
07811         status = NC_check_id(ncid, &ncp); 
07812         if(status != NC_NOERR)
07813                 return status;
07814 
07815         if(NC_indef(ncp))
07816                 return NC_EINDEFINE;
07817 
07818         varp = NC_lookupvar(ncp, varid);
07819         if(varp == NULL)
07820                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07821 
07822         if(varp->ndims == 0) /* scalar variable */
07823         {
07824                 const size_t zed = 0;
07825                 return( getNCv_float(ncp, varp, &zed, 1, value) );
07826         }
07827 
07828         if(varp->type == NC_CHAR)
07829                 return NC_ECHAR;
07830 
07831 
07832         if(!IS_RECVAR(varp))
07833         {
07834                 return(getNCv_float(ncp, varp, coord_zero, *varp->dsizes, value));
07835         }
07836         /* else */
07837 
07838         if(varp->ndims == 1
07839                         && ncp->recsize <= varp->len)
07840         {
07841                 /* one dimensional && the only record variable  */
07842                 return(getNCv_float(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07843                         value));
07844         }
07845         /* else */
07846 
07847         {
07848         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07849         size_t elemsPerRec = 1;
07850         const size_t nrecs = NC_get_numrecs(ncp);
07851         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07852         /* TODO: fix dsizes to avoid this nonsense */
07853         if(varp->ndims > 1)
07854                 elemsPerRec = varp->dsizes[1];
07855         while(*coord < nrecs)
07856         {
07857                 const int lstatus = getNCv_float(ncp, varp, coord, elemsPerRec,
07858                                 value);
07859                 if(lstatus != NC_NOERR)
07860                 {
07861                         if(lstatus != NC_ERANGE)
07862                         {
07863                                 status = lstatus;
07864                                 /* fatal for the loop */
07865                                 break;
07866                         }
07867                         /* else NC_ERANGE, not fatal for the loop */
07868                         if(status == NC_NOERR)
07869                                 status = lstatus;
07870                 }
07871                 value += elemsPerRec;
07872                 (*coord)++;
07873         }
07874         FREE_ONSTACK(coord);
07875         } /* elemsPerRec */
07876 
07877         return status;
07878 }
07879 
07880 int
07881 nc_get_var_double(int ncid, int varid, double *value)
07882 {
07883         int status = NC_NOERR;
07884         NC *ncp;
07885         const NC_var *varp;
07886 
07887         status = NC_check_id(ncid, &ncp); 
07888         if(status != NC_NOERR)
07889                 return status;
07890 
07891         if(NC_indef(ncp))
07892                 return NC_EINDEFINE;
07893 
07894         varp = NC_lookupvar(ncp, varid);
07895         if(varp == NULL)
07896                 return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */
07897 
07898         if(varp->ndims == 0) /* scalar variable */
07899         {
07900                 const size_t zed = 0;
07901                 return( getNCv_double(ncp, varp, &zed, 1, value) );
07902         }
07903 
07904         if(varp->type == NC_CHAR)
07905                 return NC_ECHAR;
07906 
07907 
07908         if(!IS_RECVAR(varp))
07909         {
07910                 return(getNCv_double(ncp, varp, coord_zero, *varp->dsizes, value));
07911         }
07912         /* else */
07913 
07914         if(varp->ndims == 1
07915                         && ncp->recsize <= varp->len)
07916         {
07917                 /* one dimensional && the only record variable  */
07918                 return(getNCv_double(ncp, varp, coord_zero, NC_get_numrecs(ncp),
07919                         value));
07920         }
07921         /* else */
07922 
07923         {
07924         ALLOC_ONSTACK(coord, size_t, varp->ndims);
07925         size_t elemsPerRec = 1;
07926         const size_t nrecs = NC_get_numrecs(ncp);
07927         (void) memset(coord, 0, varp->ndims * sizeof(size_t));
07928         /* TODO: fix dsizes to avoid this nonsense */
07929         if(varp->ndims > 1)
07930                 elemsPerRec = varp->dsizes[1];
07931         while(*coord < nrecs)
07932         {
07933                 const int lstatus = getNCv_double(ncp, varp, coord, elemsPerRec,
07934                                 value);
07935                 if(lstatus != NC_NOERR)
07936                 {
07937                         if(lstatus != NC_ERANGE)
07938                         {
07939                                 status = lstatus;
07940                                 /* fatal for the loop */
07941                                 break;
07942                         }
07943                         /* else NC_ERANGE, not fatal for the loop */
07944                         if(status == NC_NOERR)
07945                                 status = lstatus;
07946                 }
07947                 value += elemsPerRec;
07948                 (*coord)++;
07949         }
07950         FREE_ONSTACK(coord);
07951         } /* elemsPerRec */
07952 
07953         return status;
07954 }
07955 
07956 
07957 
07958 /* Begin putgetg.c */
07959 
07960 
07961 
07962 int
07963 nc_get_vars_text (
07964         int ncid,
07965         int varid,
07966         const size_t * start,
07967         const size_t * edges,
07968         const ptrdiff_t * stride,
07969         char *value)
07970 {
07971         return nc_get_varm_text (ncid, varid, start, edges,
07972                          stride, 0, value);
07973 }
07974 
07975 
07976 int
07977 nc_get_vars_uchar (
07978         int ncid,
07979         int varid,
07980         const size_t * start,
07981         const size_t * edges,
07982         const ptrdiff_t * stride,
07983         uchar *value)
07984 {
07985         return nc_get_varm_uchar (ncid, varid, start, edges,
07986                          stride, 0, value);
07987 }
07988 
07989 int
07990 nc_get_vars_schar (
07991         int ncid,
07992         int varid,
07993         const size_t * start,
07994         const size_t * edges,
07995         const ptrdiff_t * stride,
07996         schar *value)
07997 {
07998         return nc_get_varm_schar (ncid, varid, start, edges,
07999                          stride, 0, value);
08000 }
08001 
08002 int
08003 nc_get_vars_short (
08004         int ncid,
08005         int varid,
08006         const size_t * start,
08007         const size_t * edges,
08008         const ptrdiff_t * stride,
08009         short *value)
08010 {
08011         return nc_get_varm_short (ncid, varid, start, edges,
08012                          stride, 0, value);
08013 }
08014 
08015 int
08016 nc_get_vars_int (
08017         int ncid,
08018         int varid,
08019         const size_t * start,
08020         const size_t * edges,
08021         const ptrdiff_t * stride,
08022         int *value)
08023 {
08024         return nc_get_varm_int (ncid, varid, start, edges,
08025                          stride, 0, value);
08026 }
08027 
08028 int
08029 nc_get_vars_long (
08030         int ncid,
08031         int varid,
08032         const size_t * start,
08033         const size_t * edges,
08034         const ptrdiff_t * stride,
08035         long *value)
08036 {
08037         return nc_get_varm_long (ncid, varid, start, edges,
08038                          stride, 0, value);
08039 }
08040 
08041 int
08042 nc_get_vars_float (
08043         int ncid,
08044         int varid,
08045         const size_t * start,
08046         const size_t * edges,
08047         const ptrdiff_t * stride,
08048         float *value)
08049 {
08050         return nc_get_varm_float (ncid, varid, start, edges,
08051                          stride, 0, value);
08052 }
08053 
08054 int
08055 nc_get_vars_double (
08056         int ncid,
08057         int varid,
08058         const size_t * start,
08059         const size_t * edges,
08060         const ptrdiff_t * stride,
08061         double *value)
08062 {
08063         return nc_get_varm_double (ncid, varid, start, edges,
08064                          stride, 0, value);
08065 }
08066 
08067 
08068 int
08069 nc_get_vars (
08070         int ncid,
08071         int varid,
08072         const size_t * start,
08073         const size_t * edges,
08074         const ptrdiff_t * stride,
08075         void *value)
08076 {
08077         return nc_get_varm (ncid, varid, start, edges,
08078                          stride, 0, value);
08079 }
08080 
08081 
08082 
08083 int
08084 nc_put_vars_text (
08085         int ncid,
08086         int varid,
08087         const size_t * start,
08088         const size_t * edges,
08089         const ptrdiff_t * stride,
08090         const char *value)
08091 {
08092         return nc_put_varm_text (ncid, varid, start, edges,
08093                          stride, 0, value);
08094 }
08095 
08096 
08097 int
08098 nc_put_vars_uchar (
08099         int ncid,
08100         int varid,
08101         const size_t * start,
08102         const size_t * edges,
08103         const ptrdiff_t * stride,
08104         const uchar *value)
08105 {
08106         return nc_put_varm_uchar (ncid, varid, start, edges,
08107                          stride, 0, value);
08108 }
08109 
08110 int
08111 nc_put_vars_schar (
08112         int ncid,
08113         int varid,
08114         const size_t * start,
08115         const size_t * edges,
08116         const ptrdiff_t * stride,
08117         const schar *value)
08118 {
08119         return nc_put_varm_schar (ncid, varid, start, edges,
08120                          stride, 0, value);
08121 }
08122 
08123 int
08124 nc_put_vars_short (
08125         int ncid,
08126         int varid,
08127         const size_t * start,
08128         const size_t * edges,
08129         const ptrdiff_t * stride,
08130         const short *value)
08131 {
08132         return nc_put_varm_short (ncid, varid, start, edges,
08133                          stride, 0, value);
08134 }
08135 
08136 int
08137 nc_put_vars_int (
08138         int ncid,
08139         int varid,
08140         const size_t * start,
08141         const size_t * edges,
08142         const ptrdiff_t * stride,
08143         const int *value)
08144 {
08145         return nc_put_varm_int (ncid, varid, start, edges,
08146                          stride, 0, value);
08147 }
08148 
08149 int
08150 nc_put_vars_long (
08151         int ncid,
08152         int varid,
08153         const size_t * start,
08154         const size_t * edges,
08155         const ptrdiff_t * stride,
08156         const long *value)
08157 {
08158         return nc_put_varm_long (ncid, varid, start, edges,
08159                          stride, 0, value);
08160 }
08161 
08162 int
08163 nc_put_vars_float (
08164         int ncid,
08165         int varid,
08166         const size_t * start,
08167         const size_t * edges,
08168         const ptrdiff_t * stride,
08169         const float *value)
08170 {
08171         return nc_put_varm_float (ncid, varid, start, edges,
08172                          stride, 0, value);
08173 }
08174 
08175 int
08176 nc_put_vars_double (
08177         int ncid,
08178         int varid,
08179         const size_t * start,
08180         const size_t * edges,
08181         const ptrdiff_t * stride,
08182         const double *value)
08183 {
08184         return nc_put_varm_double (ncid, varid, start, edges,
08185                          stride, 0, value);
08186 }
08187 
08188 
08189 int
08190 nc_put_vars (
08191         int ncid,
08192         int varid,
08193         const size_t * start,
08194         const size_t * edges,
08195         const ptrdiff_t * stride,
08196         const void *value)
08197 {
08198         return nc_put_varm (ncid, varid, start, edges,
08199                          stride, 0, value);
08200 }
08201 
08202 
08203 /*
08204  * Generalized hyperslab input.
08205  */
08206 
08207 int
08208 nc_get_varm_text(int ncid, int varid,
08209         const size_t *start, const size_t *edges,
08210         const ptrdiff_t *stride,
08211         const ptrdiff_t *map,
08212         char *value)
08213 {
08214         int status = ENOERR;
08215         NC *ncp;
08216         NC_var *varp;
08217         int maxidim;    /* maximum dimensional index */
08218 
08219         status = NC_check_id (ncid, &ncp);
08220         if (status != NC_NOERR)
08221                 return status;
08222 
08223         if (NC_indef (ncp))
08224         {
08225                 return NC_EINDEFINE;
08226         }
08227 
08228         varp = NC_lookupvar (ncp, varid);
08229         if (varp == NULL)
08230                 return NC_ENOTVAR;
08231 
08232         if(varp->type != NC_CHAR)
08233                 return NC_ECHAR;
08234 
08235         maxidim = (int) varp->ndims - 1;
08236 
08237         if (maxidim < 0)
08238         {
08239                 /*
08240                  * The variable is a scalar; consequently,
08241                  * there s only one thing to get and only one place to put it.
08242                  * (Why was I called?)
08243                  */
08244                 return getNCv_text (ncp, varp, start, 1, value);
08245         }
08246         
08247         /*
08248          * else
08249          * The variable is an array.
08250          */
08251         {
08252                 int idim;
08253                 size_t *mystart = NULL;
08254                 size_t *myedges;
08255                 size_t *iocount;        /* count vector */
08256                 size_t *stop;   /* stop indexes */
08257                 size_t *length; /* edge lengths in bytes */
08258                 ptrdiff_t *mystride;
08259                 ptrdiff_t *mymap;
08260 
08261                 /*
08262                  * Verify stride argument.
08263                  */
08264                 for (idim = 0; idim <= maxidim; ++idim)
08265                 {
08266                         if (stride != NULL
08267                                 && (stride[idim] == 0
08268                 /* cast needed for braindead systems with signed size_t */
08269                                 || (unsigned long) stride[idim] >= X_INT_MAX))
08270                         {
08271                                 return NC_ESTRIDE;
08272                         }
08273                 }
08274 
08275                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
08276                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
08277                 if(mystart == NULL)
08278                         return NC_ENOMEM;
08279                 myedges = mystart + varp->ndims;
08280                 iocount = myedges + varp->ndims;
08281                 stop = iocount + varp->ndims;
08282                 length = stop + varp->ndims;
08283                 mystride = (ptrdiff_t *)(length + varp->ndims);
08284                 mymap = mystride + varp->ndims;
08285 
08286                 /*
08287                  * Initialize I/O parameters.
08288                  */
08289                 for (idim = maxidim; idim >= 0; --idim)
08290                 {
08291                         mystart[idim] = start != NULL
08292                                 ? start[idim]
08293                                 : 0;
08294 
08295                         if (edges[idim] == 0)
08296                         {
08297                                 status = NC_NOERR;      /* read/write no data */
08298                                 goto done;
08299                         }
08300 
08301                         myedges[idim] = edges != NULL
08302                                 ? edges[idim]
08303                                 : idim == 0 && IS_RECVAR (varp)
08304                                 ? NC_get_numrecs(ncp) - mystart[idim]
08305                                 : varp->shape[idim] - mystart[idim];
08306                         mystride[idim] = stride != NULL
08307                                 ? stride[idim]
08308                                 : 1;
08309                         mymap[idim] = map != NULL
08310                                 ? map[idim]
08311                                 : idim == maxidim
08312                                 ? 1
08313                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
08314 
08315                         iocount[idim] = 1;
08316                         length[idim] = mymap[idim] * myedges[idim];
08317                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
08318                 }
08319 
08320                 /*
08321                  * Check start, edges
08322                  */
08323                 for (idim = maxidim; idim >= 0; --idim)
08324                 {
08325                         size_t dimlen = 
08326                                 idim == 0 && IS_RECVAR (varp)
08327                                         ? NC_get_numrecs(ncp)
08328                                           : varp->shape[idim];
08329                         if (mystart[idim] >= dimlen)
08330                         {
08331                                 status = NC_EINVALCOORDS;
08332                                 goto done;
08333                         }
08334 
08335                         if (mystart[idim] + myedges[idim] > dimlen)
08336                         {
08337                                 status = NC_EEDGE;
08338                                 goto done;
08339                         }
08340 
08341                 }
08342                 /*
08343                  * As an optimization, adjust I/O parameters when the fastest 
08344                  * dimension has unity stride both externally and internally.
08345                  * In this case, the user could have called a simpler routine
08346                  * (i.e. ncvarnc_get_vara_text()
08347                  */
08348                 if (mystride[maxidim] == 1
08349                         && mymap[maxidim] == 1)
08350                 {
08351                         iocount[maxidim] = myedges[maxidim];
08352                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
08353                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
08354                 }
08355 
08356                 /*
08357                  * Perform I/O.  Exit when done.
08358                  */
08359                 for (;;)
08360                 {
08361                         /* TODO: */
08362                         int lstatus = nc_get_vara_text (ncid, varid, mystart, iocount,
08363                                                 value);
08364                         if (lstatus != NC_NOERR 
08365                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
08366                                 status = lstatus;
08367 
08368                         /*
08369                          * The following code permutes through the variable s
08370                          * external start-index space and it s internal address
08371                          * space.  At the UPC, this algorithm is commonly
08372                          * called "odometer code".
08373                          */
08374                         idim = maxidim;
08375                 carry:
08376                         value += mymap[idim];
08377                         mystart[idim] += mystride[idim];
08378                         if (mystart[idim] == stop[idim])
08379                         {
08380                                 mystart[idim] = start[idim];
08381                                 value -= length[idim];
08382                                 if (--idim < 0)
08383                                         break; /* normal return */
08384                                 goto carry;
08385                         }
08386                 } /* I/O loop */
08387         done:
08388                 free(mystart);
08389         } /* variable is array */
08390         return status;
08391 
08392 }
08393 
08394 
08395 int
08396 nc_get_varm_uchar(int ncid, int varid,
08397         const size_t *start, const size_t *edges,
08398         const ptrdiff_t *stride,
08399         const ptrdiff_t *map,
08400         uchar *value)
08401 {
08402         int status = ENOERR;
08403         NC *ncp;
08404         NC_var *varp;
08405         int maxidim;    /* maximum dimensional index */
08406 
08407         status = NC_check_id (ncid, &ncp);
08408         if (status != NC_NOERR)
08409                 return status;
08410 
08411         if (NC_indef (ncp))
08412         {
08413                 return NC_EINDEFINE;
08414         }
08415 
08416         varp = NC_lookupvar (ncp, varid);
08417         if (varp == NULL)
08418                 return NC_ENOTVAR;
08419 
08420         if(varp->type == NC_CHAR)
08421                 return NC_ECHAR;
08422 
08423         maxidim = (int) varp->ndims - 1;
08424 
08425         if (maxidim < 0)
08426         {
08427                 /*
08428                  * The variable is a scalar; consequently,
08429                  * there s only one thing to get and only one place to put it.
08430                  * (Why was I called?)
08431                  */
08432                 return getNCv_uchar (ncp, varp, start, 1, value);
08433         }
08434         
08435         /*
08436          * else
08437          * The variable is an array.
08438          */
08439         {
08440                 int idim;
08441                 size_t *mystart = NULL;
08442                 size_t *myedges;
08443                 size_t *iocount;        /* count vector */
08444                 size_t *stop;   /* stop indexes */
08445                 size_t *length; /* edge lengths in bytes */
08446                 ptrdiff_t *mystride;
08447                 ptrdiff_t *mymap;
08448 
08449                 /*
08450                  * Verify stride argument.
08451                  */
08452                 for (idim = 0; idim <= maxidim; ++idim)
08453                 {
08454                         if (stride != NULL
08455                                 && (stride[idim] == 0
08456                 /* cast needed for braindead systems with signed size_t */
08457                                 || (unsigned long) stride[idim] >= X_INT_MAX))
08458                         {
08459                                 return NC_ESTRIDE;
08460                         }
08461                 }
08462 
08463                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
08464                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
08465                 if(mystart == NULL)
08466                         return NC_ENOMEM;
08467                 myedges = mystart + varp->ndims;
08468                 iocount = myedges + varp->ndims;
08469                 stop = iocount + varp->ndims;
08470                 length = stop + varp->ndims;
08471                 mystride = (ptrdiff_t *)(length + varp->ndims);
08472                 mymap = mystride + varp->ndims;
08473 
08474                 /*
08475                  * Initialize I/O parameters.
08476                  */
08477                 for (idim = maxidim; idim >= 0; --idim)
08478                 {
08479                         mystart[idim] = start != NULL
08480                                 ? start[idim]
08481                                 : 0;
08482 
08483                         if (edges[idim] == 0)
08484                         {
08485                                 status = NC_NOERR;      /* read/write no data */
08486                                 goto done;
08487                         }
08488 
08489                         myedges[idim] = edges != NULL
08490                                 ? edges[idim]
08491                                 : idim == 0 && IS_RECVAR (varp)
08492                                 ? NC_get_numrecs(ncp) - mystart[idim]
08493                                 : varp->shape[idim] - mystart[idim];
08494                         mystride[idim] = stride != NULL
08495                                 ? stride[idim]
08496                                 : 1;
08497                         mymap[idim] = map != NULL
08498                                 ? map[idim]
08499                                 : idim == maxidim
08500                                 ? 1
08501                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
08502 
08503                         iocount[idim] = 1;
08504                         length[idim] = mymap[idim] * myedges[idim];
08505                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
08506                 }
08507 
08508                 /*
08509                  * Check start, edges
08510                  */
08511                 for (idim = maxidim; idim >= 0; --idim)
08512                 {
08513                         size_t dimlen = 
08514                                 idim == 0 && IS_RECVAR (varp)
08515                                         ? NC_get_numrecs(ncp)
08516                                           : varp->shape[idim];
08517                         if (mystart[idim] >= dimlen)
08518                         {
08519                                 status = NC_EINVALCOORDS;
08520                                 goto done;
08521                         }
08522 
08523                         if (mystart[idim] + myedges[idim] > dimlen)
08524                         {
08525                                 status = NC_EEDGE;
08526                                 goto done;
08527                         }
08528 
08529                 }
08530                 /*
08531                  * As an optimization, adjust I/O parameters when the fastest 
08532                  * dimension has unity stride both externally and internally.
08533                  * In this case, the user could have called a simpler routine
08534                  * (i.e. ncvarnc_get_vara_uchar()
08535                  */
08536                 if (mystride[maxidim] == 1
08537                         && mymap[maxidim] == 1)
08538                 {
08539                         iocount[maxidim] = myedges[maxidim];
08540                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
08541                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
08542                 }
08543 
08544                 /*
08545                  * Perform I/O.  Exit when done.
08546                  */
08547                 for (;;)
08548                 {
08549                         /* TODO: */
08550                         int lstatus = nc_get_vara_uchar (ncid, varid, mystart, iocount,
08551                                                 value);
08552                         if (lstatus != NC_NOERR 
08553                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
08554                                 status = lstatus;
08555 
08556                         /*
08557                          * The following code permutes through the variable s
08558                          * external start-index space and it s internal address
08559                          * space.  At the UPC, this algorithm is commonly
08560                          * called "odometer code".
08561                          */
08562                         idim = maxidim;
08563                 carry:
08564                         value += mymap[idim];
08565                         mystart[idim] += mystride[idim];
08566                         if (mystart[idim] == stop[idim])
08567                         {
08568                                 mystart[idim] = start[idim];
08569                                 value -= length[idim];
08570                                 if (--idim < 0)
08571                                         break; /* normal return */
08572                                 goto carry;
08573                         }
08574                 } /* I/O loop */
08575         done:
08576                 free(mystart);
08577         } /* variable is array */
08578         return status;
08579 
08580 }
08581 
08582 int
08583 nc_get_varm_schar(int ncid, int varid,
08584         const size_t *start, const size_t *edges,
08585         const ptrdiff_t *stride,
08586         const ptrdiff_t *map,
08587         schar *value)
08588 {
08589         int status = ENOERR;
08590         NC *ncp;
08591         NC_var *varp;
08592         int maxidim;    /* maximum dimensional index */
08593 
08594         status = NC_check_id (ncid, &ncp);
08595         if (status != NC_NOERR)
08596                 return status;
08597 
08598         if (NC_indef (ncp))
08599         {
08600                 return NC_EINDEFINE;
08601         }
08602 
08603         varp = NC_lookupvar (ncp, varid);
08604         if (varp == NULL)
08605                 return NC_ENOTVAR;
08606 
08607         if(varp->type == NC_CHAR)
08608                 return NC_ECHAR;
08609 
08610         maxidim = (int) varp->ndims - 1;
08611 
08612         if (maxidim < 0)
08613         {
08614                 /*
08615                  * The variable is a scalar; consequently,
08616                  * there s only one thing to get and only one place to put it.
08617                  * (Why was I called?)
08618                  */
08619                 return getNCv_schar (ncp, varp, start, 1, value);
08620         }
08621         
08622         /*
08623          * else
08624          * The variable is an array.
08625          */
08626         {
08627                 int idim;
08628                 size_t *mystart = NULL;
08629                 size_t *myedges;
08630                 size_t *iocount;        /* count vector */
08631                 size_t *stop;   /* stop indexes */
08632                 size_t *length; /* edge lengths in bytes */
08633                 ptrdiff_t *mystride;
08634                 ptrdiff_t *mymap;
08635 
08636                 /*
08637                  * Verify stride argument.
08638                  */
08639                 for (idim = 0; idim <= maxidim; ++idim)
08640                 {
08641                         if (stride != NULL
08642                                 && (stride[idim] == 0
08643                 /* cast needed for braindead systems with signed size_t */
08644                                 || (unsigned long) stride[idim] >= X_INT_MAX))
08645                         {
08646                                 return NC_ESTRIDE;
08647                         }
08648                 }
08649 
08650                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
08651                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
08652                 if(mystart == NULL)
08653                         return NC_ENOMEM;
08654                 myedges = mystart + varp->ndims;
08655                 iocount = myedges + varp->ndims;
08656                 stop = iocount + varp->ndims;
08657                 length = stop + varp->ndims;
08658                 mystride = (ptrdiff_t *)(length + varp->ndims);
08659                 mymap = mystride + varp->ndims;
08660 
08661                 /*
08662                  * Initialize I/O parameters.
08663                  */
08664                 for (idim = maxidim; idim >= 0; --idim)
08665                 {
08666                         mystart[idim] = start != NULL
08667                                 ? start[idim]
08668                                 : 0;
08669 
08670                         if (edges[idim] == 0)
08671                         {
08672                                 status = NC_NOERR;      /* read/write no data */
08673                                 goto done;
08674                         }
08675 
08676                         myedges[idim] = edges != NULL
08677                                 ? edges[idim]
08678                                 : idim == 0 && IS_RECVAR (varp)
08679                                 ? NC_get_numrecs(ncp) - mystart[idim]
08680                                 : varp->shape[idim] - mystart[idim];
08681                         mystride[idim] = stride != NULL
08682                                 ? stride[idim]
08683                                 : 1;
08684                         mymap[idim] = map != NULL
08685                                 ? map[idim]
08686                                 : idim == maxidim
08687                                 ? 1
08688                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
08689 
08690                         iocount[idim] = 1;
08691                         length[idim] = mymap[idim] * myedges[idim];
08692                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
08693                 }
08694 
08695                 /*
08696                  * Check start, edges
08697                  */
08698                 for (idim = maxidim; idim >= 0; --idim)
08699                 {
08700                         size_t dimlen = 
08701                                 idim == 0 && IS_RECVAR (varp)
08702                                         ? NC_get_numrecs(ncp)
08703                                           : varp->shape[idim];
08704                         if (mystart[idim] >= dimlen)
08705                         {
08706                                 status = NC_EINVALCOORDS;
08707                                 goto done;
08708                         }
08709 
08710                         if (mystart[idim] + myedges[idim] > dimlen)
08711                         {
08712                                 status = NC_EEDGE;
08713                                 goto done;
08714                         }
08715 
08716                 }
08717                 /*
08718                  * As an optimization, adjust I/O parameters when the fastest 
08719                  * dimension has unity stride both externally and internally.
08720                  * In this case, the user could have called a simpler routine
08721                  * (i.e. ncvarnc_get_vara_schar()
08722                  */
08723                 if (mystride[maxidim] == 1
08724                         && mymap[maxidim] == 1)
08725                 {
08726                         iocount[maxidim] = myedges[maxidim];
08727                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
08728                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
08729                 }
08730 
08731                 /*
08732                  * Perform I/O.  Exit when done.
08733                  */
08734                 for (;;)
08735                 {
08736                         /* TODO: */
08737                         int lstatus = nc_get_vara_schar (ncid, varid, mystart, iocount,
08738                                                 value);
08739                         if (lstatus != NC_NOERR 
08740                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
08741                                 status = lstatus;
08742 
08743                         /*
08744                          * The following code permutes through the variable s
08745                          * external start-index space and it s internal address
08746                          * space.  At the UPC, this algorithm is commonly
08747                          * called "odometer code".
08748                          */
08749                         idim = maxidim;
08750                 carry:
08751                         value += mymap[idim];
08752                         mystart[idim] += mystride[idim];
08753                         if (mystart[idim] == stop[idim])
08754                         {
08755                                 mystart[idim] = start[idim];
08756                                 value -= length[idim];
08757                                 if (--idim < 0)
08758                                         break; /* normal return */
08759                                 goto carry;
08760                         }
08761                 } /* I/O loop */
08762         done:
08763                 free(mystart);
08764         } /* variable is array */
08765         return status;
08766 
08767 }
08768 
08769 int
08770 nc_get_varm_short(int ncid, int varid,
08771         const size_t *start, const size_t *edges,
08772         const ptrdiff_t *stride,
08773         const ptrdiff_t *map,
08774         short *value)
08775 {
08776         int status = ENOERR;
08777         NC *ncp;
08778         NC_var *varp;
08779         int maxidim;    /* maximum dimensional index */
08780 
08781         status = NC_check_id (ncid, &ncp);
08782         if (status != NC_NOERR)
08783                 return status;
08784 
08785         if (NC_indef (ncp))
08786         {
08787                 return NC_EINDEFINE;
08788         }
08789 
08790         varp = NC_lookupvar (ncp, varid);
08791         if (varp == NULL)
08792                 return NC_ENOTVAR;
08793 
08794         if(varp->type == NC_CHAR)
08795                 return NC_ECHAR;
08796 
08797         maxidim = (int) varp->ndims - 1;
08798 
08799         if (maxidim < 0)
08800         {
08801                 /*
08802                  * The variable is a scalar; consequently,
08803                  * there s only one thing to get and only one place to put it.
08804                  * (Why was I called?)
08805                  */
08806                 return getNCv_short (ncp, varp, start, 1, value);
08807         }
08808         
08809         /*
08810          * else
08811          * The variable is an array.
08812          */
08813         {
08814                 int idim;
08815                 size_t *mystart = NULL;
08816                 size_t *myedges;
08817                 size_t *iocount;        /* count vector */
08818                 size_t *stop;   /* stop indexes */
08819                 size_t *length; /* edge lengths in bytes */
08820                 ptrdiff_t *mystride;
08821                 ptrdiff_t *mymap;
08822 
08823                 /*
08824                  * Verify stride argument.
08825                  */
08826                 for (idim = 0; idim <= maxidim; ++idim)
08827                 {
08828                         if (stride != NULL
08829                                 && (stride[idim] == 0
08830                 /* cast needed for braindead systems with signed size_t */
08831                                 || (unsigned long) stride[idim] >= X_INT_MAX))
08832                         {
08833                                 return NC_ESTRIDE;
08834                         }
08835                 }
08836 
08837                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
08838                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
08839                 if(mystart == NULL)
08840                         return NC_ENOMEM;
08841                 myedges = mystart + varp->ndims;
08842                 iocount = myedges + varp->ndims;
08843                 stop = iocount + varp->ndims;
08844                 length = stop + varp->ndims;
08845                 mystride = (ptrdiff_t *)(length + varp->ndims);
08846                 mymap = mystride + varp->ndims;
08847 
08848                 /*
08849                  * Initialize I/O parameters.
08850                  */
08851                 for (idim = maxidim; idim >= 0; --idim)
08852                 {
08853                         mystart[idim] = start != NULL
08854                                 ? start[idim]
08855                                 : 0;
08856 
08857                         if (edges[idim] == 0)
08858                         {
08859                                 status = NC_NOERR;      /* read/write no data */
08860                                 goto done;
08861                         }
08862 
08863                         myedges[idim] = edges != NULL
08864                                 ? edges[idim]
08865                                 : idim == 0 && IS_RECVAR (varp)
08866                                 ? NC_get_numrecs(ncp) - mystart[idim]
08867                                 : varp->shape[idim] - mystart[idim];
08868                         mystride[idim] = stride != NULL
08869                                 ? stride[idim]
08870                                 : 1;
08871                         mymap[idim] = map != NULL
08872                                 ? map[idim]
08873                                 : idim == maxidim
08874                                 ? 1
08875                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
08876 
08877                         iocount[idim] = 1;
08878                         length[idim] = mymap[idim] * myedges[idim];
08879                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
08880                 }
08881 
08882                 /*
08883                  * Check start, edges
08884                  */
08885                 for (idim = maxidim; idim >= 0; --idim)
08886                 {
08887                         size_t dimlen = 
08888                                 idim == 0 && IS_RECVAR (varp)
08889                                         ? NC_get_numrecs(ncp)
08890                                           : varp->shape[idim];
08891                         if (mystart[idim] >= dimlen)
08892                         {
08893                                 status = NC_EINVALCOORDS;
08894                                 goto done;
08895                         }
08896 
08897                         if (mystart[idim] + myedges[idim] > dimlen)
08898                         {
08899                                 status = NC_EEDGE;
08900                                 goto done;
08901                         }
08902 
08903                 }
08904                 /*
08905                  * As an optimization, adjust I/O parameters when the fastest 
08906                  * dimension has unity stride both externally and internally.
08907                  * In this case, the user could have called a simpler routine
08908                  * (i.e. ncvarnc_get_vara_short()
08909                  */
08910                 if (mystride[maxidim] == 1
08911                         && mymap[maxidim] == 1)
08912                 {
08913                         iocount[maxidim] = myedges[maxidim];
08914                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
08915                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
08916                 }
08917 
08918                 /*
08919                  * Perform I/O.  Exit when done.
08920                  */
08921                 for (;;)
08922                 {
08923                         /* TODO: */
08924                         int lstatus = nc_get_vara_short (ncid, varid, mystart, iocount,
08925                                                 value);
08926                         if (lstatus != NC_NOERR 
08927                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
08928                                 status = lstatus;
08929 
08930                         /*
08931                          * The following code permutes through the variable s
08932                          * external start-index space and it s internal address
08933                          * space.  At the UPC, this algorithm is commonly
08934                          * called "odometer code".
08935                          */
08936                         idim = maxidim;
08937                 carry:
08938                         value += mymap[idim];
08939                         mystart[idim] += mystride[idim];
08940                         if (mystart[idim] == stop[idim])
08941                         {
08942                                 mystart[idim] = start[idim];
08943                                 value -= length[idim];
08944                                 if (--idim < 0)
08945                                         break; /* normal return */
08946                                 goto carry;
08947                         }
08948                 } /* I/O loop */
08949         done:
08950                 free(mystart);
08951         } /* variable is array */
08952         return status;
08953 
08954 }
08955 
08956 int
08957 nc_get_varm_int(int ncid, int varid,
08958         const size_t *start, const size_t *edges,
08959         const ptrdiff_t *stride,
08960         const ptrdiff_t *map,
08961         int *value)
08962 {
08963         int status = ENOERR;
08964         NC *ncp;
08965         NC_var *varp;
08966         int maxidim;    /* maximum dimensional index */
08967 
08968         status = NC_check_id (ncid, &ncp);
08969         if (status != NC_NOERR)
08970                 return status;
08971 
08972         if (NC_indef (ncp))
08973         {
08974                 return NC_EINDEFINE;
08975         }
08976 
08977         varp = NC_lookupvar (ncp, varid);
08978         if (varp == NULL)
08979                 return NC_ENOTVAR;
08980 
08981         if(varp->type == NC_CHAR)
08982                 return NC_ECHAR;
08983 
08984         maxidim = (int) varp->ndims - 1;
08985 
08986         if (maxidim < 0)
08987         {
08988                 /*
08989                  * The variable is a scalar; consequently,
08990                  * there s only one thing to get and only one place to put it.
08991                  * (Why was I called?)
08992                  */
08993                 return getNCv_int (ncp, varp, start, 1, value);
08994         }
08995         
08996         /*
08997          * else
08998          * The variable is an array.
08999          */
09000         {
09001                 int idim;
09002                 size_t *mystart = NULL;
09003                 size_t *myedges;
09004                 size_t *iocount;        /* count vector */
09005                 size_t *stop;   /* stop indexes */
09006                 size_t *length; /* edge lengths in bytes */
09007                 ptrdiff_t *mystride;
09008                 ptrdiff_t *mymap;
09009 
09010                 /*
09011                  * Verify stride argument.
09012                  */
09013                 for (idim = 0; idim <= maxidim; ++idim)
09014                 {
09015                         if (stride != NULL
09016                                 && (stride[idim] == 0
09017                 /* cast needed for braindead systems with signed size_t */
09018                                 || (unsigned long) stride[idim] >= X_INT_MAX))
09019                         {
09020                                 return NC_ESTRIDE;
09021                         }
09022                 }
09023 
09024                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
09025                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
09026                 if(mystart == NULL)
09027                         return NC_ENOMEM;
09028                 myedges = mystart + varp->ndims;
09029                 iocount = myedges + varp->ndims;
09030                 stop = iocount + varp->ndims;
09031                 length = stop + varp->ndims;
09032                 mystride = (ptrdiff_t *)(length + varp->ndims);
09033                 mymap = mystride + varp->ndims;
09034 
09035                 /*
09036                  * Initialize I/O parameters.
09037                  */
09038                 for (idim = maxidim; idim >= 0; --idim)
09039                 {
09040                         mystart[idim] = start != NULL
09041                                 ? start[idim]
09042                                 : 0;
09043 
09044                         if (edges[idim] == 0)
09045                         {
09046                                 status = NC_NOERR;      /* read/write no data */
09047                                 goto done;
09048                         }
09049 
09050                         myedges[idim] = edges != NULL
09051                                 ? edges[idim]
09052                                 : idim == 0 && IS_RECVAR (varp)
09053                                 ? NC_get_numrecs(ncp) - mystart[idim]
09054                                 : varp->shape[idim] - mystart[idim];
09055                         mystride[idim] = stride != NULL
09056                                 ? stride[idim]
09057                                 : 1;
09058                         mymap[idim] = map != NULL
09059                                 ? map[idim]
09060                                 : idim == maxidim
09061                                 ? 1
09062                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
09063 
09064                         iocount[idim] = 1;
09065                         length[idim] = mymap[idim] * myedges[idim];
09066                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
09067                 }
09068 
09069                 /*
09070                  * Check start, edges
09071                  */
09072                 for (idim = maxidim; idim >= 0; --idim)
09073                 {
09074                         size_t dimlen = 
09075                                 idim == 0 && IS_RECVAR (varp)
09076                                         ? NC_get_numrecs(ncp)
09077                                           : varp->shape[idim];
09078                         if (mystart[idim] >= dimlen)
09079                         {
09080                                 status = NC_EINVALCOORDS;
09081                                 goto done;
09082                         }
09083 
09084                         if (mystart[idim] + myedges[idim] > dimlen)
09085                         {
09086                                 status = NC_EEDGE;
09087                                 goto done;
09088                         }
09089 
09090                 }
09091                 /*
09092                  * As an optimization, adjust I/O parameters when the fastest 
09093                  * dimension has unity stride both externally and internally.
09094                  * In this case, the user could have called a simpler routine
09095                  * (i.e. ncvarnc_get_vara_int()
09096                  */
09097                 if (mystride[maxidim] == 1
09098                         && mymap[maxidim] == 1)
09099                 {
09100                         iocount[maxidim] = myedges[maxidim];
09101                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
09102                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
09103                 }
09104 
09105                 /*
09106                  * Perform I/O.  Exit when done.
09107                  */
09108                 for (;;)
09109                 {
09110                         /* TODO: */
09111                         int lstatus = nc_get_vara_int (ncid, varid, mystart, iocount,
09112                                                 value);
09113                         if (lstatus != NC_NOERR 
09114                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
09115                                 status = lstatus;
09116 
09117                         /*
09118                          * The following code permutes through the variable s
09119                          * external start-index space and it s internal address
09120                          * space.  At the UPC, this algorithm is commonly
09121                          * called "odometer code".
09122                          */
09123                         idim = maxidim;
09124                 carry:
09125                         value += mymap[idim];
09126                         mystart[idim] += mystride[idim];
09127                         if (mystart[idim] == stop[idim])
09128                         {
09129                                 mystart[idim] = start[idim];
09130                                 value -= length[idim];
09131                                 if (--idim < 0)
09132                                         break; /* normal return */
09133                                 goto carry;
09134                         }
09135                 } /* I/O loop */
09136         done:
09137                 free(mystart);
09138         } /* variable is array */
09139         return status;
09140 
09141 }
09142 
09143 int
09144 nc_get_varm_long(int ncid, int varid,
09145         const size_t *start, const size_t *edges,
09146         const ptrdiff_t *stride,
09147         const ptrdiff_t *map,
09148         long *value)
09149 {
09150         int status = ENOERR;
09151         NC *ncp;
09152         NC_var *varp;
09153         int maxidim;    /* maximum dimensional index */
09154 
09155         status = NC_check_id (ncid, &ncp);
09156         if (status != NC_NOERR)
09157                 return status;
09158 
09159         if (NC_indef (ncp))
09160         {
09161                 return NC_EINDEFINE;
09162         }
09163 
09164         varp = NC_lookupvar (ncp, varid);
09165         if (varp == NULL)
09166                 return NC_ENOTVAR;
09167 
09168         if(varp->type == NC_CHAR)
09169                 return NC_ECHAR;
09170 
09171         maxidim = (int) varp->ndims - 1;
09172 
09173         if (maxidim < 0)
09174         {
09175                 /*
09176                  * The variable is a scalar; consequently,
09177                  * there s only one thing to get and only one place to put it.
09178                  * (Why was I called?)
09179                  */
09180                 return getNCv_long (ncp, varp, start, 1, value);
09181         }
09182         
09183         /*
09184          * else
09185          * The variable is an array.
09186          */
09187         {
09188                 int idim;
09189                 size_t *mystart = NULL;
09190                 size_t *myedges;
09191                 size_t *iocount;        /* count vector */
09192                 size_t *stop;   /* stop indexes */
09193                 size_t *length; /* edge lengths in bytes */
09194                 ptrdiff_t *mystride;
09195                 ptrdiff_t *mymap;
09196 
09197                 /*
09198                  * Verify stride argument.
09199                  */
09200                 for (idim = 0; idim <= maxidim; ++idim)
09201                 {
09202                         if (stride != NULL
09203                                 && (stride[idim] == 0
09204                 /* cast needed for braindead systems with signed size_t */
09205                                 || (unsigned long) stride[idim] >= X_INT_MAX))
09206                         {
09207                                 return NC_ESTRIDE;
09208                         }
09209                 }
09210 
09211                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
09212                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
09213                 if(mystart == NULL)
09214                         return NC_ENOMEM;
09215                 myedges = mystart + varp->ndims;
09216                 iocount = myedges + varp->ndims;
09217                 stop = iocount + varp->ndims;
09218                 length = stop + varp->ndims;
09219                 mystride = (ptrdiff_t *)(length + varp->ndims);
09220                 mymap = mystride + varp->ndims;
09221 
09222                 /*
09223                  * Initialize I/O parameters.
09224                  */
09225                 for (idim = maxidim; idim >= 0; --idim)
09226                 {
09227                         mystart[idim] = start != NULL
09228                                 ? start[idim]
09229                                 : 0;
09230 
09231                         if (edges[idim] == 0)
09232                         {
09233                                 status = NC_NOERR;      /* read/write no data */
09234                                 goto done;
09235                         }
09236 
09237                         myedges[idim] = edges != NULL
09238                                 ? edges[idim]
09239                                 : idim == 0 && IS_RECVAR (varp)
09240                                 ? NC_get_numrecs(ncp) - mystart[idim]
09241                                 : varp->shape[idim] - mystart[idim];
09242                         mystride[idim] = stride != NULL
09243                                 ? stride[idim]
09244                                 : 1;
09245                         mymap[idim] = map != NULL
09246                                 ? map[idim]
09247                                 : idim == maxidim
09248                                 ? 1
09249                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
09250 
09251                         iocount[idim] = 1;
09252                         length[idim] = mymap[idim] * myedges[idim];
09253                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
09254                 }
09255 
09256                 /*
09257                  * Check start, edges
09258                  */
09259                 for (idim = maxidim; idim >= 0; --idim)
09260                 {
09261                         size_t dimlen = 
09262                                 idim == 0 && IS_RECVAR (varp)
09263                                         ? NC_get_numrecs(ncp)
09264                                           : varp->shape[idim];
09265                         if (mystart[idim] >= dimlen)
09266                         {
09267                                 status = NC_EINVALCOORDS;
09268                                 goto done;
09269                         }
09270 
09271                         if (mystart[idim] + myedges[idim] > dimlen)
09272                         {
09273                                 status = NC_EEDGE;
09274                                 goto done;
09275                         }
09276 
09277                 }
09278                 /*
09279                  * As an optimization, adjust I/O parameters when the fastest 
09280                  * dimension has unity stride both externally and internally.
09281                  * In this case, the user could have called a simpler routine
09282                  * (i.e. ncvarnc_get_vara_long()
09283                  */
09284                 if (mystride[maxidim] == 1
09285                         && mymap[maxidim] == 1)
09286                 {
09287                         iocount[maxidim] = myedges[maxidim];
09288                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
09289                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
09290                 }
09291 
09292                 /*
09293                  * Perform I/O.  Exit when done.
09294                  */
09295                 for (;;)
09296                 {
09297                         /* TODO: */
09298                         int lstatus = nc_get_vara_long (ncid, varid, mystart, iocount,
09299                                                 value);
09300                         if (lstatus != NC_NOERR 
09301                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
09302                                 status = lstatus;
09303 
09304                         /*
09305                          * The following code permutes through the variable s
09306                          * external start-index space and it s internal address
09307                          * space.  At the UPC, this algorithm is commonly
09308                          * called "odometer code".
09309                          */
09310                         idim = maxidim;
09311                 carry:
09312                         value += mymap[idim];
09313                         mystart[idim] += mystride[idim];
09314                         if (mystart[idim] == stop[idim])
09315                         {
09316                                 mystart[idim] = start[idim];
09317                                 value -= length[idim];
09318                                 if (--idim < 0)
09319                                         break; /* normal return */
09320                                 goto carry;
09321                         }
09322                 } /* I/O loop */
09323         done:
09324                 free(mystart);
09325         } /* variable is array */
09326         return status;
09327 
09328 }
09329 
09330 int
09331 nc_get_varm_float(int ncid, int varid,
09332         const size_t *start, const size_t *edges,
09333         const ptrdiff_t *stride,
09334         const ptrdiff_t *map,
09335         float *value)
09336 {
09337         int status = ENOERR;
09338         NC *ncp;
09339         NC_var *varp;
09340         int maxidim;    /* maximum dimensional index */
09341 
09342         status = NC_check_id (ncid, &ncp);
09343         if (status != NC_NOERR)
09344                 return status;
09345 
09346         if (NC_indef (ncp))
09347         {
09348                 return NC_EINDEFINE;
09349         }
09350 
09351         varp = NC_lookupvar (ncp, varid);
09352         if (varp == NULL)
09353                 return NC_ENOTVAR;
09354 
09355         if(varp->type == NC_CHAR)
09356                 return NC_ECHAR;
09357 
09358         maxidim = (int) varp->ndims - 1;
09359 
09360         if (maxidim < 0)
09361         {
09362                 /*
09363                  * The variable is a scalar; consequently,
09364                  * there s only one thing to get and only one place to put it.
09365                  * (Why was I called?)
09366                  */
09367                 return getNCv_float (ncp, varp, start, 1, value);
09368         }
09369         
09370         /*
09371          * else
09372          * The variable is an array.
09373          */
09374         {
09375                 int idim;
09376                 size_t *mystart = NULL;
09377                 size_t *myedges;
09378                 size_t *iocount;        /* count vector */
09379                 size_t *stop;   /* stop indexes */
09380                 size_t *length; /* edge lengths in bytes */
09381                 ptrdiff_t *mystride;
09382                 ptrdiff_t *mymap;
09383 
09384                 /*
09385                  * Verify stride argument.
09386                  */
09387                 for (idim = 0; idim <= maxidim; ++idim)
09388                 {
09389                         if (stride != NULL
09390                                 && (stride[idim] == 0
09391                 /* cast needed for braindead systems with signed size_t */
09392                                 || (unsigned long) stride[idim] >= X_INT_MAX))
09393                         {
09394                                 return NC_ESTRIDE;
09395                         }
09396                 }
09397 
09398                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
09399                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
09400                 if(mystart == NULL)
09401                         return NC_ENOMEM;
09402                 myedges = mystart + varp->ndims;
09403                 iocount = myedges + varp->ndims;
09404                 stop = iocount + varp->ndims;
09405                 length = stop + varp->ndims;
09406                 mystride = (ptrdiff_t *)(length + varp->ndims);
09407                 mymap = mystride + varp->ndims;
09408 
09409                 /*
09410                  * Initialize I/O parameters.
09411                  */
09412                 for (idim = maxidim; idim >= 0; --idim)
09413                 {
09414                         mystart[idim] = start != NULL
09415                                 ? start[idim]
09416                                 : 0;
09417 
09418                         if (edges[idim] == 0)
09419                         {
09420                                 status = NC_NOERR;      /* read/write no data */
09421                                 goto done;
09422                         }
09423 
09424                         myedges[idim] = edges != NULL
09425                                 ? edges[idim]
09426                                 : idim == 0 && IS_RECVAR (varp)
09427                                 ? NC_get_numrecs(ncp) - mystart[idim]
09428                                 : varp->shape[idim] - mystart[idim];
09429                         mystride[idim] = stride != NULL
09430                                 ? stride[idim]
09431                                 : 1;
09432                         mymap[idim] = map != NULL
09433                                 ? map[idim]
09434                                 : idim == maxidim
09435                                 ? 1
09436                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
09437 
09438                         iocount[idim] = 1;
09439                         length[idim] = mymap[idim] * myedges[idim];
09440                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
09441                 }
09442 
09443                 /*
09444                  * Check start, edges
09445                  */
09446                 for (idim = maxidim; idim >= 0; --idim)
09447                 {
09448                         size_t dimlen = 
09449                                 idim == 0 && IS_RECVAR (varp)
09450                                         ? NC_get_numrecs(ncp)
09451                                           : varp->shape[idim];
09452                         if (mystart[idim] >= dimlen)
09453                         {
09454                                 status = NC_EINVALCOORDS;
09455                                 goto done;
09456                         }
09457 
09458                         if (mystart[idim] + myedges[idim] > dimlen)
09459                         {
09460                                 status = NC_EEDGE;
09461                                 goto done;
09462                         }
09463 
09464                 }
09465                 /*
09466                  * As an optimization, adjust I/O parameters when the fastest 
09467                  * dimension has unity stride both externally and internally.
09468                  * In this case, the user could have called a simpler routine
09469                  * (i.e. ncvarnc_get_vara_float()
09470                  */
09471                 if (mystride[maxidim] == 1
09472                         && mymap[maxidim] == 1)
09473                 {
09474                         iocount[maxidim] = myedges[maxidim];
09475                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
09476                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
09477                 }
09478 
09479                 /*
09480                  * Perform I/O.  Exit when done.
09481                  */
09482                 for (;;)
09483                 {
09484                         /* TODO: */
09485                         int lstatus = nc_get_vara_float (ncid, varid, mystart, iocount,
09486                                                 value);
09487                         if (lstatus != NC_NOERR 
09488                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
09489                                 status = lstatus;
09490 
09491                         /*
09492                          * The following code permutes through the variable s
09493                          * external start-index space and it s internal address
09494                          * space.  At the UPC, this algorithm is commonly
09495                          * called "odometer code".
09496                          */
09497                         idim = maxidim;
09498                 carry:
09499                         value += mymap[idim];
09500                         mystart[idim] += mystride[idim];
09501                         if (mystart[idim] == stop[idim])
09502                         {
09503                                 mystart[idim] = start[idim];
09504                                 value -= length[idim];
09505                                 if (--idim < 0)
09506                                         break; /* normal return */
09507                                 goto carry;
09508                         }
09509                 } /* I/O loop */
09510         done:
09511                 free(mystart);
09512         } /* variable is array */
09513         return status;
09514 
09515 }
09516 
09517 int
09518 nc_get_varm_double(int ncid, int varid,
09519         const size_t *start, const size_t *edges,
09520         const ptrdiff_t *stride,
09521         const ptrdiff_t *map,
09522         double *value)
09523 {
09524         int status = ENOERR;
09525         NC *ncp;
09526         NC_var *varp;
09527         int maxidim;    /* maximum dimensional index */
09528 
09529         status = NC_check_id (ncid, &ncp);
09530         if (status != NC_NOERR)
09531                 return status;
09532 
09533         if (NC_indef (ncp))
09534         {
09535                 return NC_EINDEFINE;
09536         }
09537 
09538         varp = NC_lookupvar (ncp, varid);
09539         if (varp == NULL)
09540                 return NC_ENOTVAR;
09541 
09542         if(varp->type == NC_CHAR)
09543                 return NC_ECHAR;
09544 
09545         maxidim = (int) varp->ndims - 1;
09546 
09547         if (maxidim < 0)
09548         {
09549                 /*
09550                  * The variable is a scalar; consequently,
09551                  * there s only one thing to get and only one place to put it.
09552                  * (Why was I called?)
09553                  */
09554                 return getNCv_double (ncp, varp, start, 1, value);
09555         }
09556         
09557         /*
09558          * else
09559          * The variable is an array.
09560          */
09561         {
09562                 int idim;
09563                 size_t *mystart = NULL;
09564                 size_t *myedges;
09565                 size_t *iocount;        /* count vector */
09566                 size_t *stop;   /* stop indexes */
09567                 size_t *length; /* edge lengths in bytes */
09568                 ptrdiff_t *mystride;
09569                 ptrdiff_t *mymap;
09570 
09571                 /*
09572                  * Verify stride argument.
09573                  */
09574                 for (idim = 0; idim <= maxidim; ++idim)
09575                 {
09576                         if (stride != NULL
09577                                 && (stride[idim] == 0
09578                 /* cast needed for braindead systems with signed size_t */
09579                                 || (unsigned long) stride[idim] >= X_INT_MAX))
09580                         {
09581                                 return NC_ESTRIDE;
09582                         }
09583                 }
09584 
09585                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
09586                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
09587                 if(mystart == NULL)
09588                         return NC_ENOMEM;
09589                 myedges = mystart + varp->ndims;
09590                 iocount = myedges + varp->ndims;
09591                 stop = iocount + varp->ndims;
09592                 length = stop + varp->ndims;
09593                 mystride = (ptrdiff_t *)(length + varp->ndims);
09594                 mymap = mystride + varp->ndims;
09595 
09596                 /*
09597                  * Initialize I/O parameters.
09598                  */
09599                 for (idim = maxidim; idim >= 0; --idim)
09600                 {
09601                         mystart[idim] = start != NULL
09602                                 ? start[idim]
09603                                 : 0;
09604 
09605                         if (edges[idim] == 0)
09606                         {
09607                                 status = NC_NOERR;      /* read/write no data */
09608                                 goto done;
09609                         }
09610 
09611                         myedges[idim] = edges != NULL
09612                                 ? edges[idim]
09613                                 : idim == 0 && IS_RECVAR (varp)
09614                                 ? NC_get_numrecs(ncp) - mystart[idim]
09615                                 : varp->shape[idim] - mystart[idim];
09616                         mystride[idim] = stride != NULL
09617                                 ? stride[idim]
09618                                 : 1;
09619                         mymap[idim] = map != NULL
09620                                 ? map[idim]
09621                                 : idim == maxidim
09622                                 ? 1
09623                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
09624 
09625                         iocount[idim] = 1;
09626                         length[idim] = mymap[idim] * myedges[idim];
09627                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
09628                 }
09629 
09630                 /*
09631                  * Check start, edges
09632                  */
09633                 for (idim = maxidim; idim >= 0; --idim)
09634                 {
09635                         size_t dimlen = 
09636                                 idim == 0 && IS_RECVAR (varp)
09637                                         ? NC_get_numrecs(ncp)
09638                                           : varp->shape[idim];
09639                         if (mystart[idim] >= dimlen)
09640                         {
09641                                 status = NC_EINVALCOORDS;
09642                                 goto done;
09643                         }
09644 
09645                         if (mystart[idim] + myedges[idim] > dimlen)
09646                         {
09647                                 status = NC_EEDGE;
09648                                 goto done;
09649                         }
09650 
09651                 }
09652                 /*
09653                  * As an optimization, adjust I/O parameters when the fastest 
09654                  * dimension has unity stride both externally and internally.
09655                  * In this case, the user could have called a simpler routine
09656                  * (i.e. ncvarnc_get_vara_double()
09657                  */
09658                 if (mystride[maxidim] == 1
09659                         && mymap[maxidim] == 1)
09660                 {
09661                         iocount[maxidim] = myedges[maxidim];
09662                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
09663                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
09664                 }
09665 
09666                 /*
09667                  * Perform I/O.  Exit when done.
09668                  */
09669                 for (;;)
09670                 {
09671                         /* TODO: */
09672                         int lstatus = nc_get_vara_double (ncid, varid, mystart, iocount,
09673                                                 value);
09674                         if (lstatus != NC_NOERR 
09675                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
09676                                 status = lstatus;
09677 
09678                         /*
09679                          * The following code permutes through the variable s
09680                          * external start-index space and it s internal address
09681                          * space.  At the UPC, this algorithm is commonly
09682                          * called "odometer code".
09683                          */
09684                         idim = maxidim;
09685                 carry:
09686                         value += mymap[idim];
09687                         mystart[idim] += mystride[idim];
09688                         if (mystart[idim] == stop[idim])
09689                         {
09690                                 mystart[idim] = start[idim];
09691                                 value -= length[idim];
09692                                 if (--idim < 0)
09693                                         break; /* normal return */
09694                                 goto carry;
09695                         }
09696                 } /* I/O loop */
09697         done:
09698                 free(mystart);
09699         } /* variable is array */
09700         return status;
09701 
09702 }
09703 
09704 
09705 /* deprecated, used to support the 2.x interface */
09706 int
09707 nc_get_varm (
09708         int ncid,
09709         int varid,
09710         const size_t * start,
09711         const size_t * edges,
09712         const ptrdiff_t * stride,
09713         const ptrdiff_t * map,
09714         void *value)
09715 {
09716         int status;
09717         NC *ncp;
09718         const NC_var *varp;
09719         ptrdiff_t *cvtmap = NULL;
09720 
09721         status = NC_check_id(ncid, &ncp); 
09722         if(status != NC_NOERR)
09723                 return status;
09724 
09725         varp = NC_lookupvar(ncp, varid);
09726         if(varp == NULL)
09727                 return NC_ENOTVAR;
09728 
09729         if(map != NULL && varp->ndims != 0)
09730         {
09731                 /*
09732                  * convert map units from bytes to units of sizeof(type)
09733                  */
09734                 size_t ii;
09735                 const ptrdiff_t szof = (ptrdiff_t) nctypelen(varp->type);
09736                 cvtmap = (ptrdiff_t *)calloc(varp->ndims, sizeof(ptrdiff_t));
09737                 if(cvtmap == NULL)
09738                         return NC_ENOMEM;
09739                 for(ii = 0; ii < varp->ndims; ii++)
09740                 {
09741                         if(map[ii] % szof != 0) 
09742                         {
09743                                 free(cvtmap);
09744                                 return NC_EINVAL;
09745                         }
09746                         cvtmap[ii] = map[ii] / szof;
09747                 }
09748                 map = cvtmap;
09749         }
09750 
09751         switch(varp->type){
09752         case NC_CHAR:
09753                 status =  nc_get_varm_text(ncid, varid, start, edges,
09754                         stride, map,
09755                         (char *) value);
09756                 break;
09757         case NC_BYTE:
09758                 status = nc_get_varm_schar(ncid, varid, start, edges,
09759                         stride, map,
09760                         (schar *) value);
09761                 break;
09762         case NC_SHORT:
09763                 status = nc_get_varm_short(ncid, varid, start, edges,
09764                         stride, map,
09765                         (short *) value);
09766                 break;
09767         case NC_INT:
09768 #if (SIZEOF_INT >= X_SIZEOF_INT)
09769                 status = nc_get_varm_int(ncid, varid, start, edges,
09770                         stride, map,
09771                         (int *) value);
09772 #elif SIZEOF_LONG == X_SIZEOF_INT
09773                 status = nc_get_varm_long(ncid, varid, start, edges,
09774                         stride, map,
09775                         (long *) value);
09776 #else
09777 #error "nc_get_varm implementation"
09778 #endif
09779                 break;
09780         case NC_FLOAT:
09781                 status = nc_get_varm_float(ncid, varid, start, edges,
09782                         stride, map,
09783                         (float *) value);
09784                 break;
09785         case NC_DOUBLE: 
09786                 status = nc_get_varm_double(ncid, varid, start, edges,
09787                         stride, map,
09788                         (double *) value);
09789                 break;
09790         default:
09791                 status = NC_EBADTYPE;
09792                 break;
09793         }
09794 
09795         if(cvtmap != NULL)
09796         {
09797                 free(cvtmap);
09798         }
09799         return status;
09800 }
09801 
09802 
09803 /*
09804  * Generalized hyperslab output.
09805  */
09806 
09807 int
09808 nc_put_varm_text(int ncid, int varid,
09809         const size_t *start, const size_t *edges,
09810         const ptrdiff_t *stride, const ptrdiff_t *map,
09811         const char *value)
09812 {
09813         int status = ENOERR;
09814         NC *ncp;
09815         NC_var *varp;
09816         int maxidim;    /* maximum dimensional index */
09817 
09818         status = NC_check_id (ncid, &ncp);
09819         if (status != NC_NOERR)
09820                 return status;
09821 
09822         if (NC_indef (ncp))
09823         {
09824                 return NC_EINDEFINE;
09825         }
09826 
09827                 if (NC_readonly (ncp))
09828                         return NC_EPERM;
09829         varp = NC_lookupvar (ncp, varid);
09830         if (varp == NULL)
09831                 return NC_ENOTVAR;
09832 
09833         if(varp->type != NC_CHAR)
09834                 return NC_ECHAR;
09835 
09836         maxidim = (int) varp->ndims - 1;
09837 
09838         if (maxidim < 0)
09839         {
09840                 /*
09841                  * The variable is a scalar; consequently,
09842                  * there s only one thing to get and only one place to put it.
09843                  * (Why was I called?)
09844                  */
09845                 return putNCv_text (ncp, varp, start, 1, value);
09846         }
09847         
09848         /*
09849          * else
09850          * The variable is an array.
09851          */
09852         {
09853                 int idim;
09854                 size_t *mystart = NULL;
09855                 size_t *myedges;
09856                 size_t *iocount;        /* count vector */
09857                 size_t *stop;   /* stop indexes */
09858                 size_t *length; /* edge lengths in bytes */
09859                 ptrdiff_t *mystride;
09860                 ptrdiff_t *mymap;
09861 
09862                 /*
09863                  * Verify stride argument.
09864                  */
09865                 for (idim = 0; idim <= maxidim; ++idim)
09866                 {
09867                         if (stride != NULL
09868                                 && (stride[idim] == 0
09869                 /* cast needed for braindead systems with signed size_t */
09870                                 || (unsigned long) stride[idim] >= X_INT_MAX))
09871                         {
09872                                 return NC_ESTRIDE;
09873                         }
09874                 }
09875 
09876                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
09877                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
09878                 if(mystart == NULL)
09879                         return NC_ENOMEM;
09880                 myedges = mystart + varp->ndims;
09881                 iocount = myedges + varp->ndims;
09882                 stop = iocount + varp->ndims;
09883                 length = stop + varp->ndims;
09884                 mystride = (ptrdiff_t *)(length + varp->ndims);
09885                 mymap = mystride + varp->ndims;
09886 
09887                 /*
09888                  * Initialize I/O parameters.
09889                  */
09890                 for (idim = maxidim; idim >= 0; --idim)
09891                 {
09892                         mystart[idim] = start != NULL
09893                                 ? start[idim]
09894                                 : 0;
09895 
09896                         if (edges[idim] == 0)
09897                         {
09898                                 status = NC_NOERR;      /* read/write no data */
09899                                 goto done;
09900                         }
09901 
09902                         myedges[idim] = edges != NULL
09903                                 ? edges[idim]
09904                                 : idim == 0 && IS_RECVAR (varp)
09905                                 ? NC_get_numrecs(ncp) - mystart[idim]
09906                                 : varp->shape[idim] - mystart[idim];
09907                         mystride[idim] = stride != NULL
09908                                 ? stride[idim]
09909                                 : 1;
09910                         mymap[idim] = map != NULL
09911                                 ? map[idim]
09912                                 : idim == maxidim
09913                                 ? 1
09914                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
09915 
09916                         iocount[idim] = 1;
09917                         length[idim] = mymap[idim] * myedges[idim];
09918                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
09919                 }
09920 
09921                 /*
09922                  * Check start, edges
09923                  */
09924                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
09925                 {
09926                         if (mystart[idim] >= varp->shape[idim])
09927                         {
09928                                 status = NC_EINVALCOORDS;
09929                                 goto done;
09930                         }
09931                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
09932                         {
09933                                 status = NC_EEDGE;
09934                                 goto done;
09935                         }
09936                 }
09937                 /*
09938                  * As an optimization, adjust I/O parameters when the fastest 
09939                  * dimension has unity stride both externally and internally.
09940                  * In this case, the user could have called a simpler routine
09941                  * (i.e. ncvarnc_put_vara_text()
09942                  */
09943                 if (mystride[maxidim] == 1
09944                         && mymap[maxidim] == 1)
09945                 {
09946                         iocount[maxidim] = myedges[maxidim];
09947                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
09948                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
09949                 }
09950 
09951                 /*
09952                  * Perform I/O.  Exit when done.
09953                  */
09954                 for (;;)
09955                 {
09956                         /* TODO: */
09957                         int lstatus = nc_put_vara_text (ncid, varid, mystart, iocount,
09958                                                 value);
09959                         if (lstatus != NC_NOERR 
09960                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
09961                                 status = lstatus;
09962 
09963                         /*
09964                          * The following code permutes through the variable s
09965                          * external start-index space and it s internal address
09966                          * space.  At the UPC, this algorithm is commonly
09967                          * called "odometer code".
09968                          */
09969                         idim = maxidim;
09970                 carry:
09971                         value += mymap[idim];
09972                         mystart[idim] += mystride[idim];
09973                         if (mystart[idim] == stop[idim])
09974                         {
09975                                 mystart[idim] = start[idim];
09976                                 value -= length[idim];
09977                                 if (--idim < 0)
09978                                         break; /* normal return */
09979                                 goto carry;
09980                         }
09981                 } /* I/O loop */
09982         done:
09983                 free(mystart);
09984         } /* variable is array */
09985         return status;
09986 
09987 }
09988 
09989 
09990 int
09991 nc_put_varm_uchar(int ncid, int varid,
09992         const size_t *start, const size_t *edges,
09993         const ptrdiff_t *stride, const ptrdiff_t *map,
09994         const uchar *value)
09995 {
09996         int status = ENOERR;
09997         NC *ncp;
09998         NC_var *varp;
09999         int maxidim;    /* maximum dimensional index */
10000 
10001         status = NC_check_id (ncid, &ncp);
10002         if (status != NC_NOERR)
10003                 return status;
10004 
10005         if (NC_indef (ncp))
10006         {
10007                 return NC_EINDEFINE;
10008         }
10009 
10010                 if (NC_readonly (ncp))
10011                         return NC_EPERM;
10012         varp = NC_lookupvar (ncp, varid);
10013         if (varp == NULL)
10014                 return NC_ENOTVAR;
10015 
10016         if(varp->type == NC_CHAR)
10017                 return NC_ECHAR;
10018 
10019         maxidim = (int) varp->ndims - 1;
10020 
10021         if (maxidim < 0)
10022         {
10023                 /*
10024                  * The variable is a scalar; consequently,
10025                  * there s only one thing to get and only one place to put it.
10026                  * (Why was I called?)
10027                  */
10028                 return putNCv_uchar (ncp, varp, start, 1, value);
10029         }
10030         
10031         /*
10032          * else
10033          * The variable is an array.
10034          */
10035         {
10036                 int idim;
10037                 size_t *mystart = NULL;
10038                 size_t *myedges;
10039                 size_t *iocount;        /* count vector */
10040                 size_t *stop;   /* stop indexes */
10041                 size_t *length; /* edge lengths in bytes */
10042                 ptrdiff_t *mystride;
10043                 ptrdiff_t *mymap;
10044 
10045                 /*
10046                  * Verify stride argument.
10047                  */
10048                 for (idim = 0; idim <= maxidim; ++idim)
10049                 {
10050                         if (stride != NULL
10051                                 && (stride[idim] == 0
10052                 /* cast needed for braindead systems with signed size_t */
10053                                 || (unsigned long) stride[idim] >= X_INT_MAX))
10054                         {
10055                                 return NC_ESTRIDE;
10056                         }
10057                 }
10058 
10059                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
10060                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
10061                 if(mystart == NULL)
10062                         return NC_ENOMEM;
10063                 myedges = mystart + varp->ndims;
10064                 iocount = myedges + varp->ndims;
10065                 stop = iocount + varp->ndims;
10066                 length = stop + varp->ndims;
10067                 mystride = (ptrdiff_t *)(length + varp->ndims);
10068                 mymap = mystride + varp->ndims;
10069 
10070                 /*
10071                  * Initialize I/O parameters.
10072                  */
10073                 for (idim = maxidim; idim >= 0; --idim)
10074                 {
10075                         mystart[idim] = start != NULL
10076                                 ? start[idim]
10077                                 : 0;
10078 
10079                         if (edges[idim] == 0)
10080                         {
10081                                 status = NC_NOERR;      /* read/write no data */
10082                                 goto done;
10083                         }
10084 
10085                         myedges[idim] = edges != NULL
10086                                 ? edges[idim]
10087                                 : idim == 0 && IS_RECVAR (varp)
10088                                 ? NC_get_numrecs(ncp) - mystart[idim]
10089                                 : varp->shape[idim] - mystart[idim];
10090                         mystride[idim] = stride != NULL
10091                                 ? stride[idim]
10092                                 : 1;
10093                         mymap[idim] = map != NULL
10094                                 ? map[idim]
10095                                 : idim == maxidim
10096                                 ? 1
10097                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
10098 
10099                         iocount[idim] = 1;
10100                         length[idim] = mymap[idim] * myedges[idim];
10101                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
10102                 }
10103 
10104                 /*
10105                  * Check start, edges
10106                  */
10107                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
10108                 {
10109                         if (mystart[idim] >= varp->shape[idim])
10110                         {
10111                                 status = NC_EINVALCOORDS;
10112                                 goto done;
10113                         }
10114                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
10115                         {
10116                                 status = NC_EEDGE;
10117                                 goto done;
10118                         }
10119                 }
10120                 /*
10121                  * As an optimization, adjust I/O parameters when the fastest 
10122                  * dimension has unity stride both externally and internally.
10123                  * In this case, the user could have called a simpler routine
10124                  * (i.e. ncvarnc_put_vara_uchar()
10125                  */
10126                 if (mystride[maxidim] == 1
10127                         && mymap[maxidim] == 1)
10128                 {
10129                         iocount[maxidim] = myedges[maxidim];
10130                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
10131                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
10132                 }
10133 
10134                 /*
10135                  * Perform I/O.  Exit when done.
10136                  */
10137                 for (;;)
10138                 {
10139                         /* TODO: */
10140                         int lstatus = nc_put_vara_uchar (ncid, varid, mystart, iocount,
10141                                                 value);
10142                         if (lstatus != NC_NOERR 
10143                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
10144                                 status = lstatus;
10145 
10146                         /*
10147                          * The following code permutes through the variable s
10148                          * external start-index space and it s internal address
10149                          * space.  At the UPC, this algorithm is commonly
10150                          * called "odometer code".
10151                          */
10152                         idim = maxidim;
10153                 carry:
10154                         value += mymap[idim];
10155                         mystart[idim] += mystride[idim];
10156                         if (mystart[idim] == stop[idim])
10157                         {
10158                                 mystart[idim] = start[idim];
10159                                 value -= length[idim];
10160                                 if (--idim < 0)
10161                                         break; /* normal return */
10162                                 goto carry;
10163                         }
10164                 } /* I/O loop */
10165         done:
10166                 free(mystart);
10167         } /* variable is array */
10168         return status;
10169 
10170 }
10171 
10172 int
10173 nc_put_varm_schar(int ncid, int varid,
10174         const size_t *start, const size_t *edges,
10175         const ptrdiff_t *stride, const ptrdiff_t *map,
10176         const schar *value)
10177 {
10178         int status = ENOERR;
10179         NC *ncp;
10180         NC_var *varp;
10181         int maxidim;    /* maximum dimensional index */
10182 
10183         status = NC_check_id (ncid, &ncp);
10184         if (status != NC_NOERR)
10185                 return status;
10186 
10187         if (NC_indef (ncp))
10188         {
10189                 return NC_EINDEFINE;
10190         }
10191 
10192                 if (NC_readonly (ncp))
10193                         return NC_EPERM;
10194         varp = NC_lookupvar (ncp, varid);
10195         if (varp == NULL)
10196                 return NC_ENOTVAR;
10197 
10198         if(varp->type == NC_CHAR)
10199                 return NC_ECHAR;
10200 
10201         maxidim = (int) varp->ndims - 1;
10202 
10203         if (maxidim < 0)
10204         {
10205                 /*
10206                  * The variable is a scalar; consequently,
10207                  * there s only one thing to get and only one place to put it.
10208                  * (Why was I called?)
10209                  */
10210                 return putNCv_schar (ncp, varp, start, 1, value);
10211         }
10212         
10213         /*
10214          * else
10215          * The variable is an array.
10216          */
10217         {
10218                 int idim;
10219                 size_t *mystart = NULL;
10220                 size_t *myedges;
10221                 size_t *iocount;        /* count vector */
10222                 size_t *stop;   /* stop indexes */
10223                 size_t *length; /* edge lengths in bytes */
10224                 ptrdiff_t *mystride;
10225                 ptrdiff_t *mymap;
10226 
10227                 /*
10228                  * Verify stride argument.
10229                  */
10230                 for (idim = 0; idim <= maxidim; ++idim)
10231                 {
10232                         if (stride != NULL
10233                                 && (stride[idim] == 0
10234                 /* cast needed for braindead systems with signed size_t */
10235                                 || (unsigned long) stride[idim] >= X_INT_MAX))
10236                         {
10237                                 return NC_ESTRIDE;
10238                         }
10239                 }
10240 
10241                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
10242                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
10243                 if(mystart == NULL)
10244                         return NC_ENOMEM;
10245                 myedges = mystart + varp->ndims;
10246                 iocount = myedges + varp->ndims;
10247                 stop = iocount + varp->ndims;
10248                 length = stop + varp->ndims;
10249                 mystride = (ptrdiff_t *)(length + varp->ndims);
10250                 mymap = mystride + varp->ndims;
10251 
10252                 /*
10253                  * Initialize I/O parameters.
10254                  */
10255                 for (idim = maxidim; idim >= 0; --idim)
10256                 {
10257                         mystart[idim] = start != NULL
10258                                 ? start[idim]
10259                                 : 0;
10260 
10261                         if (edges[idim] == 0)
10262                         {
10263                                 status = NC_NOERR;      /* read/write no data */
10264                                 goto done;
10265                         }
10266 
10267                         myedges[idim] = edges != NULL
10268                                 ? edges[idim]
10269                                 : idim == 0 && IS_RECVAR (varp)
10270                                 ? NC_get_numrecs(ncp) - mystart[idim]
10271                                 : varp->shape[idim] - mystart[idim];
10272                         mystride[idim] = stride != NULL
10273                                 ? stride[idim]
10274                                 : 1;
10275                         mymap[idim] = map != NULL
10276                                 ? map[idim]
10277                                 : idim == maxidim
10278                                 ? 1
10279                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
10280 
10281                         iocount[idim] = 1;
10282                         length[idim] = mymap[idim] * myedges[idim];
10283                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
10284                 }
10285 
10286                 /*
10287                  * Check start, edges
10288                  */
10289                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
10290                 {
10291                         if (mystart[idim] >= varp->shape[idim])
10292                         {
10293                                 status = NC_EINVALCOORDS;
10294                                 goto done;
10295                         }
10296                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
10297                         {
10298                                 status = NC_EEDGE;
10299                                 goto done;
10300                         }
10301                 }
10302                 /*
10303                  * As an optimization, adjust I/O parameters when the fastest 
10304                  * dimension has unity stride both externally and internally.
10305                  * In this case, the user could have called a simpler routine
10306                  * (i.e. ncvarnc_put_vara_schar()
10307                  */
10308                 if (mystride[maxidim] == 1
10309                         && mymap[maxidim] == 1)
10310                 {
10311                         iocount[maxidim] = myedges[maxidim];
10312                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
10313                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
10314                 }
10315 
10316                 /*
10317                  * Perform I/O.  Exit when done.
10318                  */
10319                 for (;;)
10320                 {
10321                         /* TODO: */
10322                         int lstatus = nc_put_vara_schar (ncid, varid, mystart, iocount,
10323                                                 value);
10324                         if (lstatus != NC_NOERR 
10325                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
10326                                 status = lstatus;
10327 
10328                         /*
10329                          * The following code permutes through the variable s
10330                          * external start-index space and it s internal address
10331                          * space.  At the UPC, this algorithm is commonly
10332                          * called "odometer code".
10333                          */
10334                         idim = maxidim;
10335                 carry:
10336                         value += mymap[idim];
10337                         mystart[idim] += mystride[idim];
10338                         if (mystart[idim] == stop[idim])
10339                         {
10340                                 mystart[idim] = start[idim];
10341                                 value -= length[idim];
10342                                 if (--idim < 0)
10343                                         break; /* normal return */
10344                                 goto carry;
10345                         }
10346                 } /* I/O loop */
10347         done:
10348                 free(mystart);
10349         } /* variable is array */
10350         return status;
10351 
10352 }
10353 
10354 int
10355 nc_put_varm_short(int ncid, int varid,
10356         const size_t *start, const size_t *edges,
10357         const ptrdiff_t *stride, const ptrdiff_t *map,
10358         const short *value)
10359 {
10360         int status = ENOERR;
10361         NC *ncp;
10362         NC_var *varp;
10363         int maxidim;    /* maximum dimensional index */
10364 
10365         status = NC_check_id (ncid, &ncp);
10366         if (status != NC_NOERR)
10367                 return status;
10368 
10369         if (NC_indef (ncp))
10370         {
10371                 return NC_EINDEFINE;
10372         }
10373 
10374                 if (NC_readonly (ncp))
10375                         return NC_EPERM;
10376         varp = NC_lookupvar (ncp, varid);
10377         if (varp == NULL)
10378                 return NC_ENOTVAR;
10379 
10380         if(varp->type == NC_CHAR)
10381                 return NC_ECHAR;
10382 
10383         maxidim = (int) varp->ndims - 1;
10384 
10385         if (maxidim < 0)
10386         {
10387                 /*
10388                  * The variable is a scalar; consequently,
10389                  * there s only one thing to get and only one place to put it.
10390                  * (Why was I called?)
10391                  */
10392                 return putNCv_short (ncp, varp, start, 1, value);
10393         }
10394         
10395         /*
10396          * else
10397          * The variable is an array.
10398          */
10399         {
10400                 int idim;
10401                 size_t *mystart = NULL;
10402                 size_t *myedges;
10403                 size_t *iocount;        /* count vector */
10404                 size_t *stop;   /* stop indexes */
10405                 size_t *length; /* edge lengths in bytes */
10406                 ptrdiff_t *mystride;
10407                 ptrdiff_t *mymap;
10408 
10409                 /*
10410                  * Verify stride argument.
10411                  */
10412                 for (idim = 0; idim <= maxidim; ++idim)
10413                 {
10414                         if (stride != NULL
10415                                 && (stride[idim] == 0
10416                 /* cast needed for braindead systems with signed size_t */
10417                                 || (unsigned long) stride[idim] >= X_INT_MAX))
10418                         {
10419                                 return NC_ESTRIDE;
10420                         }
10421                 }
10422 
10423                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
10424                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
10425                 if(mystart == NULL)
10426                         return NC_ENOMEM;
10427                 myedges = mystart + varp->ndims;
10428                 iocount = myedges + varp->ndims;
10429                 stop = iocount + varp->ndims;
10430                 length = stop + varp->ndims;
10431                 mystride = (ptrdiff_t *)(length + varp->ndims);
10432                 mymap = mystride + varp->ndims;
10433 
10434                 /*
10435                  * Initialize I/O parameters.
10436                  */
10437                 for (idim = maxidim; idim >= 0; --idim)
10438                 {
10439                         mystart[idim] = start != NULL
10440                                 ? start[idim]
10441                                 : 0;
10442 
10443                         if (edges[idim] == 0)
10444                         {
10445                                 status = NC_NOERR;      /* read/write no data */
10446                                 goto done;
10447                         }
10448 
10449                         myedges[idim] = edges != NULL
10450                                 ? edges[idim]
10451                                 : idim == 0 && IS_RECVAR (varp)
10452                                 ? NC_get_numrecs(ncp) - mystart[idim]
10453                                 : varp->shape[idim] - mystart[idim];
10454                         mystride[idim] = stride != NULL
10455                                 ? stride[idim]
10456                                 : 1;
10457                         mymap[idim] = map != NULL
10458                                 ? map[idim]
10459                                 : idim == maxidim
10460                                 ? 1
10461                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
10462 
10463                         iocount[idim] = 1;
10464                         length[idim] = mymap[idim] * myedges[idim];
10465                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
10466                 }
10467 
10468                 /*
10469                  * Check start, edges
10470                  */
10471                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
10472                 {
10473                         if (mystart[idim] >= varp->shape[idim])
10474                         {
10475                                 status = NC_EINVALCOORDS;
10476                                 goto done;
10477                         }
10478                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
10479                         {
10480                                 status = NC_EEDGE;
10481                                 goto done;
10482                         }
10483                 }
10484                 /*
10485                  * As an optimization, adjust I/O parameters when the fastest 
10486                  * dimension has unity stride both externally and internally.
10487                  * In this case, the user could have called a simpler routine
10488                  * (i.e. ncvarnc_put_vara_short()
10489                  */
10490                 if (mystride[maxidim] == 1
10491                         && mymap[maxidim] == 1)
10492                 {
10493                         iocount[maxidim] = myedges[maxidim];
10494                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
10495                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
10496                 }
10497 
10498                 /*
10499                  * Perform I/O.  Exit when done.
10500                  */
10501                 for (;;)
10502                 {
10503                         /* TODO: */
10504                         int lstatus = nc_put_vara_short (ncid, varid, mystart, iocount,
10505                                                 value);
10506                         if (lstatus != NC_NOERR 
10507                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
10508                                 status = lstatus;
10509 
10510                         /*
10511                          * The following code permutes through the variable s
10512                          * external start-index space and it s internal address
10513                          * space.  At the UPC, this algorithm is commonly
10514                          * called "odometer code".
10515                          */
10516                         idim = maxidim;
10517                 carry:
10518                         value += mymap[idim];
10519                         mystart[idim] += mystride[idim];
10520                         if (mystart[idim] == stop[idim])
10521                         {
10522                                 mystart[idim] = start[idim];
10523                                 value -= length[idim];
10524                                 if (--idim < 0)
10525                                         break; /* normal return */
10526                                 goto carry;
10527                         }
10528                 } /* I/O loop */
10529         done:
10530                 free(mystart);
10531         } /* variable is array */
10532         return status;
10533 
10534 }
10535 
10536 int
10537 nc_put_varm_int(int ncid, int varid,
10538         const size_t *start, const size_t *edges,
10539         const ptrdiff_t *stride, const ptrdiff_t *map,
10540         const int *value)
10541 {
10542         int status = ENOERR;
10543         NC *ncp;
10544         NC_var *varp;
10545         int maxidim;    /* maximum dimensional index */
10546 
10547         status = NC_check_id (ncid, &ncp);
10548         if (status != NC_NOERR)
10549                 return status;
10550 
10551         if (NC_indef (ncp))
10552         {
10553                 return NC_EINDEFINE;
10554         }
10555 
10556                 if (NC_readonly (ncp))
10557                         return NC_EPERM;
10558         varp = NC_lookupvar (ncp, varid);
10559         if (varp == NULL)
10560                 return NC_ENOTVAR;
10561 
10562         if(varp->type == NC_CHAR)
10563                 return NC_ECHAR;
10564 
10565         maxidim = (int) varp->ndims - 1;
10566 
10567         if (maxidim < 0)
10568         {
10569                 /*
10570                  * The variable is a scalar; consequently,
10571                  * there s only one thing to get and only one place to put it.
10572                  * (Why was I called?)
10573                  */
10574                 return putNCv_int (ncp, varp, start, 1, value);
10575         }
10576         
10577         /*
10578          * else
10579          * The variable is an array.
10580          */
10581         {
10582                 int idim;
10583                 size_t *mystart = NULL;
10584                 size_t *myedges;
10585                 size_t *iocount;        /* count vector */
10586                 size_t *stop;   /* stop indexes */
10587                 size_t *length; /* edge lengths in bytes */
10588                 ptrdiff_t *mystride;
10589                 ptrdiff_t *mymap;
10590 
10591                 /*
10592                  * Verify stride argument.
10593                  */
10594                 for (idim = 0; idim <= maxidim; ++idim)
10595                 {
10596                         if (stride != NULL
10597                                 && (stride[idim] == 0
10598                 /* cast needed for braindead systems with signed size_t */
10599                                 || (unsigned long) stride[idim] >= X_INT_MAX))
10600                         {
10601                                 return NC_ESTRIDE;
10602                         }
10603                 }
10604 
10605                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
10606                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
10607                 if(mystart == NULL)
10608                         return NC_ENOMEM;
10609                 myedges = mystart + varp->ndims;
10610                 iocount = myedges + varp->ndims;
10611                 stop = iocount + varp->ndims;
10612                 length = stop + varp->ndims;
10613                 mystride = (ptrdiff_t *)(length + varp->ndims);
10614                 mymap = mystride + varp->ndims;
10615 
10616                 /*
10617                  * Initialize I/O parameters.
10618                  */
10619                 for (idim = maxidim; idim >= 0; --idim)
10620                 {
10621                         mystart[idim] = start != NULL
10622                                 ? start[idim]
10623                                 : 0;
10624 
10625                         if (edges[idim] == 0)
10626                         {
10627                                 status = NC_NOERR;      /* read/write no data */
10628                                 goto done;
10629                         }
10630 
10631                         myedges[idim] = edges != NULL
10632                                 ? edges[idim]
10633                                 : idim == 0 && IS_RECVAR (varp)
10634                                 ? NC_get_numrecs(ncp) - mystart[idim]
10635                                 : varp->shape[idim] - mystart[idim];
10636                         mystride[idim] = stride != NULL
10637                                 ? stride[idim]
10638                                 : 1;
10639                         mymap[idim] = map != NULL
10640                                 ? map[idim]
10641                                 : idim == maxidim
10642                                 ? 1
10643                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
10644 
10645                         iocount[idim] = 1;
10646                         length[idim] = mymap[idim] * myedges[idim];
10647                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
10648                 }
10649 
10650                 /*
10651                  * Check start, edges
10652                  */
10653                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
10654                 {
10655                         if (mystart[idim] >= varp->shape[idim])
10656                         {
10657                                 status = NC_EINVALCOORDS;
10658                                 goto done;
10659                         }
10660                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
10661                         {
10662                                 status = NC_EEDGE;
10663                                 goto done;
10664                         }
10665                 }
10666                 /*
10667                  * As an optimization, adjust I/O parameters when the fastest 
10668                  * dimension has unity stride both externally and internally.
10669                  * In this case, the user could have called a simpler routine
10670                  * (i.e. ncvarnc_put_vara_int()
10671                  */
10672                 if (mystride[maxidim] == 1
10673                         && mymap[maxidim] == 1)
10674                 {
10675                         iocount[maxidim] = myedges[maxidim];
10676                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
10677                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
10678                 }
10679 
10680                 /*
10681                  * Perform I/O.  Exit when done.
10682                  */
10683                 for (;;)
10684                 {
10685                         /* TODO: */
10686                         int lstatus = nc_put_vara_int (ncid, varid, mystart, iocount,
10687                                                 value);
10688                         if (lstatus != NC_NOERR 
10689                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
10690                                 status = lstatus;
10691 
10692                         /*
10693                          * The following code permutes through the variable s
10694                          * external start-index space and it s internal address
10695                          * space.  At the UPC, this algorithm is commonly
10696                          * called "odometer code".
10697                          */
10698                         idim = maxidim;
10699                 carry:
10700                         value += mymap[idim];
10701                         mystart[idim] += mystride[idim];
10702                         if (mystart[idim] == stop[idim])
10703                         {
10704                                 mystart[idim] = start[idim];
10705                                 value -= length[idim];
10706                                 if (--idim < 0)
10707                                         break; /* normal return */
10708                                 goto carry;
10709                         }
10710                 } /* I/O loop */
10711         done:
10712                 free(mystart);
10713         } /* variable is array */
10714         return status;
10715 
10716 }
10717 
10718 int
10719 nc_put_varm_long(int ncid, int varid,
10720         const size_t *start, const size_t *edges,
10721         const ptrdiff_t *stride, const ptrdiff_t *map,
10722         const long *value)
10723 {
10724         int status = ENOERR;
10725         NC *ncp;
10726         NC_var *varp;
10727         int maxidim;    /* maximum dimensional index */
10728 
10729         status = NC_check_id (ncid, &ncp);
10730         if (status != NC_NOERR)
10731                 return status;
10732 
10733         if (NC_indef (ncp))
10734         {
10735                 return NC_EINDEFINE;
10736         }
10737 
10738                 if (NC_readonly (ncp))
10739                         return NC_EPERM;
10740         varp = NC_lookupvar (ncp, varid);
10741         if (varp == NULL)
10742                 return NC_ENOTVAR;
10743 
10744         if(varp->type == NC_CHAR)
10745                 return NC_ECHAR;
10746 
10747         maxidim = (int) varp->ndims - 1;
10748 
10749         if (maxidim < 0)
10750         {
10751                 /*
10752                  * The variable is a scalar; consequently,
10753                  * there s only one thing to get and only one place to put it.
10754                  * (Why was I called?)
10755                  */
10756                 return putNCv_long (ncp, varp, start, 1, value);
10757         }
10758         
10759         /*
10760          * else
10761          * The variable is an array.
10762          */
10763         {
10764                 int idim;
10765                 size_t *mystart = NULL;
10766                 size_t *myedges;
10767                 size_t *iocount;        /* count vector */
10768                 size_t *stop;   /* stop indexes */
10769                 size_t *length; /* edge lengths in bytes */
10770                 ptrdiff_t *mystride;
10771                 ptrdiff_t *mymap;
10772 
10773                 /*
10774                  * Verify stride argument.
10775                  */
10776                 for (idim = 0; idim <= maxidim; ++idim)
10777                 {
10778                         if (stride != NULL
10779                                 && (stride[idim] == 0
10780                 /* cast needed for braindead systems with signed size_t */
10781                                 || (unsigned long) stride[idim] >= X_INT_MAX))
10782                         {
10783                                 return NC_ESTRIDE;
10784                         }
10785                 }
10786 
10787                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
10788                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
10789                 if(mystart == NULL)
10790                         return NC_ENOMEM;
10791                 myedges = mystart + varp->ndims;
10792                 iocount = myedges + varp->ndims;
10793                 stop = iocount + varp->ndims;
10794                 length = stop + varp->ndims;
10795                 mystride = (ptrdiff_t *)(length + varp->ndims);
10796                 mymap = mystride + varp->ndims;
10797 
10798                 /*
10799                  * Initialize I/O parameters.
10800                  */
10801                 for (idim = maxidim; idim >= 0; --idim)
10802                 {
10803                         mystart[idim] = start != NULL
10804                                 ? start[idim]
10805                                 : 0;
10806 
10807                         if (edges[idim] == 0)
10808                         {
10809                                 status = NC_NOERR;      /* read/write no data */
10810                                 goto done;
10811                         }
10812 
10813                         myedges[idim] = edges != NULL
10814                                 ? edges[idim]
10815                                 : idim == 0 && IS_RECVAR (varp)
10816                                 ? NC_get_numrecs(ncp) - mystart[idim]
10817                                 : varp->shape[idim] - mystart[idim];
10818                         mystride[idim] = stride != NULL
10819                                 ? stride[idim]
10820                                 : 1;
10821                         mymap[idim] = map != NULL
10822                                 ? map[idim]
10823                                 : idim == maxidim
10824                                 ? 1
10825                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
10826 
10827                         iocount[idim] = 1;
10828                         length[idim] = mymap[idim] * myedges[idim];
10829                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
10830                 }
10831 
10832                 /*
10833                  * Check start, edges
10834                  */
10835                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
10836                 {
10837                         if (mystart[idim] >= varp->shape[idim])
10838                         {
10839                                 status = NC_EINVALCOORDS;
10840                                 goto done;
10841                         }
10842                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
10843                         {
10844                                 status = NC_EEDGE;
10845                                 goto done;
10846                         }
10847                 }
10848                 /*
10849                  * As an optimization, adjust I/O parameters when the fastest 
10850                  * dimension has unity stride both externally and internally.
10851                  * In this case, the user could have called a simpler routine
10852                  * (i.e. ncvarnc_put_vara_long()
10853                  */
10854                 if (mystride[maxidim] == 1
10855                         && mymap[maxidim] == 1)
10856                 {
10857                         iocount[maxidim] = myedges[maxidim];
10858                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
10859                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
10860                 }
10861 
10862                 /*
10863                  * Perform I/O.  Exit when done.
10864                  */
10865                 for (;;)
10866                 {
10867                         /* TODO: */
10868                         int lstatus = nc_put_vara_long (ncid, varid, mystart, iocount,
10869                                                 value);
10870                         if (lstatus != NC_NOERR 
10871                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
10872                                 status = lstatus;
10873 
10874                         /*
10875                          * The following code permutes through the variable s
10876                          * external start-index space and it s internal address
10877                          * space.  At the UPC, this algorithm is commonly
10878                          * called "odometer code".
10879                          */
10880                         idim = maxidim;
10881                 carry:
10882                         value += mymap[idim];
10883                         mystart[idim] += mystride[idim];
10884                         if (mystart[idim] == stop[idim])
10885                         {
10886                                 mystart[idim] = start[idim];
10887                                 value -= length[idim];
10888                                 if (--idim < 0)
10889                                         break; /* normal return */
10890                                 goto carry;
10891                         }
10892                 } /* I/O loop */
10893         done:
10894                 free(mystart);
10895         } /* variable is array */
10896         return status;
10897 
10898 }
10899 
10900 int
10901 nc_put_varm_float(int ncid, int varid,
10902         const size_t *start, const size_t *edges,
10903         const ptrdiff_t *stride, const ptrdiff_t *map,
10904         const float *value)
10905 {
10906         int status = ENOERR;
10907         NC *ncp;
10908         NC_var *varp;
10909         int maxidim;    /* maximum dimensional index */
10910 
10911         status = NC_check_id (ncid, &ncp);
10912         if (status != NC_NOERR)
10913                 return status;
10914 
10915         if (NC_indef (ncp))
10916         {
10917                 return NC_EINDEFINE;
10918         }
10919 
10920                 if (NC_readonly (ncp))
10921                         return NC_EPERM;
10922         varp = NC_lookupvar (ncp, varid);
10923         if (varp == NULL)
10924                 return NC_ENOTVAR;
10925 
10926         if(varp->type == NC_CHAR)
10927                 return NC_ECHAR;
10928 
10929         maxidim = (int) varp->ndims - 1;
10930 
10931         if (maxidim < 0)
10932         {
10933                 /*
10934                  * The variable is a scalar; consequently,
10935                  * there s only one thing to get and only one place to put it.
10936                  * (Why was I called?)
10937                  */
10938                 return putNCv_float (ncp, varp, start, 1, value);
10939         }
10940         
10941         /*
10942          * else
10943          * The variable is an array.
10944          */
10945         {
10946                 int idim;
10947                 size_t *mystart = NULL;
10948                 size_t *myedges;
10949                 size_t *iocount;        /* count vector */
10950                 size_t *stop;   /* stop indexes */
10951                 size_t *length; /* edge lengths in bytes */
10952                 ptrdiff_t *mystride;
10953                 ptrdiff_t *mymap;
10954 
10955                 /*
10956                  * Verify stride argument.
10957                  */
10958                 for (idim = 0; idim <= maxidim; ++idim)
10959                 {
10960                         if (stride != NULL
10961                                 && (stride[idim] == 0
10962                 /* cast needed for braindead systems with signed size_t */
10963                                 || (unsigned long) stride[idim] >= X_INT_MAX))
10964                         {
10965                                 return NC_ESTRIDE;
10966                         }
10967                 }
10968 
10969                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
10970                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
10971                 if(mystart == NULL)
10972                         return NC_ENOMEM;
10973                 myedges = mystart + varp->ndims;
10974                 iocount = myedges + varp->ndims;
10975                 stop = iocount + varp->ndims;
10976                 length = stop + varp->ndims;
10977                 mystride = (ptrdiff_t *)(length + varp->ndims);
10978                 mymap = mystride + varp->ndims;
10979 
10980                 /*
10981                  * Initialize I/O parameters.
10982                  */
10983                 for (idim = maxidim; idim >= 0; --idim)
10984                 {
10985                         mystart[idim] = start != NULL
10986                                 ? start[idim]
10987                                 : 0;
10988 
10989                         if (edges[idim] == 0)
10990                         {
10991                                 status = NC_NOERR;      /* read/write no data */
10992                                 goto done;
10993                         }
10994 
10995                         myedges[idim] = edges != NULL
10996                                 ? edges[idim]
10997                                 : idim == 0 && IS_RECVAR (varp)
10998                                 ? NC_get_numrecs(ncp) - mystart[idim]
10999                                 : varp->shape[idim] - mystart[idim];
11000                         mystride[idim] = stride != NULL
11001                                 ? stride[idim]
11002                                 : 1;
11003                         mymap[idim] = map != NULL
11004                                 ? map[idim]
11005                                 : idim == maxidim
11006                                 ? 1
11007                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
11008 
11009                         iocount[idim] = 1;
11010                         length[idim] = mymap[idim] * myedges[idim];
11011                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
11012                 }
11013 
11014                 /*
11015                  * Check start, edges
11016                  */
11017                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
11018                 {
11019                         if (mystart[idim] >= varp->shape[idim])
11020                         {
11021                                 status = NC_EINVALCOORDS;
11022                                 goto done;
11023                         }
11024                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
11025                         {
11026                                 status = NC_EEDGE;
11027                                 goto done;
11028                         }
11029                 }
11030                 /*
11031                  * As an optimization, adjust I/O parameters when the fastest 
11032                  * dimension has unity stride both externally and internally.
11033                  * In this case, the user could have called a simpler routine
11034                  * (i.e. ncvarnc_put_vara_float()
11035                  */
11036                 if (mystride[maxidim] == 1
11037                         && mymap[maxidim] == 1)
11038                 {
11039                         iocount[maxidim] = myedges[maxidim];
11040                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
11041                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
11042                 }
11043 
11044                 /*
11045                  * Perform I/O.  Exit when done.
11046                  */
11047                 for (;;)
11048                 {
11049                         /* TODO: */
11050                         int lstatus = nc_put_vara_float (ncid, varid, mystart, iocount,
11051                                                 value);
11052                         if (lstatus != NC_NOERR 
11053                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
11054                                 status = lstatus;
11055 
11056                         /*
11057                          * The following code permutes through the variable s
11058                          * external start-index space and it s internal address
11059                          * space.  At the UPC, this algorithm is commonly
11060                          * called "odometer code".
11061                          */
11062                         idim = maxidim;
11063                 carry:
11064                         value += mymap[idim];
11065                         mystart[idim] += mystride[idim];
11066                         if (mystart[idim] == stop[idim])
11067                         {
11068                                 mystart[idim] = start[idim];
11069                                 value -= length[idim];
11070                                 if (--idim < 0)
11071                                         break; /* normal return */
11072                                 goto carry;
11073                         }
11074                 } /* I/O loop */
11075         done:
11076                 free(mystart);
11077         } /* variable is array */
11078         return status;
11079 
11080 }
11081 
11082 int
11083 nc_put_varm_double(int ncid, int varid,
11084         const size_t *start, const size_t *edges,
11085         const ptrdiff_t *stride, const ptrdiff_t *map,
11086         const double *value)
11087 {
11088         int status = ENOERR;
11089         NC *ncp;
11090         NC_var *varp;
11091         int maxidim;    /* maximum dimensional index */
11092 
11093         status = NC_check_id (ncid, &ncp);
11094         if (status != NC_NOERR)
11095                 return status;
11096 
11097         if (NC_indef (ncp))
11098         {
11099                 return NC_EINDEFINE;
11100         }
11101 
11102                 if (NC_readonly (ncp))
11103                         return NC_EPERM;
11104         varp = NC_lookupvar (ncp, varid);
11105         if (varp == NULL)
11106                 return NC_ENOTVAR;
11107 
11108         if(varp->type == NC_CHAR)
11109                 return NC_ECHAR;
11110 
11111         maxidim = (int) varp->ndims - 1;
11112 
11113         if (maxidim < 0)
11114         {
11115                 /*
11116                  * The variable is a scalar; consequently,
11117                  * there s only one thing to get and only one place to put it.
11118                  * (Why was I called?)
11119                  */
11120                 return putNCv_double (ncp, varp, start, 1, value);
11121         }
11122         
11123         /*
11124          * else
11125          * The variable is an array.
11126          */
11127         {
11128                 int idim;
11129                 size_t *mystart = NULL;
11130                 size_t *myedges;
11131                 size_t *iocount;        /* count vector */
11132                 size_t *stop;   /* stop indexes */
11133                 size_t *length; /* edge lengths in bytes */
11134                 ptrdiff_t *mystride;
11135                 ptrdiff_t *mymap;
11136 
11137                 /*
11138                  * Verify stride argument.
11139                  */
11140                 for (idim = 0; idim <= maxidim; ++idim)
11141                 {
11142                         if (stride != NULL
11143                                 && (stride[idim] == 0
11144                 /* cast needed for braindead systems with signed size_t */
11145                                 || (unsigned long) stride[idim] >= X_INT_MAX))
11146                         {
11147                                 return NC_ESTRIDE;
11148                         }
11149                 }
11150 
11151                 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
11152                 mystart = (size_t *)calloc(varp->ndims * 7, sizeof(ptrdiff_t));
11153                 if(mystart == NULL)
11154                         return NC_ENOMEM;
11155                 myedges = mystart + varp->ndims;
11156                 iocount = myedges + varp->ndims;
11157                 stop = iocount + varp->ndims;
11158                 length = stop + varp->ndims;
11159                 mystride = (ptrdiff_t *)(length + varp->ndims);
11160                 mymap = mystride + varp->ndims;
11161 
11162                 /*
11163                  * Initialize I/O parameters.
11164                  */
11165                 for (idim = maxidim; idim >= 0; --idim)
11166                 {
11167                         mystart[idim] = start != NULL
11168                                 ? start[idim]
11169                                 : 0;
11170 
11171                         if (edges[idim] == 0)
11172                         {
11173                                 status = NC_NOERR;      /* read/write no data */
11174                                 goto done;
11175                         }
11176 
11177                         myedges[idim] = edges != NULL
11178                                 ? edges[idim]
11179                                 : idim == 0 && IS_RECVAR (varp)
11180                                 ? NC_get_numrecs(ncp) - mystart[idim]
11181                                 : varp->shape[idim] - mystart[idim];
11182                         mystride[idim] = stride != NULL
11183                                 ? stride[idim]
11184                                 : 1;
11185                         mymap[idim] = map != NULL
11186                                 ? map[idim]
11187                                 : idim == maxidim
11188                                 ? 1
11189                                 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
11190 
11191                         iocount[idim] = 1;
11192                         length[idim] = mymap[idim] * myedges[idim];
11193                         stop[idim] = mystart[idim] + myedges[idim] * mystride[idim];
11194                 }
11195 
11196                 /*
11197                  * Check start, edges
11198                  */
11199                 for (idim = IS_RECVAR (varp); idim < maxidim; ++idim)
11200                 {
11201                         if (mystart[idim] >= varp->shape[idim])
11202                         {
11203                                 status = NC_EINVALCOORDS;
11204                                 goto done;
11205                         }
11206                         if (mystart[idim] + myedges[idim] > varp->shape[idim])
11207                         {
11208                                 status = NC_EEDGE;
11209                                 goto done;
11210                         }
11211                 }
11212                 /*
11213                  * As an optimization, adjust I/O parameters when the fastest 
11214                  * dimension has unity stride both externally and internally.
11215                  * In this case, the user could have called a simpler routine
11216                  * (i.e. ncvarnc_put_vara_double()
11217                  */
11218                 if (mystride[maxidim] == 1
11219                         && mymap[maxidim] == 1)
11220                 {
11221                         iocount[maxidim] = myedges[maxidim];
11222                         mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
11223                         mymap[maxidim] = (ptrdiff_t) length[maxidim];
11224                 }
11225 
11226                 /*
11227                  * Perform I/O.  Exit when done.
11228                  */
11229                 for (;;)
11230                 {
11231                         /* TODO: */
11232                         int lstatus = nc_put_vara_double (ncid, varid, mystart, iocount,
11233                                                 value);
11234                         if (lstatus != NC_NOERR 
11235                                 && (status == NC_NOERR || lstatus != NC_ERANGE))
11236                                 status = lstatus;
11237 
11238                         /*
11239                          * The following code permutes through the variable s
11240                          * external start-index space and it s internal address
11241                          * space.  At the UPC, this algorithm is commonly
11242                          * called "odometer code".
11243                          */
11244                         idim = maxidim;
11245                 carry:
11246                         value += mymap[idim];
11247                         mystart[idim] += mystride[idim];
11248                         if (mystart[idim] == stop[idim])
11249                         {
11250                                 mystart[idim] = start[idim];
11251                                 value -= length[idim];
11252                                 if (--idim < 0)
11253                                         break; /* normal return */
11254                                 goto carry;
11255                         }
11256                 } /* I/O loop */
11257         done:
11258                 free(mystart);
11259         } /* variable is array */
11260         return status;
11261 
11262 }
11263 
11264 
11265 
11266 /* deprecated, used to support the 2.x interface */
11267 int
11268 nc_put_varm (
11269         int ncid,
11270         int varid,
11271         const size_t * start,
11272         const size_t * edges,
11273         const ptrdiff_t * stride,
11274         const ptrdiff_t * map,
11275         const void *value)
11276 {
11277         int status;
11278         NC *ncp;
11279         const NC_var *varp;
11280         ptrdiff_t *cvtmap = NULL;
11281 
11282         status = NC_check_id(ncid, &ncp); 
11283         if(status != NC_NOERR)
11284                 return status;
11285 
11286         varp = NC_lookupvar(ncp, varid);
11287         if(varp == NULL)
11288                 return NC_ENOTVAR;
11289 
11290         if(map != NULL && varp->ndims != 0)
11291         {
11292                 /*
11293                  * convert map units from bytes to units of sizeof(type)
11294                  */
11295                 size_t ii;
11296                 const ptrdiff_t szof = (ptrdiff_t) nctypelen(varp->type);
11297                 cvtmap = (ptrdiff_t *)calloc(varp->ndims, sizeof(ptrdiff_t));
11298                 if(cvtmap == NULL)
11299                         return NC_ENOMEM;
11300                 for(ii = 0; ii < varp->ndims; ii++)
11301                 {
11302                         if(map[ii] % szof != 0) 
11303                         {
11304                                 free(cvtmap);
11305                                 return NC_EINVAL;
11306                         }
11307                         cvtmap[ii] = map[ii] / szof;
11308                 }
11309                 map = cvtmap;
11310         }
11311 
11312         switch(varp->type){
11313         case NC_CHAR:
11314                 status =  nc_put_varm_text(ncid, varid, start, edges,
11315                         stride, map,
11316                         (const char *) value);
11317                 break;
11318         case NC_BYTE:
11319                 status = nc_put_varm_schar(ncid, varid, start, edges,
11320                         stride, map,
11321                         (const schar *) value);
11322                 break;
11323         case NC_SHORT:
11324                 status = nc_put_varm_short(ncid, varid, start, edges,
11325                         stride, map,
11326                         (const short *) value);
11327                 break;
11328         case NC_INT:
11329 #if (SIZEOF_INT >= X_SIZEOF_INT)
11330                 status = nc_put_varm_int(ncid, varid, start, edges,
11331                         stride, map,
11332                         (const int *) value);
11333 #elif SIZEOF_LONG == X_SIZEOF_INT
11334                 status = nc_put_varm_long(ncid, varid, start, edges,
11335                         stride, map,
11336                         (const long *) value);
11337 #else
11338 #error "nc_put_varm implementation"
11339 #endif
11340                 break;
11341         case NC_FLOAT:
11342                 status = nc_put_varm_float(ncid, varid, start, edges,
11343                         stride, map,
11344                         (const float *) value);
11345                 break;
11346         case NC_DOUBLE: 
11347                 status = nc_put_varm_double(ncid, varid, start, edges,
11348                         stride, map,
11349                         (const double *) value);
11350                 break;
11351         default:
11352                 status = NC_EBADTYPE;
11353                 break;
11354         }
11355 
11356         if(cvtmap != NULL)
11357         {
11358                 free(cvtmap);
11359         }
11360         return status;
11361 }
11362 
11363 
11364 /* Begin recio, deprecated */
11365 
11366 /*
11367  * input 'nelems' items of contiguous data of 'varp' at 'start'
11368  * N.B. this function deprecated.
11369  */
11370 static int
11371 getNCvdata(const NC *ncp, const NC_var *varp,
11372                  const size_t *start, size_t nelems, void *value)
11373 {
11374         switch(varp->type){
11375         case NC_CHAR:
11376                 return getNCvx_char_char(ncp, varp, start, nelems,
11377                         (char *) value);
11378         case NC_BYTE:
11379                 return getNCvx_schar_schar(ncp, varp, start, nelems,
11380                         (schar *) value);
11381         case NC_SHORT:
11382                 return getNCvx_short_short(ncp, varp, start, nelems,
11383                         (short *) value);
11384         case NC_INT:
11385 #if (SIZEOF_INT >= X_SIZEOF_INT)
11386                 return getNCvx_int_int(ncp, varp, start, nelems,
11387                         (int *) value);
11388 #elif SIZEOF_LONG == X_SIZEOF_INT
11389                 return getNCvx_int_long(ncp, varp, start, nelems,
11390                         (long *) value);
11391 #else
11392 #error "getNCvdata implementation"
11393 #endif
11394         case NC_FLOAT:
11395                 return getNCvx_float_float(ncp, varp, start, nelems,
11396                         (float *) value);
11397         case NC_DOUBLE: 
11398                 return getNCvx_double_double(ncp, varp, start, nelems,
11399                         (double *) value);
11400         }
11401         return NC_EBADTYPE;
11402 }
11403 
11404 
11405 /*
11406  * output 'nelems' items of contiguous data of 'varp' at 'start'
11407  * N.B. this function deprecated.
11408  */
11409 static int
11410 putNCvdata(NC *ncp, const NC_var *varp,
11411                  const size_t *start, size_t nelems, const void *value)
11412 {
11413         switch(varp->type){
11414         case NC_CHAR:
11415                 return putNCvx_char_char(ncp, varp, start, nelems,
11416                         (const char *) value);
11417         case NC_BYTE:
11418                 return putNCvx_schar_schar(ncp, varp, start, nelems,
11419                         (const schar *) value);
11420         case NC_SHORT:
11421                 return putNCvx_short_short(ncp, varp, start, nelems,
11422                         (const short *) value);
11423         case NC_INT:
11424 #if (SIZEOF_INT >= X_SIZEOF_INT)
11425                 return putNCvx_int_int(ncp, varp, start, nelems,
11426                         (const int *) value);
11427 #elif SIZEOF_LONG == X_SIZEOF_INT
11428                 return putNCvx_long_int(ncp, varp, start, nelems,
11429                         (const long *) value);
11430 #else
11431 #error "putNCvdata implementation"
11432 #endif
11433         case NC_FLOAT:
11434                 return putNCvx_float_float(ncp, varp, start, nelems,
11435                         (const float *) value);
11436         case NC_DOUBLE: 
11437                 return putNCvx_double_double(ncp, varp, start, nelems,
11438                         (const double *) value);
11439         }
11440         return NC_EBADTYPE;
11441 }
11442 
11443 
11444 static size_t
11445 NCelemsPerRec(
11446         const NC_var *varp)
11447 {
11448         size_t nelems = 1;
11449         size_t jj;
11450         for(jj = 1; jj < varp->ndims; jj++)     
11451                 nelems *= varp->shape[jj];
11452         return nelems;
11453 }
11454 
11455 
11456 /*
11457  * Retrieves the number of record variables, the record variable ids, and the
11458  * record size of each record variable.  If any pointer to info to be returned
11459  * is null, the associated information is not returned.  Returns -1 on error.
11460  */
11461 int
11462 nc_inq_rec(
11463         int ncid,
11464         size_t *nrecvars,
11465         int *recvarids,
11466         size_t *recsizes)
11467 {
11468         NC *ncp;
11469 
11470    {
11471         const int status = NC_check_id(ncid, &ncp); 
11472         if(status != NC_NOERR)
11473                 return status;
11474    }
11475 
11476    {
11477         size_t nrvars = 0;
11478         size_t ii = 0;
11479         for(; ii < ncp->vars.nelems; ii++)
11480         {
11481                 const NC_var *const varp = ncp->vars.value[ii];
11482                 if(!IS_RECVAR(varp))
11483                         continue;
11484 
11485                 if(recvarids != NULL)
11486                         recvarids[nrvars] = (int) ii;
11487                 if(recsizes != NULL)
11488                 {
11489                         *recsizes++ = nctypelen(varp->type)
11490                                  * NCelemsPerRec(varp);
11491                 }
11492                 nrvars++;
11493         }
11494 
11495         if(nrecvars != NULL)
11496                 *nrecvars = nrvars;
11497     }
11498 
11499         return NC_NOERR;
11500 }
11501 
11502 
11503 static int
11504 NCrecput(
11505         NC *ncp,
11506         size_t recnum,
11507         void *const *datap)
11508 {
11509         int status = NC_NOERR;
11510         size_t nrvars = 0;
11511         NC_var *varp;
11512         size_t ii;
11513         size_t iocount;
11514         ALLOC_ONSTACK(coord, size_t, ncp->dims.nelems);
11515 
11516         assert(ncp->dims.nelems != 0);
11517 
11518         (void) memset(coord, 0, ncp->dims.nelems * sizeof(size_t));
11519         coord[0] = recnum;
11520         for(ii = 0; ii < ncp->vars.nelems; ii++)
11521         {
11522                 varp = ncp->vars.value[ii];
11523                 if(!IS_RECVAR(varp))
11524                         continue;
11525                 /* else */
11526                 nrvars++;
11527                 if(*datap == NULL)
11528                 {
11529                         datap++;
11530                         continue;
11531                 }
11532                 /* else */
11533                 iocount = NCelemsPerRec(varp);
11534                 status = putNCvdata(ncp, varp, coord, iocount, *datap++);
11535                 if(status != NC_NOERR)
11536                         break;
11537         }
11538         if(nrvars == 0 && status == NC_NOERR)
11539         {
11540                 status = NC_ENORECVARS;
11541         }
11542                 
11543         FREE_ONSTACK(coord);
11544         return status;
11545 }
11546 
11547 
11548 static int
11549 NCrecget(
11550         NC *ncp,
11551         size_t recnum,
11552         void **datap)
11553 {
11554         int status = NC_NOERR;
11555         size_t nrvars = 0;
11556         NC_var *varp;
11557         size_t ii;
11558         size_t iocount;
11559         ALLOC_ONSTACK(coord, size_t, ncp->dims.nelems);
11560 
11561         assert(ncp->dims.nelems != 0);
11562 
11563         (void) memset(coord, 0, ncp->dims.nelems * sizeof(size_t));
11564         coord[0] = recnum;
11565         for(ii = 0; ii < ncp->vars.nelems; ii++)
11566         {
11567                 varp = ncp->vars.value[ii];
11568                 if(!IS_RECVAR(varp))
11569                         continue;
11570                 /* else */
11571                 nrvars++;
11572                 if(*datap == NULL)
11573                 {
11574                         datap++;
11575                         continue;
11576                 }
11577                 /* else */
11578                 iocount = NCelemsPerRec(varp);
11579                 status = getNCvdata(ncp, varp, coord, iocount, *datap++);
11580                 if(status != NC_NOERR)
11581                         break;
11582         }
11583         if(nrvars == 0 && status == NC_NOERR)
11584         {
11585                 status = NC_ENORECVARS;
11586         }
11587 
11588         FREE_ONSTACK(coord);
11589         return status;
11590 }
11591 
11592 
11593 /*
11594  * Write one record's worth of data, except don't write to variables for which
11595  * the address of the data to be written is null.  Return -1 on error.
11596  */
11597 int
11598 nc_put_rec(
11599         int ncid,
11600         size_t recnum,
11601         void * const *datap)
11602 {
11603         int status;
11604         NC *ncp;
11605 
11606         status = NC_check_id(ncid, &ncp); 
11607         if(status != NC_NOERR)
11608                 return status;
11609 
11610         if(NC_readonly(ncp))
11611         {
11612                 return NC_EPERM;
11613         }
11614 
11615         if(NC_indef(ncp))
11616         {
11617                 return NC_EINDEFINE;
11618         }
11619 
11620         status = NCvnrecs(ncp, recnum +1);
11621         if(status != NC_NOERR)
11622                 return status;
11623 
11624         return( NCrecput(ncp, recnum, datap) );
11625 }
11626 
11627 
11628 /*
11629  * Read one record's worth of data, except don't read from variables for which
11630  * the address of the data to be read is null.  Return -1 on error;
11631  */
11632 int
11633 nc_get_rec(
11634         int ncid,
11635         size_t recnum,
11636         void **datap)
11637 {
11638         int status;
11639         NC *ncp;
11640 
11641         status = NC_check_id(ncid, &ncp); 
11642         if(status != NC_NOERR)
11643                 return status;
11644 
11645         if(NC_indef(ncp))
11646         {
11647                 return NC_EINDEFINE;
11648         }
11649 
11650         if(recnum >= NC_get_numrecs(ncp))
11651         {
11652                 return NC_EINVALCOORDS;
11653         }
11654 
11655         return( NCrecget(ncp, recnum, datap) );
11656 }
11657 
11658 
11659 /*
11660  * Copy the values of a variable from an input netCDF to an output netCDF.
11661  * Input and output var assummed to have the same shape.
11662  * return -1 on error.
11663  */
11664 int
11665 nc_copy_var(int ncid_in, int varid, int ncid_out)
11666 {
11667         int status = NC_NOERR;
11668         NC *inncp, *outncp;
11669         NC_var *invp, *outvp;
11670 
11671         status = NC_check_id(ncid_in, &inncp); 
11672         if(status != NC_NOERR)
11673                 return status;
11674 
11675 
11676         if(NC_indef(inncp))
11677         {
11678                 return NC_EINDEFINE;
11679         }
11680 
11681         status = NC_check_id(ncid_out, &outncp); 
11682         if(status != NC_NOERR)
11683                 return status;
11684 
11685         if(NC_readonly(outncp))
11686         {
11687                 /* output file isn't writable */
11688                 return NC_EPERM;
11689         }
11690 
11691         if(NC_indef(outncp))
11692         {
11693                 return NC_EINDEFINE;
11694         }
11695 
11696         /* find the variable in the input cdf */
11697         invp = NC_lookupvar(inncp, varid);
11698         if(invp == NULL)
11699         {
11700                 return NC_ENOTVAR;
11701         }
11702 
11703         /* find the variable in the output cdf */
11704         if(NC_findvar(&outncp->vars, invp->name->cp, &outvp) == -1)
11705         {
11706                 return NC_ENOTVAR;
11707         }
11708 
11709         /* can we even attempt to copy without conversion? */
11710         if(outvp->type != invp->type)
11711         {
11712                 return NC_EINVAL;
11713         }
11714 
11715         if(        (invp->ndims == 0 && outvp->ndims != 0)
11716                 || (invp->ndims != 0 && outvp->ndims == 0)
11717                 || (IS_RECVAR(invp) && !IS_RECVAR(outvp))
11718                 || (!IS_RECVAR(invp) && IS_RECVAR(outvp))
11719                 || (invp->len != outvp->len)
11720         )
11721         {
11722                 return NC_EINVAL;
11723         }
11724 
11725         /*
11726          * Check coordinates
11727          */
11728         {
11729         ALLOC_ONSTACK(coord, size_t, invp->ndims);
11730         const size_t nrecs = NC_get_numrecs(inncp);
11731         (void) memcpy(coord, invp->shape, invp->ndims * sizeof(size_t));
11732         if(IS_RECVAR(invp))
11733                 *coord = nrecs;
11734         
11735         {
11736         size_t ii = 0;
11737         for(; ii < invp->ndims; ii++)
11738                 coord[ii] --;
11739         }
11740         /* at this point, coord is the largest valid coord of invp */
11741 
11742         if(NCcoordck(outncp, outvp, coord) != NC_NOERR)
11743         {
11744                 return NC_EINVAL;
11745         }
11746         /* else */
11747 
11748         (void) memset(coord, 0, invp->ndims * sizeof(size_t));
11749         
11750         if(!IS_RECVAR(invp))
11751         {
11752                 status = NCxvarcpy(inncp, invp, coord,
11753                                 outncp, outvp, coord,
11754                                 invp->len);
11755                 goto done;
11756         }
11757         /* else */
11758 
11759         status = NCvnrecs(outncp, nrecs);
11760         if(status != NC_NOERR)
11761                 goto done;
11762 
11763         for( /*NADA*/; *coord < nrecs; (*coord)++)
11764         {
11765                 status = NCxvarcpy(inncp, invp, coord,
11766                                 outncp, outvp, coord,
11767                                 invp->len);
11768                 if(status != NC_NOERR)
11769                         break;
11770         }
11771 done:
11772         FREE_ONSTACK(coord);
11773         }
11774         return status;
11775 }
 

Powered by Plone

This site conforms to the following standards: