NetCDF
4.3.2
|
00001 00008 #ifndef NO_NETCDF_2 00009 00010 #include <config.h> 00011 #include <stdlib.h> 00012 #include <stdio.h> 00013 #include <stdarg.h> 00014 #include "netcdf.h" 00015 #include "math.h" 00016 /* The subroutines in error.c emit no messages unless NC_VERBOSE bit 00017 * is on. They call exit() when NC_FATAL bit is on. */ 00018 int ncopts = (NC_FATAL | NC_VERBOSE) ; 00019 int ncerr = NC_NOERR ; 00020 00021 #if SIZEOF_LONG == SIZEOF_SIZE_T 00022 /* 00023 * We don't have to copy the arguments to switch from 'long' 00024 * to 'size_t' or 'ptrdiff_t'. Use dummy macros. 00025 */ 00026 00027 # define NDIMS_DECL 00028 # define A_DECL(name, type, ndims, rhs) \ 00029 const type *const name = ((const type *)(rhs)) 00030 00031 # define A_FREE(name) 00032 00033 # define A_INIT(lhs, type, ndims, rhs) 00034 00035 #else 00036 /* 00037 * We do have to copy the arguments to switch from 'long' 00038 * to 'size_t' or 'ptrdiff_t'. In my tests on an SGI, 00039 * any additional cost was lost in measurement variation. 00040 * 00041 * This stanza is true on Windows with MinGW-64 00042 */ 00043 00044 # include "onstack.h" 00045 00046 static int 00047 nvdims(int ncid, int varid) 00048 { 00049 int ndims=-1, status; 00050 00051 if ((status = nc_inq_varndims(ncid, varid, &ndims))) 00052 { 00053 nc_advise("ncvdims", status, "ncid %d", ncid); 00054 return -1; 00055 } 00056 return ndims; 00057 } 00058 00059 /* Used to avoid errors on 64-bit windows related to 00060 c89 macros and flow control/conditionals. */ 00061 static void* nvmalloc(off_t size) { 00062 if(size < 0) 00063 return NULL; 00064 00065 return malloc(size); 00066 00067 } 00068 00069 #define NDIMS_DECL const int ndims = nvdims(ncid, varid); \ 00070 00071 00072 # define A_DECL(name, type, ndims, rhs) \ 00073 type *const name = (type*) nvmalloc((ndims) * sizeof(type)) 00074 00075 00076 // ALLOC_ONSTACK(name, type, ndims) 00077 00078 00079 # define A_FREE(name) \ 00080 FREE_ONSTACK(name) 00081 00082 # define A_INIT(lhs, type, ndims, rhs) \ 00083 { \ 00084 if((off_t)ndims >= 0) { \ 00085 const long *lp = rhs; \ 00086 type *tp = lhs; \ 00087 type *const end = lhs + ndims; \ 00088 while(tp < end) \ 00089 { \ 00090 *tp++ = (type) *lp++; \ 00091 } \ 00092 } \ 00093 } \ 00094 \ 00095 if ((off_t)ndims < 0) {nc_advise("nvdims",NC_EMAXDIMS,"ndims %d",ndims); return -1;} 00096 00097 00098 #endif 00099 00100 typedef signed char schar; 00101 00102 /* 00103 * Computes number of record variables in an open netCDF file, and an array of 00104 * the record variable ids, if the array parameter is non-null. 00105 */ 00106 static int 00107 numrecvars(int ncid, int* nrecvarsp, int *recvarids) 00108 { 00109 int status = NC_NOERR; 00110 int nvars = 0; 00111 int ndims = 0; 00112 int nrecvars = 0; 00113 int varid; 00114 int recdimid; 00115 int dimids[MAX_NC_DIMS]; 00116 00117 status = nc_inq_nvars(ncid, &nvars); 00118 if(status != NC_NOERR) 00119 return status; 00120 00121 status = nc_inq_unlimdim(ncid, &recdimid); 00122 if(status != NC_NOERR) 00123 return status; 00124 00125 if (recdimid == -1) { 00126 *nrecvarsp = 0; 00127 return NC_NOERR; 00128 } 00129 nrecvars = 0; 00130 for (varid = 0; varid < nvars; varid++) { 00131 status = nc_inq_varndims(ncid, varid, &ndims); 00132 if(status != NC_NOERR) 00133 return status; 00134 status = nc_inq_vardimid(ncid, varid, dimids); 00135 if(status != NC_NOERR) 00136 return status; 00137 if (ndims > 0 && dimids[0] == recdimid) { 00138 if (recvarids != NULL) 00139 recvarids[nrecvars] = varid; 00140 nrecvars++; 00141 } 00142 } 00143 *nrecvarsp = nrecvars; 00144 return NC_NOERR; 00145 } 00146 00147 00148 /* 00149 * Computes record size (in bytes) of the record variable with a specified 00150 * variable id. Returns size as 0 if not a record variable. 00151 */ 00152 static int 00153 ncrecsize(int ncid, int varid, size_t *recsizep) 00154 { 00155 int status = NC_NOERR; 00156 int recdimid; 00157 nc_type type; 00158 int ndims; 00159 int dimids[MAX_NC_DIMS]; 00160 int id; 00161 int size; 00162 00163 *recsizep = 0; 00164 status = nc_inq_unlimdim(ncid, &recdimid); 00165 if(status != NC_NOERR) 00166 return status; 00167 status = nc_inq_vartype(ncid, varid, &type); 00168 if(status != NC_NOERR) 00169 return status; 00170 status = nc_inq_varndims(ncid, varid, &ndims); 00171 if(status != NC_NOERR) 00172 return status; 00173 status = nc_inq_vardimid(ncid, varid, dimids); 00174 if(status != NC_NOERR) 00175 return status; 00176 if (ndims == 0 || dimids[0] != recdimid) { 00177 return NC_NOERR; 00178 } 00179 size = nctypelen(type); 00180 for (id = 1; id < ndims; id++) { 00181 size_t len; 00182 status = nc_inq_dimlen(ncid, dimids[id], &len); 00183 if(status != NC_NOERR) 00184 return status; 00185 size *= (int)len; 00186 } 00187 *recsizep = (size_t)size; 00188 return NC_NOERR; 00189 } 00190 00191 00192 /* 00193 * Retrieves the dimension sizes of a variable with a specified variable id in 00194 * an open netCDF file. Returns -1 on error. 00195 */ 00196 static int 00197 dimsizes(int ncid, int varid, size_t *sizes) 00198 { 00199 int status = NC_NOERR; 00200 int ndims; 00201 int id; 00202 int dimids[MAX_NC_DIMS]; 00203 00204 status = nc_inq_varndims(ncid, varid, &ndims); 00205 if(status != NC_NOERR) 00206 return status; 00207 status = nc_inq_vardimid(ncid, varid, dimids); 00208 if(status != NC_NOERR) 00209 return status; 00210 if (ndims == 0 || sizes == NULL) 00211 return NC_NOERR; 00212 for (id = 0; id < ndims; id++) { 00213 size_t len; 00214 status = nc_inq_dimlen(ncid, dimids[id], &len); 00215 if(status != NC_NOERR) 00216 return status; 00217 sizes[id] = len; 00218 } 00219 return NC_NOERR; 00220 } 00221 00222 00223 /* 00224 * Retrieves the number of record variables, the record variable ids, and the 00225 * record size of each record variable. If any pointer to info to be returned 00226 * is null, the associated information is not returned. Returns -1 on error. 00227 */ 00228 int 00229 nc_inq_rec( 00230 int ncid, 00231 size_t *nrecvarsp, 00232 int *recvarids, 00233 size_t *recsizes) 00234 { 00235 int status = NC_NOERR; 00236 int nvars = 0; 00237 int recdimid; 00238 int varid; 00239 int rvarids[MAX_NC_VARS]; 00240 int nrvars = 0; 00241 00242 status = nc_inq_nvars(ncid, &nvars); 00243 if(status != NC_NOERR) 00244 return status; 00245 00246 status = nc_inq_unlimdim(ncid, &recdimid); 00247 if(status != NC_NOERR) 00248 return status; 00249 00250 *nrecvarsp = 0; 00251 if (recdimid == -1) 00252 return NC_NOERR; 00253 00254 status = numrecvars(ncid, &nrvars, rvarids); 00255 if(status != NC_NOERR) 00256 return status; 00257 00258 if (nrecvarsp != NULL) 00259 *nrecvarsp = (size_t)nrvars; 00260 if (recvarids != NULL) 00261 for (varid = 0; varid < nrvars; varid++) 00262 recvarids[varid] = rvarids[varid]; 00263 00264 if (recsizes != NULL) 00265 for (varid = 0; varid < nrvars; varid++) { 00266 size_t rsize; 00267 status = ncrecsize(ncid, rvarids[varid], &rsize); 00268 if (status != NC_NOERR) 00269 return status; 00270 recsizes[varid] = rsize; 00271 } 00272 return NC_NOERR; 00273 } 00274 00275 00276 /* 00277 * Write one record's worth of data, except don't write to variables for which 00278 * the address of the data to be written is NULL. Return -1 on error. This is 00279 * the same as the ncrecput() in the library, except that can handle errors 00280 * better. 00281 */ 00282 int 00283 nc_put_rec( 00284 int ncid, 00285 size_t recnum, 00286 void* const* datap) 00287 { 00288 int status = NC_NOERR; 00289 int varid; 00290 int rvarids[MAX_NC_VARS]; 00291 int nrvars; 00292 size_t start[MAX_NC_DIMS]; 00293 size_t edges[MAX_NC_DIMS]; 00294 00295 status = numrecvars(ncid, &nrvars, rvarids); 00296 if(status != NC_NOERR) 00297 return status; 00298 00299 if (nrvars == 0) 00300 return NC_NOERR; 00301 00302 start[0] = recnum; 00303 for (varid = 1; varid < nrvars; varid++) 00304 start[varid] = 0; 00305 00306 for (varid = 0; varid < nrvars; varid++) { 00307 if (datap[varid] != NULL) { 00308 status = dimsizes(ncid, rvarids[varid], edges); 00309 if(status != NC_NOERR) 00310 return status; 00311 00312 edges[0] = 1; /* only 1 record's worth */ 00313 status = nc_put_vara(ncid, rvarids[varid], start, edges, datap[varid]); 00314 if(status != NC_NOERR) 00315 return status; 00316 } 00317 } 00318 return 0; 00319 } 00320 00321 00322 /* 00323 * Read one record's worth of data, except don't read from variables for which 00324 * the address of the data to be read is null. Return -1 on error. This is 00325 * the same as the ncrecget() in the library, except that can handle errors 00326 * better. 00327 */ 00328 int 00329 nc_get_rec( 00330 int ncid, 00331 size_t recnum, 00332 void **datap) 00333 { 00334 int status = NC_NOERR; 00335 int varid; 00336 int rvarids[MAX_NC_VARS]; 00337 int nrvars; 00338 size_t start[MAX_NC_DIMS]; 00339 size_t edges[MAX_NC_DIMS]; 00340 00341 status = numrecvars(ncid, &nrvars, rvarids); 00342 if(status != NC_NOERR) 00343 return status; 00344 00345 if (nrvars == 0) 00346 return NC_NOERR; 00347 00348 start[0] = recnum; 00349 for (varid = 1; varid < nrvars; varid++) 00350 start[varid] = 0; 00351 00352 for (varid = 0; varid < nrvars; varid++) { 00353 if (datap[varid] != NULL) { 00354 status = dimsizes(ncid, rvarids[varid], edges); 00355 if(status != NC_NOERR) 00356 return status; 00357 edges[0] = 1; /* only 1 record's worth */ 00358 status = nc_get_vara(ncid, rvarids[varid], start, edges, datap[varid]); 00359 if(status != NC_NOERR) 00360 return status; 00361 } 00362 } 00363 return 0; 00364 } 00365 00366 /* 00367 */ 00368 void 00369 nc_advise(const char *routine_name, int err, const char *fmt,...) 00370 { 00371 va_list args; 00372 00373 if(NC_ISSYSERR(err)) 00374 ncerr = NC_SYSERR; 00375 else 00376 ncerr = err; 00377 00378 if( ncopts & NC_VERBOSE ) 00379 { 00380 (void) fprintf(stderr,"%s: ", routine_name); 00381 va_start(args ,fmt); 00382 (void) vfprintf(stderr,fmt,args); 00383 va_end(args); 00384 if(err != NC_NOERR) 00385 { 00386 (void) fprintf(stderr,": %s", 00387 nc_strerror(err)); 00388 } 00389 (void) fputc('\n',stderr); 00390 (void) fflush(stderr); /* to ensure log files are current */ 00391 } 00392 00393 if( (ncopts & NC_FATAL) && err != NC_NOERR ) 00394 { 00395 exit(ncopts); 00396 } 00397 } 00398 00399 /* End error handling */ 00400 00401 int 00402 nccreate(const char* path, int cmode) 00403 { 00404 int ncid; 00405 const int status = nc_create(path, cmode, &ncid); 00406 if(status != NC_NOERR) 00407 { 00408 nc_advise("nccreate", status, "filename \"%s\"", path); 00409 return -1; 00410 } 00411 return ncid; 00412 } 00413 00414 00415 int 00416 ncopen(const char *path, int mode) 00417 { 00418 int ncid; 00419 const int status = nc_open(path, mode, &ncid); 00420 if(status != NC_NOERR) 00421 { 00422 nc_advise("ncopen", status, "filename \"%s\"", path); 00423 return -1; 00424 } 00425 return ncid; 00426 } 00427 00428 00429 int 00430 ncredef(int ncid) 00431 { 00432 const int status = nc_redef(ncid); 00433 if(status != NC_NOERR) 00434 { 00435 nc_advise("ncredef", status, "ncid %d", ncid); 00436 return -1; 00437 } 00438 return 0; 00439 } 00440 00441 00442 int 00443 ncendef(int ncid) 00444 { 00445 const int status = nc_enddef(ncid); 00446 if(status != NC_NOERR) 00447 { 00448 nc_advise("ncendef", status, "ncid %d", ncid); 00449 return -1; 00450 } 00451 return 0; 00452 } 00453 00454 00455 int 00456 ncclose(int ncid) 00457 { 00458 const int status = nc_close(ncid); 00459 if(status != NC_NOERR) 00460 { 00461 nc_advise("ncclose", status, "ncid %d", ncid); 00462 return -1; 00463 00464 } 00465 return 0; 00466 } 00467 00468 00469 int 00470 ncinquire( 00471 int ncid, 00472 int* ndims, 00473 int* nvars, 00474 int* natts, 00475 int* recdim 00476 ) 00477 { 00478 int nd, nv, na; 00479 const int status = nc_inq(ncid, &nd, &nv, &na, recdim); 00480 00481 if(status != NC_NOERR) 00482 { 00483 nc_advise("ncinquire", status, "ncid %d", ncid); 00484 return -1; 00485 } 00486 /* else */ 00487 00488 if(ndims != NULL) 00489 *ndims = (int) nd; 00490 00491 if(nvars != NULL) 00492 *nvars = (int) nv; 00493 00494 if(natts != NULL) 00495 *natts = (int) na; 00496 00497 return ncid; 00498 } 00499 00500 00501 int 00502 ncsync(int ncid) 00503 { 00504 const int status = nc_sync(ncid); 00505 if(status != NC_NOERR) 00506 { 00507 nc_advise("ncsync", status, "ncid %d", ncid); 00508 return -1; 00509 00510 } 00511 return 0; 00512 } 00513 00514 00515 int 00516 ncabort(int ncid) 00517 { 00518 const int status = nc_abort(ncid); 00519 if(status != NC_NOERR) 00520 { 00521 nc_advise("ncabort", status, "ncid %d", ncid); 00522 return -1; 00523 } 00524 return 0; 00525 } 00526 00527 00528 int 00529 ncdimdef( 00530 int ncid, 00531 const char* name, 00532 long length 00533 ) 00534 { 00535 int dimid; 00536 int status = NC_NOERR; 00537 if(length < 0) { 00538 status = NC_EDIMSIZE; 00539 nc_advise("ncdimdef", status, "ncid %d", ncid); 00540 return -1; 00541 } 00542 status = nc_def_dim(ncid, name, (size_t)length, &dimid); 00543 if(status != NC_NOERR) 00544 { 00545 nc_advise("ncdimdef", status, "ncid %d", ncid); 00546 return -1; 00547 } 00548 return dimid; 00549 } 00550 00551 00552 int 00553 ncdimid(int ncid, const char* name) 00554 { 00555 int dimid; 00556 const int status = nc_inq_dimid(ncid, name, &dimid); 00557 if(status != NC_NOERR) 00558 { 00559 nc_advise("ncdimid", status, "ncid %d", ncid); 00560 return -1; 00561 } 00562 return dimid; 00563 } 00564 00565 00566 int 00567 ncdiminq( 00568 int ncid, 00569 int dimid, 00570 char* name, 00571 long* length 00572 ) 00573 { 00574 size_t ll; 00575 const int status = nc_inq_dim(ncid, dimid, name, &ll); 00576 00577 if(status != NC_NOERR) 00578 { 00579 nc_advise("ncdiminq", status, "ncid %d", ncid); 00580 return -1; 00581 } 00582 /* else */ 00583 00584 if(length != NULL) 00585 *length = (int) ll; 00586 00587 return dimid; 00588 } 00589 00590 00591 int 00592 ncdimrename( 00593 int ncid, 00594 int dimid, 00595 const char* name 00596 ) 00597 { 00598 const int status = nc_rename_dim(ncid, dimid, name); 00599 if(status != NC_NOERR) 00600 { 00601 nc_advise("ncdimrename", status, "ncid %d", ncid); 00602 return -1; 00603 } 00604 return dimid; 00605 } 00606 00607 00608 int 00609 ncvardef( 00610 int ncid, 00611 const char* name, 00612 nc_type datatype, 00613 int ndims, 00614 const int* dim 00615 ) 00616 { 00617 int varid = -1; 00618 const int status = nc_def_var(ncid, name, datatype, ndims, dim, &varid); 00619 if(status != NC_NOERR) 00620 { 00621 nc_advise("ncvardef", status, "ncid %d", ncid); 00622 return -1; 00623 } 00624 return varid; 00625 } 00626 00627 00628 int 00629 ncvarid( 00630 int ncid, 00631 const char* name 00632 ) 00633 { 00634 int varid = -1; 00635 const int status = nc_inq_varid(ncid, name, &varid); 00636 if(status != NC_NOERR) 00637 { 00638 nc_advise("ncvarid", status, "ncid %d", ncid); 00639 return -1; 00640 } 00641 return varid; 00642 } 00643 00644 00645 int 00646 ncvarinq( 00647 int ncid, 00648 int varid, 00649 char* name, 00650 nc_type* datatype, 00651 int* ndims, 00652 int* dim, 00653 int* natts 00654 ) 00655 { 00656 int nd, na; 00657 const int status = nc_inq_var(ncid, varid, name, datatype, 00658 &nd, dim, &na); 00659 00660 if(status != NC_NOERR) 00661 { 00662 nc_advise("ncvarinq", status, "ncid %d", ncid); 00663 return -1; 00664 } 00665 /* else */ 00666 00667 if(ndims != NULL) 00668 *ndims = (int) nd; 00669 00670 if(natts != NULL) 00671 *natts = (int) na; 00672 00673 return varid; 00674 } 00675 00676 00677 int 00678 ncvarput1( 00679 int ncid, 00680 int varid, 00681 const long* index, 00682 const void* value 00683 ) 00684 { 00685 NDIMS_DECL 00686 A_DECL(coordp, size_t, (size_t)ndims, index); 00687 A_INIT(coordp, size_t, (size_t)ndims, index); 00688 { 00689 const int status = nc_put_var1(ncid, varid, coordp, value); 00690 A_FREE(coordp); 00691 if(status != NC_NOERR) 00692 { 00693 nc_advise("ncvarput1", status, "ncid %d", ncid); 00694 return -1; 00695 } 00696 } 00697 return 0; 00698 } 00699 00700 00701 int 00702 ncvarget1( 00703 int ncid, 00704 int varid, 00705 const long* index, 00706 void* value 00707 ) 00708 { 00709 NDIMS_DECL 00710 A_DECL(coordp, size_t, ndims, index); 00711 A_INIT(coordp, size_t, ndims, index); 00712 { 00713 const int status = nc_get_var1(ncid, varid, coordp, value); 00714 A_FREE(coordp); 00715 if(status != NC_NOERR) 00716 { 00717 nc_advise("ncdimid", status, "ncid %d", ncid); 00718 return -1; 00719 } 00720 } 00721 return 0; 00722 } 00723 00724 00725 int 00726 ncvarput( 00727 int ncid, 00728 int varid, 00729 const long* start, 00730 const long* count, 00731 const void* value 00732 ) 00733 { 00734 NDIMS_DECL 00735 A_DECL(stp, size_t, ndims, start); 00736 A_DECL(cntp, size_t, ndims, count); 00737 A_INIT(stp, size_t, ndims, start); 00738 A_INIT(cntp, size_t, ndims, count); 00739 { 00740 const int status = nc_put_vara(ncid, varid, stp, cntp, value); 00741 A_FREE(cntp); 00742 A_FREE(stp); 00743 if(status != NC_NOERR) 00744 { 00745 nc_advise("ncvarput", status, "ncid %d", ncid); 00746 return -1; 00747 } 00748 } 00749 return 0; 00750 } 00751 00752 00753 int 00754 ncvarget( 00755 int ncid, 00756 int varid, 00757 const long* start, 00758 const long* count, 00759 void* value 00760 ) 00761 { 00762 NDIMS_DECL 00763 A_DECL(stp, size_t, ndims, start); 00764 A_DECL(cntp, size_t, ndims, count); 00765 A_INIT(stp, size_t, ndims, start); 00766 A_INIT(cntp, size_t, ndims, count); 00767 { 00768 const int status = nc_get_vara(ncid, varid, stp, cntp, value); 00769 A_FREE(cntp); 00770 A_FREE(stp); 00771 if(status != NC_NOERR) 00772 { 00773 nc_advise("ncvarget", status, "ncid %d; varid %d", ncid, varid); 00774 return -1; 00775 } 00776 } 00777 return 0; 00778 } 00779 00780 00781 int 00782 ncvarputs( 00783 int ncid, 00784 int varid, 00785 const long* start, 00786 const long* count, 00787 const long* stride, 00788 const void* value 00789 ) 00790 { 00791 if(stride == NULL) 00792 return ncvarput(ncid, varid, start, count, value); 00793 /* else */ 00794 { 00795 00796 NDIMS_DECL 00797 A_DECL(stp, size_t, ndims, start); 00798 A_DECL(cntp, size_t, ndims, count); 00799 A_DECL(strdp, ptrdiff_t, ndims, stride); 00800 A_INIT(stp, size_t, ndims, start); 00801 A_INIT(cntp, size_t, ndims, count); 00802 A_INIT(strdp, ptrdiff_t, ndims, stride); 00803 { 00804 const int status = nc_put_vars(ncid, varid, stp, cntp, strdp, value); 00805 A_FREE(strdp); 00806 A_FREE(cntp); 00807 A_FREE(stp); 00808 if(status != NC_NOERR) 00809 { 00810 nc_advise("ncvarputs", status, "ncid %d", ncid); 00811 return -1; 00812 } 00813 } 00814 return 0; 00815 } 00816 } 00817 00818 00819 int 00820 ncvargets( 00821 int ncid, 00822 int varid, 00823 const long* start, 00824 const long* count, 00825 const long* stride, 00826 void* value 00827 ) 00828 { 00829 if(stride == NULL) 00830 return ncvarget(ncid, varid, start, count, value); 00831 /* else */ 00832 { 00833 NDIMS_DECL 00834 A_DECL(stp, size_t, ndims, start); 00835 A_DECL(cntp, size_t, ndims, count); 00836 A_DECL(strdp, ptrdiff_t, ndims, stride); 00837 A_INIT(stp, size_t, ndims, start); 00838 A_INIT(cntp, size_t, ndims, count); 00839 A_INIT(strdp, ptrdiff_t, ndims, stride); 00840 { 00841 const int status = nc_get_vars(ncid, varid, stp, cntp, strdp, value); 00842 A_FREE(strdp); 00843 A_FREE(cntp); 00844 A_FREE(stp); 00845 if(status != NC_NOERR) 00846 { 00847 nc_advise("ncvargets", status, "ncid %d", ncid); 00848 return -1; 00849 } 00850 } 00851 return 0; 00852 } 00853 } 00854 00855 00856 int 00857 ncvarputg( 00858 int ncid, 00859 int varid, 00860 const long* start, 00861 const long* count, 00862 const long* stride, 00863 const long* map, 00864 const void* value 00865 ) 00866 { 00867 if(map == NULL) 00868 return ncvarputs(ncid, varid, start, count, stride, value); 00869 /* else */ 00870 { 00871 NDIMS_DECL 00872 A_DECL(stp, size_t, ndims, start); 00873 A_DECL(cntp, size_t, ndims, count); 00874 A_DECL(strdp, ptrdiff_t, ndims, stride); 00875 A_DECL(imp, ptrdiff_t, ndims, map); 00876 A_INIT(stp, size_t, ndims, start); 00877 A_INIT(cntp, size_t, ndims, count); 00878 A_INIT(strdp, ptrdiff_t, ndims, stride); 00879 A_INIT(imp, ptrdiff_t, ndims, map); 00880 { 00881 const int status = nc_put_varm(ncid, varid, 00882 stp, cntp, strdp, imp, value); 00883 A_FREE(imp); 00884 A_FREE(strdp); 00885 A_FREE(cntp); 00886 A_FREE(stp); 00887 if(status != NC_NOERR) 00888 { 00889 nc_advise("ncvarputg", status, "ncid %d", ncid); 00890 return -1; 00891 } 00892 } 00893 return 0; 00894 } 00895 } 00896 00897 00898 int 00899 ncvargetg( 00900 int ncid, 00901 int varid, 00902 const long* start, 00903 const long* count, 00904 const long* stride, 00905 const long* map, 00906 void* value 00907 ) 00908 { 00909 if(map == NULL) 00910 return ncvargets(ncid, varid, start, count, stride, value); 00911 /* else */ 00912 { 00913 NDIMS_DECL 00914 A_DECL(stp, size_t, ndims, start); 00915 A_DECL(cntp, size_t, ndims, count); 00916 A_DECL(strdp, ptrdiff_t, ndims, stride); 00917 A_DECL(imp, ptrdiff_t, ndims, map); 00918 A_INIT(stp, size_t, ndims, start); 00919 A_INIT(cntp, size_t, ndims, count); 00920 A_INIT(strdp, ptrdiff_t, ndims, stride); 00921 A_INIT(imp, ptrdiff_t, ndims, map); 00922 { 00923 const int status = nc_get_varm(ncid, varid, 00924 stp, cntp, strdp, imp, value); 00925 A_FREE(imp); 00926 A_FREE(strdp); 00927 A_FREE(cntp); 00928 A_FREE(stp); 00929 if(status != NC_NOERR) 00930 { 00931 nc_advise("ncvargetg", status, "ncid %d", ncid); 00932 return -1; 00933 } 00934 } 00935 return 0; 00936 } 00937 } 00938 00939 00940 int 00941 ncvarrename( 00942 int ncid, 00943 int varid, 00944 const char* name 00945 ) 00946 { 00947 const int status = nc_rename_var(ncid, varid, name); 00948 if(status != NC_NOERR) 00949 { 00950 nc_advise("ncvarrename", status, "ncid %d", ncid); 00951 return -1; 00952 } 00953 return varid; 00954 } 00955 00956 00957 int 00958 ncattput( 00959 int ncid, 00960 int varid, 00961 const char* name, 00962 nc_type datatype, 00963 int len, 00964 const void* value 00965 ) 00966 { 00967 const int status = nc_put_att(ncid, varid, name, datatype, len, value); 00968 if(status != NC_NOERR) 00969 { 00970 nc_advise("ncattput", status, "ncid %d", ncid); 00971 return -1; 00972 } 00973 return 0; 00974 } 00975 00976 00977 int 00978 ncattinq( 00979 int ncid, 00980 int varid, 00981 const char* name, 00982 nc_type* datatype, 00983 int* len 00984 ) 00985 { 00986 size_t ll; 00987 const int status = nc_inq_att(ncid, varid, name, datatype, &ll); 00988 if(status != NC_NOERR) 00989 { 00990 nc_advise("ncattinq", status, 00991 "ncid %d; varid %d; attname \"%s\"", 00992 ncid, varid, name); 00993 return -1; 00994 } 00995 00996 if(len != NULL) 00997 *len = (int) ll; 00998 00999 return 1; 01000 01001 } 01002 01003 01004 int 01005 ncattget( 01006 int ncid, 01007 int varid, 01008 const char* name, 01009 void* value 01010 ) 01011 { 01012 const int status = nc_get_att(ncid, varid, name, value); 01013 if(status != NC_NOERR) 01014 { 01015 nc_advise("ncattget", status, "ncid %d", ncid); 01016 return -1; 01017 } 01018 return 1; 01019 } 01020 01021 01022 int 01023 ncattcopy( 01024 int ncid_in, 01025 int varid_in, 01026 const char* name, 01027 int ncid_out, 01028 int varid_out 01029 ) 01030 { 01031 const int status = nc_copy_att(ncid_in, varid_in, name, ncid_out, varid_out); 01032 if(status != NC_NOERR) 01033 { 01034 nc_advise("ncattcopy", status, "%s", name); 01035 return -1; 01036 } 01037 return 0; 01038 } 01039 01040 01041 int 01042 ncattname( 01043 int ncid, 01044 int varid, 01045 int attnum, 01046 char* name 01047 ) 01048 { 01049 const int status = nc_inq_attname(ncid, varid, attnum, name); 01050 if(status != NC_NOERR) 01051 { 01052 nc_advise("ncattname", status, "ncid %d", ncid); 01053 return -1; 01054 } 01055 return attnum; 01056 } 01057 01058 01059 int 01060 ncattrename( 01061 int ncid, 01062 int varid, 01063 const char* name, 01064 const char* newname 01065 ) 01066 { 01067 const int status = nc_rename_att(ncid, varid, name, newname); 01068 if(status != NC_NOERR) 01069 { 01070 nc_advise("ncattrename", status, "ncid %d", ncid); 01071 return -1; 01072 } 01073 return 1; 01074 } 01075 01076 01077 int 01078 ncattdel( 01079 int ncid, 01080 int varid, 01081 const char* name 01082 ) 01083 { 01084 const int status = nc_del_att(ncid, varid, name); 01085 if(status != NC_NOERR) 01086 { 01087 nc_advise("ncattdel", status, "ncid %d", ncid); 01088 return -1; 01089 } 01090 return 1; 01091 } 01092 01093 #endif /* NO_NETCDF_2 */ 01094 01095 #ifndef NO_NETCDF_2 01096 01097 int 01098 ncsetfill( 01099 int ncid, 01100 int fillmode 01101 ) 01102 { 01103 int oldmode = -1; 01104 const int status = nc_set_fill(ncid, fillmode, &oldmode); 01105 if(status != NC_NOERR) 01106 { 01107 nc_advise("ncsetfill", status, "ncid %d", ncid); 01108 return -1; 01109 } 01110 return oldmode; 01111 } 01112 01113 01114 int 01115 ncrecinq( 01116 int ncid, 01117 int* nrecvars, 01118 int* recvarids, 01119 long* recsizes 01120 ) 01121 { 01122 size_t nrv = 0; 01123 size_t *rs = NULL; 01124 int status = NC_NOERR; 01125 01126 rs = (size_t*)malloc(sizeof(size_t)*NC_MAX_VARS); 01127 if(rs == NULL) 01128 return NC_ENOMEM; 01129 01130 status = nc_inq_rec(ncid, &nrv, recvarids, rs); 01131 if(status != NC_NOERR) 01132 { 01133 nc_advise("ncrecinq", status, "ncid %d", ncid); 01134 if(rs != NULL) free(rs); 01135 return -1; 01136 } 01137 01138 if(nrecvars != NULL) 01139 *nrecvars = (int) nrv; 01140 01141 if(recsizes != NULL) 01142 { 01143 size_t ii; 01144 for(ii = 0; ii < nrv; ii++) 01145 { 01146 recsizes[ii] = (long) rs[ii]; 01147 } 01148 } 01149 01150 if(rs != NULL) free(rs); 01151 01152 return (int) nrv; 01153 } 01154 01155 01156 int 01157 ncrecget( 01158 int ncid, 01159 long recnum, 01160 void** datap 01161 ) 01162 { 01163 const int status = nc_get_rec(ncid, (size_t)recnum, datap); 01164 if(status != NC_NOERR) 01165 { 01166 nc_advise("ncrecget", status, "ncid %d", ncid); 01167 return -1; 01168 } 01169 return 0; 01170 } 01171 01172 01173 int 01174 ncrecput( 01175 int ncid, 01176 long recnum, 01177 void* const* datap 01178 ) 01179 { 01180 const int status = nc_put_rec(ncid, (size_t)recnum, datap); 01181 if(status != NC_NOERR) 01182 { 01183 nc_advise("ncrecput", status, "ncid %d", ncid); 01184 return -1; 01185 } 01186 return 0; 01187 } 01188 01189 #endif /* NO_NETCDF_2 */