dv2i.c 20 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. /** \file
  2. The V2 API Funtions.
  3. Copyright 1996, University Corporation for Atmospheric Research
  4. See \ref copyright file for copying and redistribution conditions.
  5. */
  6. #ifndef NO_NETCDF_2
  7. #include <config.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include "netcdf.h"
  12. /* The subroutines in error.c emit no messages unless NC_VERBOSE bit
  13. * is on. They call exit() when NC_FATAL bit is on. */
  14. int ncopts = (NC_FATAL | NC_VERBOSE) ;
  15. int ncerr = NC_NOERR ;
  16. #if SIZEOF_LONG == SIZEOF_SIZE_T
  17. /*
  18. * We don't have to copy the arguments to switch from 'long'
  19. * to 'size_t' or 'ptrdiff_t'. Use dummy macros.
  20. */
  21. # define NDIMS_DECL
  22. # define A_DECL(name, type, ndims, rhs) \
  23. const type *const name = ((const type *)(rhs))
  24. # define A_FREE(name)
  25. # define A_INIT(lhs, type, ndims, rhs)
  26. #else
  27. /*
  28. * We do have to copy the arguments to switch from 'long'
  29. * to 'size_t' or 'ptrdiff_t'. In my tests on an SGI,
  30. * any additional cost was lost in measurement variation.
  31. *
  32. * This stanza is true on Windows with MinGW-64
  33. */
  34. # include "onstack.h"
  35. static size_t
  36. nvdims(int ncid, int varid)
  37. {
  38. int ndims=-1, status;
  39. if ((status = nc_inq_varndims(ncid, varid, &ndims)))
  40. {
  41. nc_advise("ncvdims", status, "ncid %d", ncid);
  42. return -1;
  43. }
  44. return ndims;
  45. }
  46. #define NDIMS_DECL const size_t ndims = nvdims(ncid, varid);
  47. # define A_DECL(name, type, ndims, rhs) \
  48. ALLOC_ONSTACK(name, type, ndims)
  49. # define A_FREE(name) \
  50. FREE_ONSTACK(name)
  51. # define A_INIT(lhs, type, ndims, rhs) \
  52. { \
  53. const long *lp = rhs; \
  54. type *tp = lhs; \
  55. type *const end = lhs + ndims; \
  56. while(tp < end) \
  57. { \
  58. *tp++ = (type) *lp++; \
  59. } \
  60. }
  61. #endif
  62. typedef signed char schar;
  63. /*
  64. * Computes number of record variables in an open netCDF file, and an array of
  65. * the record variable ids, if the array parameter is non-null.
  66. */
  67. static int
  68. numrecvars(int ncid, int *nrecvarsp, int *recvarids)
  69. {
  70. int status = NC_NOERR;
  71. int nvars = 0;
  72. int ndims = 0;
  73. int nrecvars = 0;
  74. int varid;
  75. int recdimid;
  76. int dimids[MAX_NC_DIMS];
  77. status = nc_inq_nvars(ncid, &nvars);
  78. if(status != NC_NOERR)
  79. return status;
  80. status = nc_inq_unlimdim(ncid, &recdimid);
  81. if(status != NC_NOERR)
  82. return status;
  83. if (recdimid == -1) {
  84. *nrecvarsp = 0;
  85. return NC_NOERR;
  86. }
  87. nrecvars = 0;
  88. for (varid = 0; varid < nvars; varid++) {
  89. status = nc_inq_varndims(ncid, varid, &ndims);
  90. if(status != NC_NOERR)
  91. return status;
  92. status = nc_inq_vardimid(ncid, varid, dimids);
  93. if(status != NC_NOERR)
  94. return status;
  95. if (ndims > 0 && dimids[0] == recdimid) {
  96. if (recvarids != NULL)
  97. recvarids[nrecvars] = varid;
  98. nrecvars++;
  99. }
  100. }
  101. *nrecvarsp = nrecvars;
  102. return NC_NOERR;
  103. }
  104. /*
  105. * Computes record size (in bytes) of the record variable with a specified
  106. * variable id. Returns size as 0 if not a record variable.
  107. */
  108. static int
  109. ncrecsize(int ncid, int varid, size_t *recsizep)
  110. {
  111. int status = NC_NOERR;
  112. int recdimid;
  113. nc_type type;
  114. int ndims;
  115. int dimids[MAX_NC_DIMS];
  116. int id;
  117. size_t size;
  118. *recsizep = 0;
  119. status = nc_inq_unlimdim(ncid, &recdimid);
  120. if(status != NC_NOERR)
  121. return status;
  122. status = nc_inq_vartype(ncid, varid, &type);
  123. if(status != NC_NOERR)
  124. return status;
  125. status = nc_inq_varndims(ncid, varid, &ndims);
  126. if(status != NC_NOERR)
  127. return status;
  128. status = nc_inq_vardimid(ncid, varid, dimids);
  129. if(status != NC_NOERR)
  130. return status;
  131. if (ndims == 0 || dimids[0] != recdimid) {
  132. return NC_NOERR;
  133. }
  134. size = nctypelen(type);
  135. for (id = 1; id < ndims; id++) {
  136. size_t len;
  137. status = nc_inq_dimlen(ncid, dimids[id], &len);
  138. if(status != NC_NOERR)
  139. return status;
  140. size *= len;
  141. }
  142. *recsizep = size;
  143. return NC_NOERR;
  144. }
  145. /*
  146. * Retrieves the dimension sizes of a variable with a specified variable id in
  147. * an open netCDF file. Returns -1 on error.
  148. */
  149. static int
  150. dimsizes(int ncid, int varid, size_t *sizes)
  151. {
  152. int status = NC_NOERR;
  153. int ndims;
  154. int id;
  155. int dimids[MAX_NC_DIMS];
  156. status = nc_inq_varndims(ncid, varid, &ndims);
  157. if(status != NC_NOERR)
  158. return status;
  159. status = nc_inq_vardimid(ncid, varid, dimids);
  160. if(status != NC_NOERR)
  161. return status;
  162. if (ndims == 0 || sizes == NULL)
  163. return NC_NOERR;
  164. for (id = 0; id < ndims; id++) {
  165. size_t len;
  166. status = nc_inq_dimlen(ncid, dimids[id], &len);
  167. if(status != NC_NOERR)
  168. return status;
  169. sizes[id] = len;
  170. }
  171. return NC_NOERR;
  172. }
  173. /*
  174. * Retrieves the number of record variables, the record variable ids, and the
  175. * record size of each record variable. If any pointer to info to be returned
  176. * is null, the associated information is not returned. Returns -1 on error.
  177. */
  178. int
  179. nc_inq_rec(
  180. int ncid,
  181. size_t *nrecvarsp,
  182. int *recvarids,
  183. size_t *recsizes)
  184. {
  185. int status = NC_NOERR;
  186. int nvars = 0;
  187. int recdimid;
  188. int varid;
  189. int rvarids[MAX_NC_VARS];
  190. int nrvars = 0;
  191. status = nc_inq_nvars(ncid, &nvars);
  192. if(status != NC_NOERR)
  193. return status;
  194. status = nc_inq_unlimdim(ncid, &recdimid);
  195. if(status != NC_NOERR)
  196. return status;
  197. *nrecvarsp = 0;
  198. if (recdimid == -1)
  199. return NC_NOERR;
  200. status = numrecvars(ncid, &nrvars, rvarids);
  201. if(status != NC_NOERR)
  202. return status;
  203. if (nrecvarsp != NULL)
  204. *nrecvarsp = nrvars;
  205. if (recvarids != NULL)
  206. for (varid = 0; varid < nrvars; varid++)
  207. recvarids[varid] = rvarids[varid];
  208. if (recsizes != NULL)
  209. for (varid = 0; varid < nrvars; varid++) {
  210. size_t rsize;
  211. status = ncrecsize(ncid, rvarids[varid], &rsize);
  212. if (status != NC_NOERR)
  213. return status;
  214. recsizes[varid] = rsize;
  215. }
  216. return NC_NOERR;
  217. }
  218. /*
  219. * Write one record's worth of data, except don't write to variables for which
  220. * the address of the data to be written is NULL. Return -1 on error. This is
  221. * the same as the ncrecput() in the library, except that can handle errors
  222. * better.
  223. */
  224. int
  225. nc_put_rec(
  226. int ncid,
  227. size_t recnum,
  228. void* const* datap)
  229. {
  230. int status = NC_NOERR;
  231. int varid;
  232. int rvarids[MAX_NC_VARS];
  233. int nrvars;
  234. size_t start[MAX_NC_DIMS];
  235. size_t edges[MAX_NC_DIMS];
  236. status = numrecvars(ncid, &nrvars, rvarids);
  237. if(status != NC_NOERR)
  238. return status;
  239. if (nrvars == 0)
  240. return NC_NOERR;
  241. start[0] = recnum;
  242. for (varid = 1; varid < nrvars; varid++)
  243. start[varid] = 0;
  244. for (varid = 0; varid < nrvars; varid++) {
  245. if (datap[varid] != NULL) {
  246. status = dimsizes(ncid, rvarids[varid], edges);
  247. if(status != NC_NOERR)
  248. return status;
  249. edges[0] = 1; /* only 1 record's worth */
  250. status = nc_put_vara(ncid, rvarids[varid], start, edges, datap[varid]);
  251. if(status != NC_NOERR)
  252. return status;
  253. }
  254. }
  255. return 0;
  256. }
  257. /*
  258. * Read one record's worth of data, except don't read from variables for which
  259. * the address of the data to be read is null. Return -1 on error. This is
  260. * the same as the ncrecget() in the library, except that can handle errors
  261. * better.
  262. */
  263. int
  264. nc_get_rec(
  265. int ncid,
  266. size_t recnum,
  267. void **datap)
  268. {
  269. int status = NC_NOERR;
  270. int varid;
  271. int rvarids[MAX_NC_VARS];
  272. int nrvars;
  273. size_t start[MAX_NC_DIMS];
  274. size_t edges[MAX_NC_DIMS];
  275. status = numrecvars(ncid, &nrvars, rvarids);
  276. if(status != NC_NOERR)
  277. return status;
  278. if (nrvars == 0)
  279. return NC_NOERR;
  280. start[0] = recnum;
  281. for (varid = 1; varid < nrvars; varid++)
  282. start[varid] = 0;
  283. for (varid = 0; varid < nrvars; varid++) {
  284. if (datap[varid] != NULL) {
  285. status = dimsizes(ncid, rvarids[varid], edges);
  286. if(status != NC_NOERR)
  287. return status;
  288. edges[0] = 1; /* only 1 record's worth */
  289. status = nc_get_vara(ncid, rvarids[varid], start, edges, datap[varid]);
  290. if(status != NC_NOERR)
  291. return status;
  292. }
  293. }
  294. return 0;
  295. }
  296. /*
  297. */
  298. void
  299. nc_advise(const char *routine_name, int err, const char *fmt,...)
  300. {
  301. va_list args;
  302. if(NC_ISSYSERR(err))
  303. ncerr = NC_SYSERR;
  304. else
  305. ncerr = err;
  306. if( ncopts & NC_VERBOSE )
  307. {
  308. (void) fprintf(stderr,"%s: ", routine_name);
  309. va_start(args ,fmt);
  310. (void) vfprintf(stderr,fmt,args);
  311. va_end(args);
  312. if(err != NC_NOERR)
  313. {
  314. (void) fprintf(stderr,": %s",
  315. nc_strerror(err));
  316. }
  317. (void) fputc('\n',stderr);
  318. (void) fflush(stderr); /* to ensure log files are current */
  319. }
  320. if( (ncopts & NC_FATAL) && err != NC_NOERR )
  321. {
  322. exit(ncopts);
  323. }
  324. }
  325. /* End error handling */
  326. int
  327. nccreate(const char* path, int cmode)
  328. {
  329. int ncid;
  330. const int status = nc_create(path, cmode, &ncid);
  331. if(status != NC_NOERR)
  332. {
  333. nc_advise("nccreate", status, "filename \"%s\"", path);
  334. return -1;
  335. }
  336. return ncid;
  337. }
  338. int
  339. ncopen(const char *path, int mode)
  340. {
  341. int ncid;
  342. const int status = nc_open(path, mode, &ncid);
  343. if(status != NC_NOERR)
  344. {
  345. nc_advise("ncopen", status, "filename \"%s\"", path);
  346. return -1;
  347. }
  348. return ncid;
  349. }
  350. int
  351. ncredef(int ncid)
  352. {
  353. const int status = nc_redef(ncid);
  354. if(status != NC_NOERR)
  355. {
  356. nc_advise("ncredef", status, "ncid %d", ncid);
  357. return -1;
  358. }
  359. return 0;
  360. }
  361. int
  362. ncendef(int ncid)
  363. {
  364. const int status = nc_enddef(ncid);
  365. if(status != NC_NOERR)
  366. {
  367. nc_advise("ncendef", status, "ncid %d", ncid);
  368. return -1;
  369. }
  370. return 0;
  371. }
  372. int
  373. ncclose(int ncid)
  374. {
  375. const int status = nc_close(ncid);
  376. if(status != NC_NOERR)
  377. {
  378. nc_advise("ncclose", status, "ncid %d", ncid);
  379. return -1;
  380. }
  381. return 0;
  382. }
  383. int
  384. ncinquire(
  385. int ncid,
  386. int* ndims,
  387. int* nvars,
  388. int* natts,
  389. int* recdim
  390. )
  391. {
  392. int nd, nv, na;
  393. const int status = nc_inq(ncid, &nd, &nv, &na, recdim);
  394. if(status != NC_NOERR)
  395. {
  396. nc_advise("ncinquire", status, "ncid %d", ncid);
  397. return -1;
  398. }
  399. /* else */
  400. if(ndims != NULL)
  401. *ndims = (int) nd;
  402. if(nvars != NULL)
  403. *nvars = (int) nv;
  404. if(natts != NULL)
  405. *natts = (int) na;
  406. return ncid;
  407. }
  408. int
  409. ncsync(int ncid)
  410. {
  411. const int status = nc_sync(ncid);
  412. if(status != NC_NOERR)
  413. {
  414. nc_advise("ncsync", status, "ncid %d", ncid);
  415. return -1;
  416. }
  417. return 0;
  418. }
  419. int
  420. ncabort(int ncid)
  421. {
  422. const int status = nc_abort(ncid);
  423. if(status != NC_NOERR)
  424. {
  425. nc_advise("ncabort", status, "ncid %d", ncid);
  426. return -1;
  427. }
  428. return 0;
  429. }
  430. int
  431. ncdimdef(
  432. int ncid,
  433. const char* name,
  434. long length
  435. )
  436. {
  437. int dimid;
  438. int status = NC_NOERR;
  439. if(length < 0) {
  440. status = NC_EDIMSIZE;
  441. nc_advise("ncdimdef", status, "ncid %d", ncid);
  442. return -1;
  443. }
  444. status = nc_def_dim(ncid, name, (size_t)length, &dimid);
  445. if(status != NC_NOERR)
  446. {
  447. nc_advise("ncdimdef", status, "ncid %d", ncid);
  448. return -1;
  449. }
  450. return dimid;
  451. }
  452. int
  453. ncdimid(int ncid, const char* name)
  454. {
  455. int dimid;
  456. const int status = nc_inq_dimid(ncid, name, &dimid);
  457. if(status != NC_NOERR)
  458. {
  459. nc_advise("ncdimid", status, "ncid %d", ncid);
  460. return -1;
  461. }
  462. return dimid;
  463. }
  464. int
  465. ncdiminq(
  466. int ncid,
  467. int dimid,
  468. char* name,
  469. long* length
  470. )
  471. {
  472. size_t ll;
  473. const int status = nc_inq_dim(ncid, dimid, name, &ll);
  474. if(status != NC_NOERR)
  475. {
  476. nc_advise("ncdiminq", status, "ncid %d", ncid);
  477. return -1;
  478. }
  479. /* else */
  480. if(length != NULL)
  481. *length = (int) ll;
  482. return dimid;
  483. }
  484. int
  485. ncdimrename(
  486. int ncid,
  487. int dimid,
  488. const char* name
  489. )
  490. {
  491. const int status = nc_rename_dim(ncid, dimid, name);
  492. if(status != NC_NOERR)
  493. {
  494. nc_advise("ncdimrename", status, "ncid %d", ncid);
  495. return -1;
  496. }
  497. return dimid;
  498. }
  499. int
  500. ncvardef(
  501. int ncid,
  502. const char* name,
  503. nc_type datatype,
  504. int ndims,
  505. const int* dim
  506. )
  507. {
  508. int varid = -1;
  509. const int status = nc_def_var(ncid, name, datatype, ndims, dim, &varid);
  510. if(status != NC_NOERR)
  511. {
  512. nc_advise("ncvardef", status, "ncid %d", ncid);
  513. return -1;
  514. }
  515. return varid;
  516. }
  517. int
  518. ncvarid(
  519. int ncid,
  520. const char* name
  521. )
  522. {
  523. int varid = -1;
  524. const int status = nc_inq_varid(ncid, name, &varid);
  525. if(status != NC_NOERR)
  526. {
  527. nc_advise("ncvarid", status, "ncid %d", ncid);
  528. return -1;
  529. }
  530. return varid;
  531. }
  532. int
  533. ncvarinq(
  534. int ncid,
  535. int varid,
  536. char* name,
  537. nc_type* datatype,
  538. int* ndims,
  539. int* dim,
  540. int* natts
  541. )
  542. {
  543. int nd, na;
  544. const int status = nc_inq_var(ncid, varid, name, datatype,
  545. &nd, dim, &na);
  546. if(status != NC_NOERR)
  547. {
  548. nc_advise("ncvarinq", status, "ncid %d", ncid);
  549. return -1;
  550. }
  551. /* else */
  552. if(ndims != NULL)
  553. *ndims = (int) nd;
  554. if(natts != NULL)
  555. *natts = (int) na;
  556. return varid;
  557. }
  558. int
  559. ncvarput1(
  560. int ncid,
  561. int varid,
  562. const long* index,
  563. const void* value
  564. )
  565. {
  566. NDIMS_DECL
  567. A_DECL(coordp, size_t, ndims, index);
  568. A_INIT(coordp, size_t, ndims, index);
  569. {
  570. const int status = nc_put_var1(ncid, varid, coordp, value);
  571. A_FREE(coordp);
  572. if(status != NC_NOERR)
  573. {
  574. nc_advise("ncvarput1", status, "ncid %d", ncid);
  575. return -1;
  576. }
  577. }
  578. return 0;
  579. }
  580. int
  581. ncvarget1(
  582. int ncid,
  583. int varid,
  584. const long* index,
  585. void* value
  586. )
  587. {
  588. NDIMS_DECL
  589. A_DECL(coordp, size_t, ndims, index);
  590. A_INIT(coordp, size_t, ndims, index);
  591. {
  592. const int status = nc_get_var1(ncid, varid, coordp, value);
  593. A_FREE(coordp);
  594. if(status != NC_NOERR)
  595. {
  596. nc_advise("ncdimid", status, "ncid %d", ncid);
  597. return -1;
  598. }
  599. }
  600. return 0;
  601. }
  602. int
  603. ncvarput(
  604. int ncid,
  605. int varid,
  606. const long* start,
  607. const long* count,
  608. const void* value
  609. )
  610. {
  611. NDIMS_DECL
  612. A_DECL(stp, size_t, ndims, start);
  613. A_DECL(cntp, size_t, ndims, count);
  614. A_INIT(stp, size_t, ndims, start);
  615. A_INIT(cntp, size_t, ndims, count);
  616. {
  617. const int status = nc_put_vara(ncid, varid, stp, cntp, value);
  618. A_FREE(cntp);
  619. A_FREE(stp);
  620. if(status != NC_NOERR)
  621. {
  622. nc_advise("ncvarput", status, "ncid %d", ncid);
  623. return -1;
  624. }
  625. }
  626. return 0;
  627. }
  628. int
  629. ncvarget(
  630. int ncid,
  631. int varid,
  632. const long* start,
  633. const long* count,
  634. void* value
  635. )
  636. {
  637. NDIMS_DECL
  638. A_DECL(stp, size_t, ndims, start);
  639. A_DECL(cntp, size_t, ndims, count);
  640. A_INIT(stp, size_t, ndims, start);
  641. A_INIT(cntp, size_t, ndims, count);
  642. {
  643. const int status = nc_get_vara(ncid, varid, stp, cntp, value);
  644. A_FREE(cntp);
  645. A_FREE(stp);
  646. if(status != NC_NOERR)
  647. {
  648. nc_advise("ncvarget", status, "ncid %d; varid %d", ncid, varid);
  649. return -1;
  650. }
  651. }
  652. return 0;
  653. }
  654. int
  655. ncvarputs(
  656. int ncid,
  657. int varid,
  658. const long* start,
  659. const long* count,
  660. const long* stride,
  661. const void* value
  662. )
  663. {
  664. if(stride == NULL)
  665. return ncvarput(ncid, varid, start, count, value);
  666. /* else */
  667. {
  668. NDIMS_DECL
  669. A_DECL(stp, size_t, ndims, start);
  670. A_DECL(cntp, size_t, ndims, count);
  671. A_DECL(strdp, ptrdiff_t, ndims, stride);
  672. A_INIT(stp, size_t, ndims, start);
  673. A_INIT(cntp, size_t, ndims, count);
  674. A_INIT(strdp, ptrdiff_t, ndims, stride);
  675. {
  676. const int status = nc_put_vars(ncid, varid, stp, cntp, strdp, value);
  677. A_FREE(strdp);
  678. A_FREE(cntp);
  679. A_FREE(stp);
  680. if(status != NC_NOERR)
  681. {
  682. nc_advise("ncvarputs", status, "ncid %d", ncid);
  683. return -1;
  684. }
  685. }
  686. return 0;
  687. }
  688. }
  689. int
  690. ncvargets(
  691. int ncid,
  692. int varid,
  693. const long* start,
  694. const long* count,
  695. const long* stride,
  696. void* value
  697. )
  698. {
  699. if(stride == NULL)
  700. return ncvarget(ncid, varid, start, count, value);
  701. /* else */
  702. {
  703. NDIMS_DECL
  704. A_DECL(stp, size_t, ndims, start);
  705. A_DECL(cntp, size_t, ndims, count);
  706. A_DECL(strdp, ptrdiff_t, ndims, stride);
  707. A_INIT(stp, size_t, ndims, start);
  708. A_INIT(cntp, size_t, ndims, count);
  709. A_INIT(strdp, ptrdiff_t, ndims, stride);
  710. {
  711. const int status = nc_get_vars(ncid, varid, stp, cntp, strdp, value);
  712. A_FREE(strdp);
  713. A_FREE(cntp);
  714. A_FREE(stp);
  715. if(status != NC_NOERR)
  716. {
  717. nc_advise("ncvargets", status, "ncid %d", ncid);
  718. return -1;
  719. }
  720. }
  721. return 0;
  722. }
  723. }
  724. int
  725. ncvarputg(
  726. int ncid,
  727. int varid,
  728. const long* start,
  729. const long* count,
  730. const long* stride,
  731. const long* map,
  732. const void* value
  733. )
  734. {
  735. if(map == NULL)
  736. return ncvarputs(ncid, varid, start, count, stride, value);
  737. /* else */
  738. {
  739. NDIMS_DECL
  740. A_DECL(stp, size_t, ndims, start);
  741. A_DECL(cntp, size_t, ndims, count);
  742. A_DECL(strdp, ptrdiff_t, ndims, stride);
  743. A_DECL(imp, ptrdiff_t, ndims, map);
  744. A_INIT(stp, size_t, ndims, start);
  745. A_INIT(cntp, size_t, ndims, count);
  746. A_INIT(strdp, ptrdiff_t, ndims, stride);
  747. A_INIT(imp, ptrdiff_t, ndims, map);
  748. {
  749. const int status = nc_put_varm(ncid, varid,
  750. stp, cntp, strdp, imp, value);
  751. A_FREE(imp);
  752. A_FREE(strdp);
  753. A_FREE(cntp);
  754. A_FREE(stp);
  755. if(status != NC_NOERR)
  756. {
  757. nc_advise("ncvarputg", status, "ncid %d", ncid);
  758. return -1;
  759. }
  760. }
  761. return 0;
  762. }
  763. }
  764. int
  765. ncvargetg(
  766. int ncid,
  767. int varid,
  768. const long* start,
  769. const long* count,
  770. const long* stride,
  771. const long* map,
  772. void* value
  773. )
  774. {
  775. if(map == NULL)
  776. return ncvargets(ncid, varid, start, count, stride, value);
  777. /* else */
  778. {
  779. NDIMS_DECL
  780. A_DECL(stp, size_t, ndims, start);
  781. A_DECL(cntp, size_t, ndims, count);
  782. A_DECL(strdp, ptrdiff_t, ndims, stride);
  783. A_DECL(imp, ptrdiff_t, ndims, map);
  784. A_INIT(stp, size_t, ndims, start);
  785. A_INIT(cntp, size_t, ndims, count);
  786. A_INIT(strdp, ptrdiff_t, ndims, stride);
  787. A_INIT(imp, ptrdiff_t, ndims, map);
  788. {
  789. const int status = nc_get_varm(ncid, varid,
  790. stp, cntp, strdp, imp, value);
  791. A_FREE(imp);
  792. A_FREE(strdp);
  793. A_FREE(cntp);
  794. A_FREE(stp);
  795. if(status != NC_NOERR)
  796. {
  797. nc_advise("ncvargetg", status, "ncid %d", ncid);
  798. return -1;
  799. }
  800. }
  801. return 0;
  802. }
  803. }
  804. int
  805. ncvarrename(
  806. int ncid,
  807. int varid,
  808. const char* name
  809. )
  810. {
  811. const int status = nc_rename_var(ncid, varid, name);
  812. if(status != NC_NOERR)
  813. {
  814. nc_advise("ncvarrename", status, "ncid %d", ncid);
  815. return -1;
  816. }
  817. return varid;
  818. }
  819. int
  820. ncattput(
  821. int ncid,
  822. int varid,
  823. const char* name,
  824. nc_type datatype,
  825. int len,
  826. const void* value
  827. )
  828. {
  829. const int status = nc_put_att(ncid, varid, name, datatype, len, value);
  830. if(status != NC_NOERR)
  831. {
  832. nc_advise("ncattput", status, "ncid %d", ncid);
  833. return -1;
  834. }
  835. return 0;
  836. }
  837. int
  838. ncattinq(
  839. int ncid,
  840. int varid,
  841. const char* name,
  842. nc_type* datatype,
  843. int* len
  844. )
  845. {
  846. size_t ll;
  847. const int status = nc_inq_att(ncid, varid, name, datatype, &ll);
  848. if(status != NC_NOERR)
  849. {
  850. nc_advise("ncattinq", status,
  851. "ncid %d; varid %d; attname \"%s\"",
  852. ncid, varid, name);
  853. return -1;
  854. }
  855. if(len != NULL)
  856. *len = (int) ll;
  857. return 1;
  858. }
  859. int
  860. ncattget(
  861. int ncid,
  862. int varid,
  863. const char* name,
  864. void* value
  865. )
  866. {
  867. const int status = nc_get_att(ncid, varid, name, value);
  868. if(status != NC_NOERR)
  869. {
  870. nc_advise("ncattget", status, "ncid %d", ncid);
  871. return -1;
  872. }
  873. return 1;
  874. }
  875. int
  876. ncattcopy(
  877. int ncid_in,
  878. int varid_in,
  879. const char* name,
  880. int ncid_out,
  881. int varid_out
  882. )
  883. {
  884. const int status = nc_copy_att(ncid_in, varid_in, name, ncid_out, varid_out);
  885. if(status != NC_NOERR)
  886. {
  887. nc_advise("ncattcopy", status, "%s", name);
  888. return -1;
  889. }
  890. return 0;
  891. }
  892. int
  893. ncattname(
  894. int ncid,
  895. int varid,
  896. int attnum,
  897. char* name
  898. )
  899. {
  900. const int status = nc_inq_attname(ncid, varid, attnum, name);
  901. if(status != NC_NOERR)
  902. {
  903. nc_advise("ncattname", status, "ncid %d", ncid);
  904. return -1;
  905. }
  906. return attnum;
  907. }
  908. int
  909. ncattrename(
  910. int ncid,
  911. int varid,
  912. const char* name,
  913. const char* newname
  914. )
  915. {
  916. const int status = nc_rename_att(ncid, varid, name, newname);
  917. if(status != NC_NOERR)
  918. {
  919. nc_advise("ncattrename", status, "ncid %d", ncid);
  920. return -1;
  921. }
  922. return 1;
  923. }
  924. int
  925. ncattdel(
  926. int ncid,
  927. int varid,
  928. const char* name
  929. )
  930. {
  931. const int status = nc_del_att(ncid, varid, name);
  932. if(status != NC_NOERR)
  933. {
  934. nc_advise("ncattdel", status, "ncid %d", ncid);
  935. return -1;
  936. }
  937. return 1;
  938. }
  939. #endif /* NO_NETCDF_2 */
  940. #ifndef NO_NETCDF_2
  941. int
  942. ncsetfill(
  943. int ncid,
  944. int fillmode
  945. )
  946. {
  947. int oldmode = -1;
  948. const int status = nc_set_fill(ncid, fillmode, &oldmode);
  949. if(status != NC_NOERR)
  950. {
  951. nc_advise("ncsetfill", status, "ncid %d", ncid);
  952. return -1;
  953. }
  954. return oldmode;
  955. }
  956. int
  957. ncrecinq(
  958. int ncid,
  959. int* nrecvars,
  960. int* recvarids,
  961. long* recsizes
  962. )
  963. {
  964. size_t nrv = 0;
  965. size_t rs[NC_MAX_VARS]; /* TODO */
  966. const int status = nc_inq_rec(ncid, &nrv, recvarids, rs);
  967. if(status != NC_NOERR)
  968. {
  969. nc_advise("ncrecinq", status, "ncid %d", ncid);
  970. return -1;
  971. }
  972. if(nrecvars != NULL)
  973. *nrecvars = (int) nrv;
  974. if(recsizes != NULL)
  975. {
  976. size_t ii;
  977. for(ii = 0; ii < nrv; ii++)
  978. {
  979. recsizes[ii] = (long) rs[ii];
  980. }
  981. }
  982. return (int) nrv;
  983. }
  984. int
  985. ncrecget(
  986. int ncid,
  987. long recnum,
  988. void** datap
  989. )
  990. {
  991. const int status = nc_get_rec(ncid, (size_t)recnum, datap);
  992. if(status != NC_NOERR)
  993. {
  994. nc_advise("ncrecget", status, "ncid %d", ncid);
  995. return -1;
  996. }
  997. return 0;
  998. }
  999. int
  1000. ncrecput(
  1001. int ncid,
  1002. long recnum,
  1003. void* const* datap
  1004. )
  1005. {
  1006. const int status = nc_put_rec(ncid, (size_t)recnum, datap);
  1007. if(status != NC_NOERR)
  1008. {
  1009. nc_advise("ncrecput", status, "ncid %d", ncid);
  1010. return -1;
  1011. }
  1012. return 0;
  1013. }
  1014. #endif /* NO_NETCDF_2 */