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