1 /*! \file
2 Functions for getting data from variables.
3
4 Copyright 2011 University Corporation for Atmospheric
5 Research/Unidata. See \ref copyright file for more info.
6
7 */
8
9 #include "ncdispatch.h"
10
11 #undef VARS_USES_VARM
12 #ifndef VARS_USES_VARM
13
14 /*!
15 \internal
16
17 */
18 struct GETodometer {
19 int rank;
20 size_t index[NC_MAX_VAR_DIMS];
21 size_t start[NC_MAX_VAR_DIMS];
22 size_t edges[NC_MAX_VAR_DIMS];
23 ptrdiff_t stride[NC_MAX_VAR_DIMS];
24 size_t stop[NC_MAX_VAR_DIMS];
25 };
26
27
28 /** \internal
29
30 */
31 static void
odom_init(struct GETodometer * odom,int rank,const size_t * start,const size_t * edges,const ptrdiff_t * stride)32 odom_init(struct GETodometer* odom,
33 int rank,
34 const size_t* start, const size_t* edges, const ptrdiff_t* stride)
35 {
36 int i;
37 memset(odom,0,sizeof(struct GETodometer));
38 odom->rank = rank;
39 assert(odom->rank <= NC_MAX_VAR_DIMS);
40 for(i=0;i<odom->rank;i++) {
41 odom->start[i] = (start != NULL ? start[i] : 0);
42 odom->edges[i] = (edges != NULL ? edges[i] : 1);
43 odom->stride[i] = (stride != NULL ? stride[i] : 1);
44 odom->stop[i] = odom->start[i] + (odom->edges[i]*((size_t)odom->stride[i]));
45 odom->index[i] = odom->start[i];
46 }
47 }
48
49 /** \internal
50
51 */
52 static int
odom_more(struct GETodometer * odom)53 odom_more(struct GETodometer* odom)
54 {
55 return (odom->index[0] < odom->stop[0]);
56 }
57
58 /** \internal
59
60 */
61 static int
odom_next(struct GETodometer * odom)62 odom_next(struct GETodometer* odom)
63 {
64 int i;
65 if(odom->rank == 0) return 0;
66 for(i=odom->rank-1;i>=0;i--) {
67 odom->index[i] += (size_t)odom->stride[i];
68 if(odom->index[i] < odom->stop[i]) break;
69 if(i == 0) return 0; /* leave the 0th entry if it overflows*/
70 odom->index[i] = odom->start[i]; /* reset this position*/
71 }
72 return 1;
73 }
74 #endif
75
76 /** \internal
77 \ingroup variables
78
79 */
80 int
NC_get_vara(int ncid,int varid,const size_t * start,const size_t * edges,void * value,nc_type memtype)81 NC_get_vara(int ncid, int varid,
82 const size_t *start, const size_t *edges,
83 void *value, nc_type memtype)
84 {
85 NC* ncp;
86 int stat = NC_check_id(ncid, &ncp);
87 if(stat != NC_NOERR) return stat;
88 #ifdef USE_NETCDF4
89 if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT;
90 #endif
91
92 if(edges == NULL) {
93 size_t shape[NC_MAX_VAR_DIMS];
94 int ndims;
95 stat = nc_inq_varndims(ncid, varid, &ndims);
96 if(stat != NC_NOERR) return stat;
97 stat = NC_getshape(ncid,varid,ndims,shape);
98 if(stat != NC_NOERR) return stat;
99 stat = ncp->dispatch->get_vara(ncid,varid,start,shape,value,memtype);
100 } else
101 stat = ncp->dispatch->get_vara(ncid,varid,start,edges,value,memtype);
102 return stat;
103 }
104
105 /** \ingroup variables
106 \internal
107 */
108 static int
NC_get_var(int ncid,int varid,void * value,nc_type memtype)109 NC_get_var(int ncid, int varid, void *value, nc_type memtype)
110 {
111 int ndims;
112 size_t shape[NC_MAX_VAR_DIMS];
113 int stat = nc_inq_varndims(ncid,varid, &ndims);
114 if(stat) return stat;
115 stat = NC_getshape(ncid,varid, ndims, shape);
116 if(stat) return stat;
117 return NC_get_vara(ncid, varid, NC_coord_zero, shape, value, memtype);
118 }
119
120 /** \internal
121 \ingroup variables
122 Most dispatch tables will use the default procedures
123 */
124 int
NCDEFAULT_get_vars(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,void * value0,nc_type memtype)125 NCDEFAULT_get_vars(int ncid, int varid, const size_t * start,
126 const size_t * edges, const ptrdiff_t * stride,
127 void *value0, nc_type memtype)
128 {
129 #ifdef VARS_USES_VARM
130 NC* ncp;
131 int stat = NC_check_id(ncid, &ncp);
132
133 if(stat != NC_NOERR) return stat;
134 return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,NULL,value0,memtype);
135 #else
136 /* Rebuilt get_vars code to simplify and avoid use of get_varm */
137
138 int status = NC_NOERR;
139 int i,simplestride,isrecvar;
140 int rank;
141 struct GETodometer odom;
142 nc_type vartype = NC_NAT;
143 NC* ncp;
144 int memtypelen;
145 size_t vartypelen;
146 size_t nels;
147 char* value = (char*)value0;
148 size_t numrecs;
149 size_t varshape[NC_MAX_VAR_DIMS];
150 size_t mystart[NC_MAX_VAR_DIMS];
151 size_t myedges[NC_MAX_VAR_DIMS];
152 ptrdiff_t mystride[NC_MAX_VAR_DIMS];
153 char *memptr = NULL;
154
155 status = NC_check_id (ncid, &ncp);
156 if(status != NC_NOERR) return status;
157
158 status = nc_inq_vartype(ncid, varid, &vartype);
159 if(status != NC_NOERR) return status;
160
161 if(memtype == NC_NAT) memtype = vartype;
162
163 /* compute the variable type size */
164 status = nc_inq_type(ncid,vartype,NULL,&vartypelen);
165 if(status != NC_NOERR) return status;
166
167 if(memtype > NC_MAX_ATOMIC_TYPE)
168 memtypelen = (int)vartypelen;
169 else
170 memtypelen = nctypelen(memtype);
171
172 /* Check gross internal/external type compatibility */
173 if(vartype != memtype) {
174 /* If !atomic, the two types must be the same */
175 if(vartype > NC_MAX_ATOMIC_TYPE
176 || memtype > NC_MAX_ATOMIC_TYPE)
177 return NC_EBADTYPE;
178 /* ok, the types differ but both are atomic */
179 if(memtype == NC_CHAR || vartype == NC_CHAR)
180 return NC_ECHAR;
181 }
182
183 /* Get the variable rank */
184 status = nc_inq_varndims(ncid, varid, &rank);
185 if(status != NC_NOERR) return status;
186
187 /* Get variable dimension sizes */
188 isrecvar = NC_is_recvar(ncid,varid,&numrecs);
189 NC_getshape(ncid,varid,rank,varshape);
190
191 /* Optimize out using various checks */
192 if (rank == 0) {
193 /*
194 * The variable is a scalar; consequently,
195 * there s only one thing to get and only one place to put it.
196 * (Why was I called?)
197 */
198 size_t edge1[1] = {1};
199 return NC_get_vara(ncid, varid, start, edge1, value, memtype);
200 }
201
202 /* Do various checks and fixups on start/edges/stride */
203 simplestride = 1; /* assume so */
204 nels = 1;
205 for(i=0;i<rank;i++) {
206 size_t dimlen;
207 mystart[i] = (start == NULL ? 0 : start[i]);
208 /* illegal value checks */
209 dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
210 /* mystart is unsigned, never < 0 */
211 #ifdef RELAX_COORD_BOUND
212 if (mystart[i] > dimlen) return NC_EINVALCOORDS;
213 #else
214 if (mystart[i] >= dimlen) return NC_EINVALCOORDS;
215 #endif
216 if(edges == NULL) {
217 if(i == 0 && isrecvar)
218 myedges[i] = numrecs - start[i];
219 else
220 myedges[i] = varshape[i] - mystart[i];
221 } else
222 myedges[i] = edges[i];
223 #ifdef RELAX_COORD_BOUND
224 if (mystart[i] == dimlen && myedges[i] > 0) return NC_EINVALCOORDS;
225 #endif
226 /* myedges is unsigned, never < 0 */
227 if(mystart[i] + myedges[i] > dimlen)
228 return NC_EEDGE;
229 mystride[i] = (stride == NULL ? 1 : stride[i]);
230 if(mystride[i] <= 0
231 /* cast needed for braindead systems with signed size_t */
232 || ((unsigned long) mystride[i] >= X_INT_MAX))
233 return NC_ESTRIDE;
234 if(mystride[i] != 1) simplestride = 0;
235 if(myedges[i] == 0)
236 nels = 0;
237 }
238 if(nels == 0)
239 return NC_NOERR; /* cannot read anything */
240 if(simplestride) {
241 return NC_get_vara(ncid, varid, mystart, myedges, value, memtype);
242 }
243
244 /* memptr indicates where to store the next value */
245 memptr = value;
246
247 odom_init(&odom,rank,mystart,myedges,mystride);
248
249 /* walk the odometer to extract values */
250 while(odom_more(&odom)) {
251 int localstatus = NC_NOERR;
252 /* Read a single value */
253 localstatus = NC_get_vara(ncid,varid,odom.index,nc_sizevector1,memptr,memtype);
254 /* So it turns out that when get_varm is used, all errors are
255 delayed and ERANGE will be overwritten by more serious errors.
256 */
257 if(localstatus != NC_NOERR) {
258 if(status == NC_NOERR || localstatus != NC_ERANGE)
259 status = localstatus;
260 }
261 memptr += memtypelen;
262 odom_next(&odom);
263 }
264 return status;
265 #endif
266 }
267
268 /** \internal
269 \ingroup variables
270 */
271 static int
NC_get_var1(int ncid,int varid,const size_t * coord,void * value,nc_type memtype)272 NC_get_var1(int ncid, int varid, const size_t *coord, void* value,
273 nc_type memtype)
274 {
275 return NC_get_vara(ncid, varid, coord, NC_coord_one, value, memtype);
276 }
277
278 /** \internal
279 \ingroup variables
280 */
281 int
NCDEFAULT_get_varm(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,const ptrdiff_t * imapp,void * value0,nc_type memtype)282 NCDEFAULT_get_varm(int ncid, int varid, const size_t *start,
283 const size_t *edges, const ptrdiff_t *stride,
284 const ptrdiff_t *imapp, void *value0, nc_type memtype)
285 {
286 int status = NC_NOERR;
287 nc_type vartype = NC_NAT;
288 int varndims,maxidim;
289 NC* ncp;
290 int memtypelen;
291 char* value = (char*)value0;
292
293 status = NC_check_id (ncid, &ncp);
294 if(status != NC_NOERR) return status;
295
296 /*
297 if(NC_indef(ncp)) return NC_EINDEFINE;
298 */
299
300 status = nc_inq_vartype(ncid, varid, &vartype);
301 if(status != NC_NOERR) return status;
302 /* Check that this is an atomic type */
303 if(vartype > NC_MAX_ATOMIC_TYPE)
304 return NC_EMAPTYPE;
305
306 status = nc_inq_varndims(ncid, varid, &varndims);
307 if(status != NC_NOERR) return status;
308
309 if(memtype == NC_NAT) {
310 memtype = vartype;
311 }
312
313 if(memtype == NC_CHAR && vartype != NC_CHAR)
314 return NC_ECHAR;
315 else if(memtype != NC_CHAR && vartype == NC_CHAR)
316 return NC_ECHAR;
317
318 memtypelen = nctypelen(memtype);
319
320 maxidim = (int) varndims - 1;
321
322 if (maxidim < 0)
323 {
324 /*
325 * The variable is a scalar; consequently,
326 * there s only one thing to get and only one place to put it.
327 * (Why was I called?)
328 */
329 size_t edge1[1] = {1};
330 return NC_get_vara(ncid, varid, start, edge1, value, memtype);
331 }
332
333 /*
334 * else
335 * The variable is an array.
336 */
337 {
338 int idim;
339 size_t *mystart = NULL;
340 size_t *myedges;
341 size_t *iocount; /* count vector */
342 size_t *stop; /* stop indexes */
343 size_t *length; /* edge lengths in bytes */
344 ptrdiff_t *mystride;
345 ptrdiff_t *mymap;
346 size_t varshape[NC_MAX_VAR_DIMS];
347 int isrecvar;
348 size_t numrecs;
349
350 /* Compute some dimension related values */
351 isrecvar = NC_is_recvar(ncid,varid,&numrecs);
352 NC_getshape(ncid,varid,varndims,varshape);
353
354 /*
355 * Verify stride argument; also see if stride is all ones
356 */
357 if(stride != NULL) {
358 int stride1 = 1;
359 for (idim = 0; idim <= maxidim; ++idim)
360 {
361 if (stride[idim] == 0
362 /* cast needed for braindead systems with signed size_t */
363 || ((unsigned long) stride[idim] >= X_INT_MAX))
364 {
365 return NC_ESTRIDE;
366 }
367 if(stride[idim] != 1) stride1 = 0;
368 }
369 /* If stride1 is true, and there is no imap
370 then call get_vara directly.
371 */
372 if(stride1 && imapp == NULL) {
373 return NC_get_vara(ncid, varid, start, edges, value, memtype);
374 }
375 }
376
377 /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
378 /* Allocate space for mystart,mystride,mymap etc.all at once */
379 mystart = (size_t *)calloc((size_t)(varndims * 7), sizeof(ptrdiff_t));
380 if(mystart == NULL) return NC_ENOMEM;
381 myedges = mystart + varndims;
382 iocount = myedges + varndims;
383 stop = iocount + varndims;
384 length = stop + varndims;
385 mystride = (ptrdiff_t *)(length + varndims);
386 mymap = mystride + varndims;
387
388 /*
389 * Check start, edges
390 */
391 for (idim = maxidim; idim >= 0; --idim)
392 {
393 size_t dimlen =
394 idim == 0 && isrecvar
395 ? numrecs
396 : varshape[idim];
397
398 mystart[idim] = start != NULL
399 ? start[idim]
400 : 0;
401
402 #ifdef RELAX_COORD_BOUND
403 if (mystart[idim] > dimlen)
404 #else
405 if (mystart[idim] >= dimlen)
406 #endif
407 {
408 status = NC_EINVALCOORDS;
409 goto done;
410 }
411
412 #ifdef COMPLEX
413 myedges[idim] = edges != NULL
414 ? edges[idim]
415 : idim == 0 && isrecvar
416 ? numrecs - mystart[idim]
417 : varshape[idim] - mystart[idim];
418 #else
419 if(edges != NULL)
420 myedges[idim] = edges[idim];
421 else if (idim == 0 && isrecvar)
422 myedges[idim] = numrecs - mystart[idim];
423 else
424 myedges[idim] = varshape[idim] - mystart[idim];
425 #endif
426
427 #ifdef RELAX_COORD_BOUND
428 if (mystart[idim] == dimlen && myedges[idim] > 0)
429 {
430 status = NC_EINVALCOORDS;
431 goto done;
432 }
433 #endif
434
435 if (mystart[idim] + myedges[idim] > dimlen)
436 {
437 status = NC_EEDGE;
438 goto done;
439 }
440 }
441
442
443 /*
444 * Initialize I/O parameters.
445 */
446 for (idim = maxidim; idim >= 0; --idim)
447 {
448 if (edges != NULL && edges[idim] == 0)
449 {
450 status = NC_NOERR; /* read/write no data */
451 goto done;
452 }
453
454 mystride[idim] = stride != NULL
455 ? stride[idim]
456 : 1;
457
458 /* Remember: in netCDF-2 imapp is byte oriented, not index oriented
459 * Starting from netCDF-3, imapp is index oriented */
460 #ifdef COMPLEX
461 mymap[idim] = (imapp != NULL
462 ? imapp[idim]
463 : (idim == maxidim ? 1
464 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]));
465 #else
466 if(imapp != NULL)
467 mymap[idim] = imapp[idim];
468 else if (idim == maxidim)
469 mymap[idim] = 1;
470 else
471 mymap[idim] =
472 mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
473 #endif
474 iocount[idim] = 1;
475 length[idim] = ((size_t)mymap[idim]) * myedges[idim];
476 stop[idim] = (mystart[idim] + myedges[idim] * (size_t)mystride[idim]);
477 }
478
479 /* Lower body */
480 /*
481 * As an optimization, adjust I/O parameters when the fastest
482 * dimension has unity stride both externally and internally.
483 * In this case, the user could have called a simpler routine
484 * (i.e. ncvar$1()
485 */
486 if (mystride[maxidim] == 1
487 && mymap[maxidim] == 1)
488 {
489 iocount[maxidim] = myedges[maxidim];
490 mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
491 mymap[maxidim] = (ptrdiff_t) length[maxidim];
492 }
493
494 /*
495 * Perform I/O. Exit when done.
496 */
497 for (;;)
498 {
499 /* TODO: */
500 int lstatus = NC_get_vara(ncid, varid, mystart, iocount,
501 value, memtype);
502 if (lstatus != NC_NOERR) {
503 if(status == NC_NOERR || lstatus != NC_ERANGE)
504 status = lstatus;
505 }
506 /*
507 * The following code permutes through the variable s
508 * external start-index space and it s internal address
509 * space. At the UPC, this algorithm is commonly
510 * called "odometer code".
511 */
512 idim = maxidim;
513 carry:
514 value += (((int)mymap[idim]) * memtypelen);
515 mystart[idim] += (size_t)mystride[idim];
516 if (mystart[idim] == stop[idim])
517 {
518 size_t l = (length[idim] * (size_t)memtypelen);
519 value -= l;
520 mystart[idim] = start[idim];
521 if (--idim < 0)
522 break; /* normal return */
523 goto carry;
524 }
525 } /* I/O loop */
526 done:
527 free(mystart);
528 } /* variable is array */
529 return status;
530 }
531
532 /** \ingroup variables
533 \internal
534 Called by externally visible nc_get_vars_xxx routines */
535 static int
NC_get_vars(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,void * value,nc_type memtype)536 NC_get_vars(int ncid, int varid, const size_t *start,
537 const size_t *edges, const ptrdiff_t *stride, void *value,
538 nc_type memtype)
539 {
540 NC* ncp;
541 int stat = NC_check_id(ncid, &ncp);
542
543 if(stat != NC_NOERR) return stat;
544 #ifdef USE_NETCDF4
545 if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT;
546 #endif
547 return ncp->dispatch->get_vars(ncid,varid,start,edges,stride,value,memtype);
548 }
549
550 /** \ingroup variables
551 \internal
552 Called by externally visible nc_get_varm_xxx routines
553 */
554 static int
NC_get_varm(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,const ptrdiff_t * map,void * value,nc_type memtype)555 NC_get_varm(int ncid, int varid, const size_t *start,
556 const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t* map,
557 void *value, nc_type memtype)
558 {
559 NC* ncp;
560 int stat = NC_check_id(ncid, &ncp);
561
562 if(stat != NC_NOERR) return stat;
563 #ifdef USE_NETCDF4
564 if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT;
565 #endif
566 return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,map,value,memtype);
567 }
568
569 /** \name Reading Data from Variables
570
571 Functions to read data from variables. */
572 /*! \{ */ /* All these functions are part of this named group... */
573
574 /** \ingroup variables
575 Read an array of values from a variable.
576
577 The array to be read is specified by giving a corner and a vector of
578 edge lengths to \ref specify_hyperslab.
579
580 The data values are read into consecutive locations with the last
581 dimension varying fastest. The netCDF dataset must be in data mode
582 (for netCDF-4/HDF5 files, the switch to data mode will happen
583 automatically, unless the classic model is used).
584
585 The nc_get_vara() function will read a variable of any type,
586 including user defined type. For this function, the type of the data
587 in memory must match the type of the variable - no data conversion is
588 done.
589
590 Other nc_get_vara_ functions will convert data to the desired output
591 type as needed.
592
593 \param ncid NetCDF or group ID, from a previous call to nc_open(),
594 nc_create(), nc_def_grp(), or associated inquiry functions such as
595 nc_inq_ncid().
596
597 \param varid Variable ID
598
599 \param startp Start vector with one element for each dimension to \ref
600 specify_hyperslab.
601
602 \param countp Count vector with one element for each dimension to \ref
603 specify_hyperslab.
604
605 \param ip Pointer where the data will be copied. Memory must be
606 allocated by the user before this function is called.
607
608 \returns ::NC_NOERR No error.
609 \returns ::NC_ENOTVAR Variable not found.
610 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
611 \returns ::NC_EEDGE Start+count exceeds dimension bound.
612 \returns ::NC_ERANGE One or more of the values are out of range.
613 \returns ::NC_EINDEFINE Operation not allowed in define mode.
614 \returns ::NC_EBADID Bad ncid.
615
616 \section nc_get_vara_double_example Example
617
618 Here is an example using nc_get_vara_double() to read all the values of
619 the variable named rh from an existing netCDF dataset named
620 foo.nc. For simplicity in this example, we assume that we know that rh
621 is dimensioned with time, lat, and lon, and that there are three time
622 values, five lat values, and ten lon values.
623
624 \code
625 #include <xxxnetcdf.h>
626 ...
627 #define TIMES 3
628 #define LATS 5
629 #define LONS 10
630 int status;
631 int ncid;
632 int rh_id;
633 static size_t start[] = {0, 0, 0};
634 static size_t count[] = {TIMES, LATS, LONS};
635 double rh_vals[TIMES*LATS*LONS];
636 ...
637 status = nc_open("foo.nc", NC_NOWRITE, &ncid);
638 if (status != NC_NOERR) handle_error(status);
639 ...
640 status = nc_inq_varid (ncid, "rh", &rh_id);
641 if (status != NC_NOERR) handle_error(status);
642 ...
643 status = nc_get_vara_double(ncid, rh_id, start, count, rh_vals);
644 if (status != NC_NOERR) handle_error(status);
645 \endcode
646 */
647 /**@{*/
648 int
nc_get_vara(int ncid,int varid,const size_t * startp,const size_t * countp,void * ip)649 nc_get_vara(int ncid, int varid, const size_t *startp,
650 const size_t *countp, void *ip)
651 {
652 NC* ncp = NULL;
653 nc_type xtype = NC_NAT;
654 int stat = NC_check_id(ncid, &ncp);
655 if(stat != NC_NOERR) return stat;
656 stat = nc_inq_vartype(ncid, varid, &xtype);
657 if(stat != NC_NOERR) return stat;
658 return NC_get_vara(ncid, varid, startp, countp, ip, xtype);
659 }
660
661 int
nc_get_vara_text(int ncid,int varid,const size_t * startp,const size_t * countp,char * ip)662 nc_get_vara_text(int ncid, int varid, const size_t *startp,
663 const size_t *countp, char *ip)
664 {
665 NC* ncp;
666 int stat = NC_check_id(ncid, &ncp);
667 if(stat != NC_NOERR) return stat;
668 return NC_get_vara(ncid, varid, startp, countp,
669 (void *)ip, NC_CHAR);
670 }
671
672 int
nc_get_vara_schar(int ncid,int varid,const size_t * startp,const size_t * countp,signed char * ip)673 nc_get_vara_schar(int ncid, int varid, const size_t *startp,
674 const size_t *countp, signed char *ip)
675 {
676 NC* ncp;
677 int stat = NC_check_id(ncid, &ncp);
678 if(stat != NC_NOERR) return stat;
679 return NC_get_vara(ncid, varid, startp, countp,
680 (void *)ip, NC_BYTE);
681 }
682
683 int
nc_get_vara_uchar(int ncid,int varid,const size_t * startp,const size_t * countp,unsigned char * ip)684 nc_get_vara_uchar(int ncid, int varid, const size_t *startp,
685 const size_t *countp, unsigned char *ip)
686 {
687 NC* ncp;
688 int stat = NC_check_id(ncid, &ncp);
689 if(stat != NC_NOERR) return stat;
690 return NC_get_vara(ncid, varid, startp, countp,
691 (void *)ip, T_uchar);
692 }
693
694 int
nc_get_vara_short(int ncid,int varid,const size_t * startp,const size_t * countp,short * ip)695 nc_get_vara_short(int ncid, int varid, const size_t *startp,
696 const size_t *countp, short *ip)
697 {
698 NC* ncp;
699 int stat = NC_check_id(ncid, &ncp);
700 if(stat != NC_NOERR) return stat;
701 return NC_get_vara(ncid, varid, startp, countp,
702 (void *)ip, NC_SHORT);
703 }
704
705 int
nc_get_vara_int(int ncid,int varid,const size_t * startp,const size_t * countp,int * ip)706 nc_get_vara_int(int ncid, int varid,
707 const size_t *startp, const size_t *countp, int *ip)
708 {
709 NC* ncp;
710 int stat = NC_check_id(ncid, &ncp);
711 if(stat != NC_NOERR) return stat;
712 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_INT);
713 }
714
715 int
nc_get_vara_long(int ncid,int varid,const size_t * startp,const size_t * countp,long * ip)716 nc_get_vara_long(int ncid, int varid,
717 const size_t *startp, const size_t *countp, long *ip)
718 {
719 NC* ncp;
720 int stat = NC_check_id(ncid, &ncp);
721 if(stat != NC_NOERR) return stat;
722 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_long);
723 }
724
725 int
nc_get_vara_float(int ncid,int varid,const size_t * startp,const size_t * countp,float * ip)726 nc_get_vara_float(int ncid, int varid,
727 const size_t *startp, const size_t *countp, float *ip)
728 {
729 NC* ncp;
730 int stat = NC_check_id(ncid, &ncp);
731 if(stat != NC_NOERR) return stat;
732 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_float);
733 }
734
735
736 int
nc_get_vara_double(int ncid,int varid,const size_t * startp,const size_t * countp,double * ip)737 nc_get_vara_double(int ncid, int varid, const size_t *startp,
738 const size_t *countp, double *ip)
739 {
740 NC* ncp;
741 int stat = NC_check_id(ncid, &ncp);
742 if(stat != NC_NOERR) return stat;
743 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_double);
744 }
745
746 int
nc_get_vara_ubyte(int ncid,int varid,const size_t * startp,const size_t * countp,unsigned char * ip)747 nc_get_vara_ubyte(int ncid, int varid,
748 const size_t *startp, const size_t *countp, unsigned char *ip)
749 {
750 NC* ncp;
751 int stat = NC_check_id(ncid, &ncp);
752 if(stat != NC_NOERR) return stat;
753 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_ubyte);
754 }
755
756 int
nc_get_vara_ushort(int ncid,int varid,const size_t * startp,const size_t * countp,unsigned short * ip)757 nc_get_vara_ushort(int ncid, int varid,
758 const size_t *startp, const size_t *countp, unsigned short *ip)
759 {
760 NC* ncp;
761 int stat = NC_check_id(ncid, &ncp);
762 if(stat != NC_NOERR) return stat;
763 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_ushort);
764 }
765
766 int
nc_get_vara_uint(int ncid,int varid,const size_t * startp,const size_t * countp,unsigned int * ip)767 nc_get_vara_uint(int ncid, int varid,
768 const size_t *startp, const size_t *countp, unsigned int *ip)
769 {
770 NC* ncp;
771 int stat = NC_check_id(ncid, &ncp);
772 if(stat != NC_NOERR) return stat;
773 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_uint);
774 }
775
776 int
nc_get_vara_longlong(int ncid,int varid,const size_t * startp,const size_t * countp,long long * ip)777 nc_get_vara_longlong(int ncid, int varid,
778 const size_t *startp, const size_t *countp, long long *ip)
779 {
780 NC* ncp;
781 int stat = NC_check_id(ncid, &ncp);
782 if(stat != NC_NOERR) return stat;
783 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_longlong);
784 }
785
786 int
nc_get_vara_ulonglong(int ncid,int varid,const size_t * startp,const size_t * countp,unsigned long long * ip)787 nc_get_vara_ulonglong(int ncid, int varid,
788 const size_t *startp, const size_t *countp, unsigned long long *ip)
789 {
790 NC* ncp;
791 int stat = NC_check_id(ncid, &ncp);
792 if(stat != NC_NOERR) return stat;
793 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_UINT64);
794 }
795
796 #ifdef USE_NETCDF4
797 int
nc_get_vara_string(int ncid,int varid,const size_t * startp,const size_t * countp,char ** ip)798 nc_get_vara_string(int ncid, int varid,
799 const size_t *startp, const size_t *countp, char* *ip)
800 {
801 NC* ncp;
802 int stat = NC_check_id(ncid, &ncp);
803 if(stat != NC_NOERR) return stat;
804 return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_STRING);
805 }
806
807 #endif /*USE_NETCDF4*/
808 /**@}*/
809
810 /** \ingroup variables
811 Read a single datum from a variable.
812
813 Inputs are the netCDF ID, the variable ID, a multidimensional index
814 that specifies which value to get, and the address of a location into
815 which the data value will be read. The value is converted from the
816 external data type of the variable, if necessary.
817
818 The nc_get_var1() function will read a variable of any type, including
819 user defined type. For this function, the type of the data in memory
820 must match the type of the variable - no data conversion is done.
821
822 Other nc_get_var1_ functions will convert data to the desired output
823 type as needed.
824
825 \param ncid NetCDF or group ID, from a previous call to nc_open(),
826 nc_create(), nc_def_grp(), or associated inquiry functions such as
827 nc_inq_ncid().
828
829 \param varid Variable ID
830
831 \param indexp Index vector with one element for each dimension.
832
833 \param ip Pointer where the data will be copied. Memory must be
834 allocated by the user before this function is called.
835
836 \returns ::NC_NOERR No error.
837 \returns ::NC_ENOTVAR Variable not found.
838 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
839 \returns ::NC_ERANGE One or more of the values are out of range.
840 \returns ::NC_EINDEFINE Operation not allowed in define mode.
841 \returns ::NC_EBADID Bad ncid.
842 */
843 /** \{ */
844 int
nc_get_var1(int ncid,int varid,const size_t * indexp,void * ip)845 nc_get_var1(int ncid, int varid, const size_t *indexp, void *ip)
846 {
847 return NC_get_var1(ncid, varid, indexp, ip, NC_NAT);
848 }
849
850 int
nc_get_var1_text(int ncid,int varid,const size_t * indexp,char * ip)851 nc_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip)
852 {
853 NC* ncp;
854 int stat = NC_check_id(ncid, &ncp);
855 if(stat != NC_NOERR) return stat;
856 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_CHAR);
857 }
858
859 int
nc_get_var1_schar(int ncid,int varid,const size_t * indexp,signed char * ip)860 nc_get_var1_schar(int ncid, int varid, const size_t *indexp, signed char *ip)
861 {
862 NC* ncp;
863 int stat = NC_check_id(ncid, &ncp);
864 if(stat != NC_NOERR) return stat;
865 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_BYTE);
866 }
867
868 int
nc_get_var1_uchar(int ncid,int varid,const size_t * indexp,unsigned char * ip)869 nc_get_var1_uchar(int ncid, int varid, const size_t *indexp, unsigned char *ip)
870 {
871 NC* ncp;
872 int stat = NC_check_id(ncid, &ncp);
873 if(stat != NC_NOERR) return stat;
874 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UBYTE);
875 }
876
877 int
nc_get_var1_short(int ncid,int varid,const size_t * indexp,short * ip)878 nc_get_var1_short(int ncid, int varid, const size_t *indexp, short *ip)
879 {
880 NC* ncp;
881 int stat = NC_check_id(ncid, &ncp);
882 if(stat != NC_NOERR) return stat;
883 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_SHORT);
884 }
885
886 int
nc_get_var1_int(int ncid,int varid,const size_t * indexp,int * ip)887 nc_get_var1_int(int ncid, int varid, const size_t *indexp, int *ip)
888 {
889 NC* ncp;
890 int stat = NC_check_id(ncid, &ncp);
891 if(stat != NC_NOERR) return stat;
892 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT);
893 }
894
895 int
nc_get_var1_long(int ncid,int varid,const size_t * indexp,long * ip)896 nc_get_var1_long(int ncid, int varid, const size_t *indexp,
897 long *ip)
898 {
899 NC* ncp;
900 int stat = NC_check_id(ncid, &ncp);
901 if(stat != NC_NOERR) return stat;
902 return NC_get_var1(ncid, varid, indexp, (void *)ip, longtype);
903 }
904
905 int
nc_get_var1_float(int ncid,int varid,const size_t * indexp,float * ip)906 nc_get_var1_float(int ncid, int varid, const size_t *indexp,
907 float *ip)
908 {
909 NC* ncp;
910 int stat = NC_check_id(ncid, &ncp);
911 if(stat != NC_NOERR) return stat;
912 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_FLOAT);
913 }
914
915 int
nc_get_var1_double(int ncid,int varid,const size_t * indexp,double * ip)916 nc_get_var1_double(int ncid, int varid, const size_t *indexp,
917 double *ip)
918 {
919 NC* ncp;
920 int stat = NC_check_id(ncid, &ncp);
921 if(stat != NC_NOERR) return stat;
922 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_DOUBLE);
923 }
924
925 int
nc_get_var1_ubyte(int ncid,int varid,const size_t * indexp,unsigned char * ip)926 nc_get_var1_ubyte(int ncid, int varid, const size_t *indexp,
927 unsigned char *ip)
928 {
929 NC* ncp;
930 int stat = NC_check_id(ncid, &ncp);
931 if(stat != NC_NOERR) return stat;
932 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UBYTE);
933 }
934
935 int
nc_get_var1_ushort(int ncid,int varid,const size_t * indexp,unsigned short * ip)936 nc_get_var1_ushort(int ncid, int varid, const size_t *indexp,
937 unsigned short *ip)
938 {
939 NC* ncp;
940 int stat = NC_check_id(ncid, &ncp);
941 if(stat != NC_NOERR) return stat;
942 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_USHORT);
943 }
944
945 int
nc_get_var1_uint(int ncid,int varid,const size_t * indexp,unsigned int * ip)946 nc_get_var1_uint(int ncid, int varid, const size_t *indexp,
947 unsigned int *ip)
948 {
949 NC* ncp;
950 int stat = NC_check_id(ncid, &ncp);
951 if(stat != NC_NOERR) return stat;
952 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UINT);
953 }
954
955 int
nc_get_var1_longlong(int ncid,int varid,const size_t * indexp,long long * ip)956 nc_get_var1_longlong(int ncid, int varid, const size_t *indexp,
957 long long *ip)
958 {
959 NC* ncp;
960 int stat = NC_check_id(ncid, &ncp);
961 if(stat != NC_NOERR) return stat;
962 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT64);
963 }
964
965 int
nc_get_var1_ulonglong(int ncid,int varid,const size_t * indexp,unsigned long long * ip)966 nc_get_var1_ulonglong(int ncid, int varid, const size_t *indexp,
967 unsigned long long *ip)
968 {
969 NC* ncp;
970 int stat = NC_check_id(ncid, &ncp);
971 if(stat != NC_NOERR) return stat;
972 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UINT64);
973 }
974
975 #ifdef USE_NETCDF4
976 int
nc_get_var1_string(int ncid,int varid,const size_t * indexp,char ** ip)977 nc_get_var1_string(int ncid, int varid, const size_t *indexp, char* *ip)
978 {
979 NC* ncp;
980 int stat = NC_check_id(ncid, &ncp);
981 if(stat != NC_NOERR) return stat;
982 return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_STRING);
983 }
984 #endif /*USE_NETCDF4*/
985 /** \} */
986
987 /** \ingroup variables
988 Read an entire variable in one call.
989
990 This function will read all the values from a netCDF variable of an
991 open netCDF dataset.
992
993 This is the simplest interface to use for reading the value of a
994 scalar variable or when all the values of a multidimensional variable
995 can be read at once. The values are read into consecutive locations
996 with the last dimension varying fastest. The netCDF dataset must be in
997 data mode.
998
999 Take care when using this function with record variables (variables
1000 that use the ::NC_UNLIMITED dimension). If you try to read all the
1001 values of a record variable into an array but there are more records
1002 in the file than you assume, more data will be read than you expect,
1003 which may cause a segmentation violation. To avoid such problems, it
1004 is better to use the nc_get_vara interfaces for variables that use the
1005 ::NC_UNLIMITED dimension.
1006
1007 The functions for types ubyte, ushort, uint, longlong, ulonglong, and
1008 string are only available for netCDF-4/HDF5 files.
1009
1010 The nc_get_var() function will read a variable of any type, including
1011 user defined type. For this function, the type of the data in memory
1012 must match the type of the variable - no data conversion is done.
1013
1014 \param ncid NetCDF or group ID, from a previous call to nc_open(),
1015 nc_create(), nc_def_grp(), or associated inquiry functions such as
1016 nc_inq_ncid().
1017
1018 \param varid Variable ID
1019
1020 \param ip Pointer where the data will be copied. Memory must be
1021 allocated by the user before this function is called.
1022
1023 \returns ::NC_NOERR No error.
1024 \returns ::NC_ENOTVAR Variable not found.
1025 \returns ::NC_ERANGE One or more of the values are out of range.
1026 \returns ::NC_EINDEFINE Operation not allowed in define mode.
1027 \returns ::NC_EBADID Bad ncid.
1028 */
1029 /** \{ */
1030 int
nc_get_var(int ncid,int varid,void * ip)1031 nc_get_var(int ncid, int varid, void *ip)
1032 {
1033 return NC_get_var(ncid, varid, ip, NC_NAT);
1034 }
1035
1036 int
nc_get_var_text(int ncid,int varid,char * ip)1037 nc_get_var_text(int ncid, int varid, char *ip)
1038 {
1039 NC *ncp;
1040 int stat = NC_check_id(ncid, &ncp);
1041 if(stat != NC_NOERR) return stat;
1042 return NC_get_var(ncid, varid, (void *)ip, NC_CHAR);
1043 }
1044
1045 int
nc_get_var_schar(int ncid,int varid,signed char * ip)1046 nc_get_var_schar(int ncid, int varid, signed char *ip)
1047 {
1048 NC *ncp;
1049 int stat = NC_check_id(ncid, &ncp);
1050 if(stat != NC_NOERR) return stat;
1051 return NC_get_var(ncid, varid, (void *)ip, NC_BYTE);
1052 }
1053
1054 int
nc_get_var_uchar(int ncid,int varid,unsigned char * ip)1055 nc_get_var_uchar(int ncid, int varid, unsigned char *ip)
1056 {
1057 NC *ncp;
1058 int stat = NC_check_id(ncid, &ncp);
1059 if(stat != NC_NOERR) return stat;
1060 return NC_get_var(ncid,varid, (void *)ip, NC_UBYTE);
1061 }
1062
1063 int
nc_get_var_short(int ncid,int varid,short * ip)1064 nc_get_var_short(int ncid, int varid, short *ip)
1065 {
1066 NC* ncp;
1067 int stat = NC_check_id(ncid, &ncp);
1068 if(stat != NC_NOERR) return stat;
1069 return NC_get_var(ncid, varid, (void *)ip, NC_SHORT);
1070 }
1071
1072 int
nc_get_var_int(int ncid,int varid,int * ip)1073 nc_get_var_int(int ncid, int varid, int *ip)
1074 {
1075 NC* ncp;
1076 int stat = NC_check_id(ncid, &ncp);
1077 if(stat != NC_NOERR) return stat;
1078 return NC_get_var(ncid,varid, (void *)ip, NC_INT);
1079 }
1080
1081 int
nc_get_var_long(int ncid,int varid,long * ip)1082 nc_get_var_long(int ncid, int varid, long *ip)
1083 {
1084 NC* ncp;
1085 int stat = NC_check_id(ncid, &ncp);
1086 if(stat != NC_NOERR) return stat;
1087 return NC_get_var(ncid,varid, (void *)ip, longtype);
1088 }
1089
1090 int
nc_get_var_float(int ncid,int varid,float * ip)1091 nc_get_var_float(int ncid, int varid, float *ip)
1092 {
1093 NC* ncp;
1094 int stat = NC_check_id(ncid, &ncp);
1095 if(stat != NC_NOERR) return stat;
1096 return NC_get_var(ncid,varid, (void *)ip, NC_FLOAT);
1097 }
1098
1099 int
nc_get_var_double(int ncid,int varid,double * ip)1100 nc_get_var_double(int ncid, int varid, double *ip)
1101 {
1102 NC* ncp;
1103 int stat = NC_check_id(ncid, &ncp);
1104 if(stat != NC_NOERR) return stat;
1105 return NC_get_var(ncid,varid, (void *)ip, NC_DOUBLE);
1106 }
1107
1108 int
nc_get_var_ubyte(int ncid,int varid,unsigned char * ip)1109 nc_get_var_ubyte(int ncid, int varid, unsigned char *ip)
1110 {
1111 NC* ncp;
1112 int stat = NC_check_id(ncid, &ncp);
1113 if(stat != NC_NOERR) return stat;
1114 return NC_get_var(ncid,varid, (void *)ip, NC_UBYTE);
1115 }
1116
1117 int
nc_get_var_ushort(int ncid,int varid,unsigned short * ip)1118 nc_get_var_ushort(int ncid, int varid, unsigned short *ip)
1119 {
1120 NC* ncp;
1121 int stat = NC_check_id(ncid, &ncp);
1122 if(stat != NC_NOERR) return stat;
1123 return NC_get_var(ncid,varid, (void *)ip, NC_USHORT);
1124 }
1125
1126 int
nc_get_var_uint(int ncid,int varid,unsigned int * ip)1127 nc_get_var_uint(int ncid, int varid, unsigned int *ip)
1128 {
1129 NC* ncp;
1130 int stat = NC_check_id(ncid, &ncp);
1131 if(stat != NC_NOERR) return stat;
1132 return NC_get_var(ncid,varid, (void *)ip, NC_UINT);
1133 }
1134
1135 int
nc_get_var_longlong(int ncid,int varid,long long * ip)1136 nc_get_var_longlong(int ncid, int varid, long long *ip)
1137 {
1138 NC* ncp;
1139 int stat = NC_check_id(ncid, &ncp);
1140 if(stat != NC_NOERR) return stat;
1141 return NC_get_var(ncid,varid, (void *)ip, NC_INT64);
1142 }
1143
1144 int
nc_get_var_ulonglong(int ncid,int varid,unsigned long long * ip)1145 nc_get_var_ulonglong(int ncid, int varid, unsigned long long *ip)
1146 {
1147 NC* ncp;
1148 int stat = NC_check_id(ncid, &ncp);
1149 if(stat != NC_NOERR) return stat;
1150 return NC_get_var(ncid,varid, (void *)ip,NC_UINT64);
1151 }
1152
1153 #ifdef USE_NETCDF4
1154 int
nc_get_var_string(int ncid,int varid,char ** ip)1155 nc_get_var_string(int ncid, int varid, char* *ip)
1156 {
1157 NC* ncp;
1158 int stat = NC_check_id(ncid, &ncp);
1159 if(stat != NC_NOERR) return stat;
1160 return NC_get_var(ncid,varid, (void *)ip,NC_STRING);
1161 }
1162 #endif /*USE_NETCDF4*/
1163 /** \} */
1164
1165 /** \ingroup variables
1166 Read a strided array from a variable.
1167
1168 This function reads a subsampled (strided) array section of values
1169 from a netCDF variable of an open netCDF dataset. The subsampled array
1170 section is specified by giving a corner, a vector of edge lengths, and
1171 a stride vector. The values are read with the last dimension of the
1172 netCDF variable varying fastest. The netCDF dataset must be in data
1173 mode.
1174
1175 The nc_get_vars() function will read a variable of any type, including
1176 user defined type. For this function, the type of the data in memory
1177 must match the type of the variable - no data conversion is done.
1178
1179 \param ncid NetCDF or group ID, from a previous call to nc_open(),
1180 nc_create(), nc_def_grp(), or associated inquiry functions such as
1181 nc_inq_ncid().
1182
1183 \param varid Variable ID
1184
1185 \param startp Start vector with one element for each dimension to \ref
1186 specify_hyperslab.
1187
1188 \param countp Count vector with one element for each dimension to \ref
1189 specify_hyperslab.
1190
1191 \param stridep Stride vector with one element for each dimension to
1192 \ref specify_hyperslab.
1193
1194 \param ip Pointer where the data will be copied. Memory must be
1195 allocated by the user before this function is called.
1196
1197 \returns ::NC_NOERR No error.
1198 \returns ::NC_ENOTVAR Variable not found.
1199 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
1200 \returns ::NC_ERANGE One or more of the values are out of range.
1201 \returns ::NC_EINDEFINE Operation not allowed in define mode.
1202 \returns ::NC_EBADID Bad ncid.
1203 */
1204 /** \{ */
1205 int
nc_get_vars(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,void * ip)1206 nc_get_vars (int ncid, int varid, const size_t * startp,
1207 const size_t * countp, const ptrdiff_t * stridep,
1208 void *ip)
1209 {
1210 NC* ncp;
1211 int stat = NC_NOERR;
1212
1213 if ((stat = NC_check_id(ncid, &ncp)))
1214 return stat;
1215 return ncp->dispatch->get_vars(ncid, varid, startp, countp, stridep,
1216 ip, NC_NAT);
1217 }
1218
1219 int
nc_get_vars_text(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,char * ip)1220 nc_get_vars_text(int ncid, int varid, const size_t *startp,
1221 const size_t *countp, const ptrdiff_t * stridep,
1222 char *ip)
1223 {
1224 NC* ncp;
1225 int stat = NC_check_id(ncid, &ncp);
1226 if(stat != NC_NOERR) return stat;
1227 return NC_get_vars(ncid,varid,startp, countp, stridep,
1228 (void *)ip, NC_CHAR);
1229 }
1230
1231 int
nc_get_vars_schar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,signed char * ip)1232 nc_get_vars_schar(int ncid, int varid, const size_t *startp,
1233 const size_t *countp, const ptrdiff_t * stridep,
1234 signed char *ip)
1235 {
1236 NC* ncp;
1237 int stat = NC_check_id(ncid, &ncp);
1238 if(stat != NC_NOERR) return stat;
1239 return NC_get_vars(ncid,varid,startp, countp, stridep,
1240 (void *)ip, NC_BYTE);
1241 }
1242
1243 int
nc_get_vars_uchar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,unsigned char * ip)1244 nc_get_vars_uchar(int ncid, int varid, const size_t *startp,
1245 const size_t *countp, const ptrdiff_t * stridep,
1246 unsigned char *ip)
1247 {
1248 NC* ncp;
1249 int stat = NC_check_id(ncid, &ncp);
1250 if(stat != NC_NOERR) return stat;
1251 return NC_get_vars(ncid,varid,startp, countp, stridep,
1252 (void *)ip, T_uchar);
1253 }
1254
1255 int
nc_get_vars_short(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,short * ip)1256 nc_get_vars_short(int ncid, int varid, const size_t *startp,
1257 const size_t *countp, const ptrdiff_t *stridep,
1258 short *ip)
1259 {
1260 NC* ncp;
1261 int stat = NC_check_id(ncid, &ncp);
1262 if(stat != NC_NOERR) return stat;
1263 return NC_get_vars(ncid,varid,startp, countp, stridep,
1264 (void *)ip, NC_SHORT);
1265 }
1266
1267 int
nc_get_vars_int(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,int * ip)1268 nc_get_vars_int(int ncid, int varid, const size_t *startp,
1269 const size_t *countp, const ptrdiff_t * stridep,
1270 int *ip)
1271 {
1272 NC* ncp;
1273 int stat = NC_check_id(ncid, &ncp);
1274 if(stat != NC_NOERR) return stat;
1275 return NC_get_vars(ncid,varid,startp, countp, stridep,
1276 (void *)ip, NC_INT);
1277 }
1278
1279 int
nc_get_vars_long(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,long * ip)1280 nc_get_vars_long(int ncid, int varid, const size_t *startp,
1281 const size_t *countp, const ptrdiff_t * stridep,
1282 long *ip)
1283 {
1284 NC* ncp;
1285 int stat = NC_check_id(ncid, &ncp);
1286 if(stat != NC_NOERR) return stat;
1287 return NC_get_vars(ncid,varid,startp, countp, stridep,
1288 (void *)ip, T_long);
1289 }
1290
1291 int
nc_get_vars_float(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,float * ip)1292 nc_get_vars_float(int ncid, int varid, const size_t *startp,
1293 const size_t *countp, const ptrdiff_t * stridep,
1294 float *ip)
1295 {
1296 NC* ncp;
1297 int stat = NC_check_id(ncid, &ncp);
1298 if(stat != NC_NOERR) return stat;
1299 return NC_get_vars(ncid,varid,startp, countp, stridep,
1300 (void *)ip, T_float);
1301 }
1302
1303 int
nc_get_vars_double(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,double * ip)1304 nc_get_vars_double(int ncid, int varid, const size_t *startp,
1305 const size_t *countp, const ptrdiff_t * stridep,
1306 double *ip)
1307 {
1308 NC* ncp;
1309 int stat = NC_check_id(ncid, &ncp);
1310 if(stat != NC_NOERR) return stat;
1311 return NC_get_vars(ncid,varid,startp, countp, stridep,
1312 (void *)ip, T_double);
1313 }
1314
1315 int
nc_get_vars_ubyte(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,unsigned char * ip)1316 nc_get_vars_ubyte(int ncid, int varid, const size_t *startp,
1317 const size_t *countp, const ptrdiff_t * stridep,
1318 unsigned char *ip)
1319 {
1320 NC* ncp;
1321 int stat = NC_check_id(ncid, &ncp);
1322 if(stat != NC_NOERR) return stat;
1323 return NC_get_vars(ncid,varid, startp, countp, stridep,
1324 (void *)ip, T_ubyte);
1325 }
1326
1327 int
nc_get_vars_ushort(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,unsigned short * ip)1328 nc_get_vars_ushort(int ncid, int varid, const size_t *startp,
1329 const size_t *countp, const ptrdiff_t * stridep,
1330 unsigned short *ip)
1331 {
1332 NC* ncp;
1333 int stat = NC_check_id(ncid, &ncp);
1334 if(stat != NC_NOERR) return stat;
1335 return NC_get_vars(ncid,varid,startp,countp, stridep,
1336 (void *)ip, T_ushort);
1337 }
1338
1339 int
nc_get_vars_uint(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,unsigned int * ip)1340 nc_get_vars_uint(int ncid, int varid, const size_t *startp,
1341 const size_t *countp, const ptrdiff_t * stridep,
1342 unsigned int *ip)
1343 {
1344 NC* ncp;
1345 int stat = NC_check_id(ncid, &ncp);
1346 if(stat != NC_NOERR) return stat;
1347 return NC_get_vars(ncid,varid,startp, countp, stridep,
1348 (void *)ip, T_uint);
1349 }
1350
1351 int
nc_get_vars_longlong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,long long * ip)1352 nc_get_vars_longlong(int ncid, int varid, const size_t *startp,
1353 const size_t *countp, const ptrdiff_t * stridep,
1354 long long *ip)
1355 {
1356 NC* ncp;
1357 int stat = NC_check_id(ncid, &ncp);
1358 if(stat != NC_NOERR) return stat;
1359 return NC_get_vars(ncid, varid, startp, countp, stridep,
1360 (void *)ip, T_longlong);
1361 }
1362
1363 int
nc_get_vars_ulonglong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,unsigned long long * ip)1364 nc_get_vars_ulonglong(int ncid, int varid, const size_t *startp,
1365 const size_t *countp, const ptrdiff_t * stridep,
1366 unsigned long long *ip)
1367 {
1368 NC* ncp;
1369 int stat = NC_check_id(ncid, &ncp);
1370 if(stat != NC_NOERR) return stat;
1371 return NC_get_vars(ncid, varid, startp, countp, stridep,
1372 (void *)ip, NC_UINT64);
1373 }
1374
1375 #ifdef USE_NETCDF4
1376 int
nc_get_vars_string(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,char ** ip)1377 nc_get_vars_string(int ncid, int varid,
1378 const size_t *startp, const size_t *countp,
1379 const ptrdiff_t * stridep,
1380 char* *ip)
1381 {
1382 NC* ncp;
1383 int stat = NC_check_id(ncid, &ncp);
1384 if(stat != NC_NOERR) return stat;
1385 return NC_get_vars(ncid, varid, startp, countp, stridep,
1386 (void *)ip, NC_STRING);
1387 }
1388 #endif /*USE_NETCDF4*/
1389 /** \} */
1390
1391 /** \ingroup variables
1392 Read a mapped array from a variable.
1393
1394 The nc_get_varm_ type family of functions reads a mapped array section
1395 of values from a netCDF variable of an open netCDF dataset. The mapped
1396 array section is specified by giving a corner, a vector of edge
1397 lengths, a stride vector, and an index mapping vector. The index
1398 mapping vector is a vector of integers that specifies the mapping
1399 between the dimensions of a netCDF variable and the in-memory
1400 structure of the internal data array. No assumptions are made about
1401 the ordering or length of the dimensions of the data array. The netCDF
1402 dataset must be in data mode.
1403
1404 The functions for types ubyte, ushort, uint, longlong, ulonglong, and
1405 string are only available for netCDF-4/HDF5 files.
1406
1407 The nc_get_varm() function will only read a variable of an
1408 atomic type; it will not read user defined types. For this
1409 function, the type of the data in memory must match the type
1410 of the variable - no data conversion is done.
1411
1412 @deprecated Use of this family of functions is discouraged,
1413 although it will continue to be supported.
1414 The reason is the complexity of the
1415 algorithm makes its use difficult for users to properly use.
1416
1417 \param ncid NetCDF or group ID, from a previous call to nc_open(),
1418 nc_create(), nc_def_grp(), or associated inquiry functions such as
1419 nc_inq_ncid().
1420
1421 \param varid Variable ID
1422
1423 \param startp Start vector with one element for each dimension to \ref
1424 specify_hyperslab.
1425
1426 \param countp Count vector with one element for each dimension to \ref
1427 specify_hyperslab.
1428
1429 \param stridep Stride vector with one element for each dimension to
1430 \ref specify_hyperslab.
1431
1432 \param imapp Mapping vector with one element for each dimension to
1433 \ref specify_hyperslab.
1434
1435 \param ip Pointer where the data will be copied. Memory must be
1436 allocated by the user before this function is called.
1437
1438 \returns ::NC_NOERR No error.
1439 \returns ::NC_ENOTVAR Variable not found.
1440 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
1441 \returns ::NC_ERANGE One or more of the values are out of range.
1442 \returns ::NC_EINDEFINE Operation not allowed in define mode.
1443 \returns ::NC_EBADID Bad ncid.
1444 */
1445 /** \{ */
1446 int
nc_get_varm(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,void * ip)1447 nc_get_varm(int ncid, int varid, const size_t * startp,
1448 const size_t * countp, const ptrdiff_t * stridep,
1449 const ptrdiff_t * imapp, void *ip)
1450 {
1451 NC* ncp;
1452 int stat = NC_NOERR;
1453
1454 if ((stat = NC_check_id(ncid, &ncp)))
1455 return stat;
1456 return ncp->dispatch->get_varm(ncid, varid, startp, countp,
1457 stridep, imapp, ip, NC_NAT);
1458 }
1459
1460 int
nc_get_varm_schar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,signed char * ip)1461 nc_get_varm_schar(int ncid, int varid,
1462 const size_t *startp, const size_t *countp,
1463 const ptrdiff_t *stridep,
1464 const ptrdiff_t *imapp, signed char *ip)
1465 {
1466 NC *ncp;
1467 int stat = NC_check_id(ncid, &ncp);
1468 if(stat != NC_NOERR) return stat;
1469 return NC_get_varm(ncid, varid, startp, countp,
1470 stridep, imapp, (void *)ip, NC_BYTE);
1471 }
1472
1473 int
nc_get_varm_uchar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,unsigned char * ip)1474 nc_get_varm_uchar(int ncid, int varid,
1475 const size_t *startp, const size_t *countp,
1476 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1477 unsigned char *ip)
1478 {
1479 NC *ncp;
1480 int stat = NC_check_id(ncid, &ncp);
1481 if(stat != NC_NOERR) return stat;
1482 return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_uchar);
1483 }
1484
1485 int
nc_get_varm_short(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,short * ip)1486 nc_get_varm_short(int ncid, int varid, const size_t *startp,
1487 const size_t *countp, const ptrdiff_t *stridep,
1488 const ptrdiff_t *imapp, short *ip)
1489 {
1490 NC *ncp;
1491 int stat = NC_check_id(ncid, &ncp);
1492 if(stat != NC_NOERR) return stat;
1493 return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,NC_SHORT);
1494 }
1495
1496 int
nc_get_varm_int(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,int * ip)1497 nc_get_varm_int(int ncid, int varid,
1498 const size_t *startp, const size_t *countp,
1499 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1500 int *ip)
1501 {
1502 NC *ncp;
1503 int stat = NC_check_id(ncid, &ncp);
1504 if(stat != NC_NOERR) return stat;
1505 return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,NC_INT);
1506 }
1507
1508 int
nc_get_varm_long(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,long * ip)1509 nc_get_varm_long(int ncid, int varid,
1510 const size_t *startp, const size_t *countp,
1511 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1512 long *ip)
1513 {
1514 NC *ncp;
1515 int stat = NC_check_id(ncid, &ncp);
1516 if(stat != NC_NOERR) return stat;
1517 return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_long);
1518 }
1519
1520 int
nc_get_varm_float(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,float * ip)1521 nc_get_varm_float(int ncid, int varid,
1522 const size_t *startp, const size_t *countp,
1523 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1524 float *ip)
1525 {
1526 NC *ncp;
1527 int stat = NC_check_id(ncid, &ncp);
1528 if(stat != NC_NOERR) return stat;
1529 return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_float);
1530 }
1531
1532 int
nc_get_varm_double(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,double * ip)1533 nc_get_varm_double(int ncid, int varid,
1534 const size_t *startp, const size_t *countp,
1535 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1536 double *ip)
1537 {
1538 NC *ncp;
1539 int stat = NC_check_id(ncid, &ncp);
1540 if(stat != NC_NOERR) return stat;
1541 return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_double);
1542 }
1543
1544 int
nc_get_varm_ubyte(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,unsigned char * ip)1545 nc_get_varm_ubyte(int ncid, int varid,
1546 const size_t *startp, const size_t *countp,
1547 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1548 unsigned char *ip)
1549 {
1550 NC *ncp;
1551 int stat = NC_check_id(ncid, &ncp);
1552 if(stat != NC_NOERR) return stat;
1553 return NC_get_varm(ncid,varid,startp,countp,stridep,
1554 imapp, (void *)ip, T_ubyte);
1555 }
1556
1557 int
nc_get_varm_ushort(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,unsigned short * ip)1558 nc_get_varm_ushort(int ncid, int varid,
1559 const size_t *startp, const size_t *countp,
1560 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1561 unsigned short *ip)
1562 {
1563 NC *ncp;
1564 int stat = NC_check_id(ncid, &ncp);
1565 if(stat != NC_NOERR) return stat;
1566 return NC_get_varm(ncid, varid, startp, countp, stridep,
1567 imapp, (void *)ip, T_ushort);
1568 }
1569
1570 int
nc_get_varm_uint(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,unsigned int * ip)1571 nc_get_varm_uint(int ncid, int varid,
1572 const size_t *startp, const size_t *countp,
1573 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1574 unsigned int *ip)
1575 {
1576 NC *ncp;
1577 int stat = NC_check_id(ncid, &ncp);
1578 if(stat != NC_NOERR) return stat;
1579 return NC_get_varm(ncid, varid, startp, countp,
1580 stridep, imapp, (void *)ip, T_uint);
1581 }
1582
1583 int
nc_get_varm_longlong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,long long * ip)1584 nc_get_varm_longlong(int ncid, int varid, const size_t *startp,
1585 const size_t *countp, const ptrdiff_t *stridep,
1586 const ptrdiff_t *imapp, long long *ip)
1587 {
1588 NC *ncp;
1589 int stat = NC_check_id(ncid, &ncp);
1590 if(stat != NC_NOERR) return stat;
1591 return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
1592 (void *)ip, T_longlong);
1593 }
1594
1595 int
nc_get_varm_ulonglong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,unsigned long long * ip)1596 nc_get_varm_ulonglong(int ncid, int varid,
1597 const size_t *startp, const size_t *countp,
1598 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1599 unsigned long long *ip)
1600 {
1601 NC *ncp;
1602 int stat = NC_check_id(ncid, &ncp);
1603 if(stat != NC_NOERR) return stat;
1604 return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
1605 (void *)ip, NC_UINT64);
1606 }
1607
1608 int
nc_get_varm_text(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,char * ip)1609 nc_get_varm_text(int ncid, int varid, const size_t *startp,
1610 const size_t *countp, const ptrdiff_t *stridep,
1611 const ptrdiff_t *imapp, char *ip)
1612 {
1613 NC *ncp;
1614 int stat = NC_check_id(ncid, &ncp);
1615 if(stat != NC_NOERR) return stat;
1616 return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
1617 (void *)ip, NC_CHAR);
1618 }
1619
1620 #ifdef USE_NETCDF4
1621 int
nc_get_varm_string(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,char ** ip)1622 nc_get_varm_string(int ncid, int varid, const size_t *startp,
1623 const size_t *countp, const ptrdiff_t *stridep,
1624 const ptrdiff_t *imapp, char **ip)
1625 {
1626 NC *ncp;
1627 int stat = NC_check_id(ncid, &ncp);
1628 if(stat != NC_NOERR) return stat;
1629 return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
1630 (void *)ip, NC_STRING);
1631 }
1632 /** \} */
1633 #endif /*USE_NETCDF4*/
1634
1635
1636 /*! \} */ /* End of named group... */
1637